diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/serde | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
173 files changed, 52952 insertions, 0 deletions
diff --git a/third_party/rust/serde/.cargo-checksum.json b/third_party/rust/serde/.cargo-checksum.json new file mode 100644 index 0000000000..ce86133bd3 --- /dev/null +++ b/third_party/rust/serde/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"736542df95689176d660863d0493740313de4a030a09ffa2b5559c80223769ac","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"5cf9d2158d70048a2916360ad59d9079f6233c6f68781a7a792e70f8b772d8ce","build.rs":"d6af5a05be728765c2d98d960406ba648333745ed8644be311d2a1f52d7075f0","crates-io.md":"25ed421fe25d0f6f74c4b78674144bef2843a5f78bf552d0a8ec633be69d282b","src/de/from_primitive.rs":"058fa17313ed3a9c29ec04c6ec67f21a756f6f28cdeb4b0dfcd7012b3e702d0b","src/de/ignored_any.rs":"6a0527edd497a56a103ae65f5e73da675b3f99094d6dcad3c335c8d932daaf40","src/de/impls.rs":"077487d2bacd1fd2093e3ef2fa0d52abe7b9530a84d1ccf9eefb4ad81b6bbad1","src/de/mod.rs":"b59c365b05e4e09a7467c958f85b2c64435514c59c17275be019397ad7ccb00e","src/de/utf8.rs":"f17524ee0af98ec3abcfd7d0b812fbd1033263bd8e2ce2f57c1e1999ce153558","src/de/value.rs":"a878f6bdd57d25b0b93bfc6288ed1e46c50870dc8703748b6fbb8c0965a6b586","src/export.rs":"2ebdf0eccaa64c5e98c6dfd13b4980474f627fc3fae90cfc2c741acf860afd5d","src/integer128.rs":"b213ec6c1ecf8c8228d9591e0b2c31b78d972cd4c6a0b231468090f15784f6f6","src/lib.rs":"c8b0d22a63c9250342fbd3a3b263435e7bca98d9091a3bad5db026eac4877ef9","src/macros.rs":"f18fc25c5fb857238bf119cdee5c7987a8584dea69c51f27ca718b7dfd871d0f","src/private/de.rs":"bce814fa2f2fd689c6d4a354839f38d7ea260509339181ce83d9b0fdbe0e1b3b","src/private/macros.rs":"ebb6affd4c89e3b5f9a42e03f8b7d966bc588875e9b44e962d0b7aba7f80a10f","src/private/mod.rs":"f8f2cd5edbfc26c268b34cdb89db1b34e6348f81384f03d18532e7568575006d","src/private/ser.rs":"96a1e23ad7f3c8ee51a02d799d92780e19dd3c18fa0f1ad791abef7cb346e224","src/ser/fmt.rs":"7827ed07fd8897e6324f75625ba0c926a4c4e7ec2914cd067391ce54d942ac7b","src/ser/impls.rs":"ce9996998c6485c88bbc77516611e9f5a9a92cbb12d34bb4f8ae022530be85e0","src/ser/impossible.rs":"3dd0e165b88fc67e698e675f16569b91fab9e054caa4c3e1997f929ba364fe90","src/ser/mod.rs":"9c26100d8058a5c39aea72512fb78de959e4ed9199481eef47996f0864df0f2c","src/std_error.rs":"3aac687856c035517fae44ed2906dd4a1e3184bae4bf613adcdeb73f74126c57"},"package":"96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"}
\ No newline at end of file diff --git a/third_party/rust/serde/Cargo.toml b/third_party/rust/serde/Cargo.toml new file mode 100644 index 0000000000..4e6fa348f2 --- /dev/null +++ b/third_party/rust/serde/Cargo.toml @@ -0,0 +1,44 @@ +# 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" +version = "1.0.116" +authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] +build = "build.rs" +include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +description = "A generic serialization/deserialization framework" +homepage = "https://serde.rs" +documentation = "https://docs.serde.rs/serde/" +readme = "crates-io.md" +keywords = ["serde", "serialization", "no_std"] +categories = ["encoding"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/serde-rs/serde" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = ["derive", "rc"] +[dependencies.serde_derive] +version = "=1.0.116" +optional = true +[dev-dependencies.serde_derive] +version = "1.0" + +[features] +alloc = [] +default = ["std"] +derive = ["serde_derive"] +rc = [] +std = [] +unstable = [] diff --git a/third_party/rust/serde/LICENSE-APACHE b/third_party/rust/serde/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde/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/serde/LICENSE-MIT b/third_party/rust/serde/LICENSE-MIT new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/third_party/rust/serde/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde/README.md b/third_party/rust/serde/README.md new file mode 100644 index 0000000000..14b00982e0 --- /dev/null +++ b/third_party/rust/serde/README.md @@ -0,0 +1,111 @@ +# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31] + +[Build Status]: https://img.shields.io/github/workflow/status/serde-rs/serde/CI/master +[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster +[Latest Version]: https://img.shields.io/crates/v/serde.svg +[crates.io]: https://crates.io/crates/serde +[serde: rustc 1.13+]: https://img.shields.io/badge/serde-rustc_1.13+-lightgray.svg +[serde_derive: rustc 1.31+]: https://img.shields.io/badge/serde_derive-rustc_1.31+-lightgray.svg +[Rust 1.13]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html +[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.serde.rs/serde/) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +<details> +<summary> +Click to show Cargo.toml. +<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a> +</summary> + +```toml +[dependencies] + +# The core APIs, including the Serialize and Deserialize traits. Always +# required when using Serde. The "derive" feature is only required when +# using #[derive(Serialize, Deserialize)] to make Serde work with structs +# and enums defined in your crate. +serde = { version = "1.0", features = ["derive"] } + +# Each data format lives in its own crate; the sample code below uses JSON +# but you may be using a different one. +serde_json = "1.0" +``` + +</details> +<p></p> + +```rust +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#general] or [#beginners] channels of the unofficial community Discord, the +[#rust-usage] channel of the official Rust Project Discord, or the +[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag +on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned +weekly easy questions post, or the Rust [Discourse forum][discourse]. It's +acceptable to file a support issue in this repo but they tend not to get as many +eyes as any of the above and may get closed without a response after some time. + +[#general]: https://discord.com/channels/273534239310479360/274215136414400513 +[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org + +<br> + +#### License + +<sup> +Licensed under either of <a href="LICENSE-APACHE">Apache License, Version +2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. +</sup> + +<br> + +<sub> +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. +</sub> diff --git a/third_party/rust/serde/build.rs b/third_party/rust/serde/build.rs new file mode 100644 index 0000000000..613760811c --- /dev/null +++ b/third_party/rust/serde/build.rs @@ -0,0 +1,127 @@ +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, + }; + + let target = env::var("TARGET").unwrap(); + let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; + + // std::collections::Bound was stabilized in Rust 1.17 + // but it was moved to core::ops later in Rust 1.26: + // https://doc.rust-lang.org/core/ops/enum.Bound.html + if minor >= 26 { + println!("cargo:rustc-cfg=ops_bound"); + } else if minor >= 17 && cfg!(feature = "std") { + println!("cargo:rustc-cfg=collections_bound"); + } + + // core::cmp::Reverse stabilized in Rust 1.19: + // https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html + if minor >= 19 { + println!("cargo:rustc-cfg=core_reverse"); + } + + // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20: + // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str + // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path + if minor >= 20 { + println!("cargo:rustc-cfg=de_boxed_c_str"); + println!("cargo:rustc-cfg=de_boxed_path"); + } + + // From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21: + // https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>> + // https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>> + if minor >= 21 { + println!("cargo:rustc-cfg=de_rc_dst"); + } + + // Duration available in core since Rust 1.25: + // https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations + if minor >= 25 { + println!("cargo:rustc-cfg=core_duration"); + } + + // 128-bit integers stabilized in Rust 1.26: + // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html + // + // Disabled on Emscripten targets as Emscripten doesn't + // currently support integers larger than 64 bits. + if minor >= 26 && !emscripten { + println!("cargo:rustc-cfg=integer128"); + } + + // Inclusive ranges methods stabilized in Rust 1.27: + // https://github.com/rust-lang/rust/pull/50758 + if minor >= 27 { + println!("cargo:rustc-cfg=range_inclusive"); + } + + // Non-zero integers stabilized in Rust 1.28: + // https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations + if minor >= 28 { + println!("cargo:rustc-cfg=num_nonzero"); + } + + // TryFrom, Atomic types, and non-zero signed integers stabilized in Rust 1.34: + // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto + // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations + if minor >= 34 { + println!("cargo:rustc-cfg=core_try_from"); + println!("cargo:rustc-cfg=num_nonzero_signed"); + + // Whitelist of archs that support std::sync::atomic module. Ideally we + // would use #[cfg(target_has_atomic = "...")] but it is not stable yet. + // Instead this is based on rustc's src/librustc_target/spec/*.rs. + let has_atomic64 = target.starts_with("x86_64") + || target.starts_with("i686") + || target.starts_with("aarch64") + || target.starts_with("powerpc64") + || target.starts_with("sparc64") + || target.starts_with("mips64el"); + let has_atomic32 = has_atomic64 || emscripten; + if has_atomic64 { + println!("cargo:rustc-cfg=std_atomic64"); + } + if has_atomic32 { + println!("cargo:rustc-cfg=std_atomic"); + } + } +} + +fn rustc_minor_version() -> Option<u32> { + 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/serde/crates-io.md b/third_party/rust/serde/crates-io.md new file mode 100644 index 0000000000..07757614a7 --- /dev/null +++ b/third_party/rust/serde/crates-io.md @@ -0,0 +1,62 @@ +<!-- Serde readme rendered on crates.io --> + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.serde.rs/serde/) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +```rust +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#general] or [#beginners] channels of the unofficial community Discord, the +[#rust-usage] channel of the official Rust Project Discord, or the +[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag +on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned +weekly easy questions post, or the Rust [Discourse forum][discourse]. It's +acceptable to file a support issue in this repo but they tend not to get as many +eyes as any of the above and may get closed without a response after some time. + +[#general]: https://discord.com/channels/273534239310479360/274215136414400513 +[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org diff --git a/third_party/rust/serde/src/de/from_primitive.rs b/third_party/rust/serde/src/de/from_primitive.rs new file mode 100644 index 0000000000..544f3f1b81 --- /dev/null +++ b/third_party/rust/serde/src/de/from_primitive.rs @@ -0,0 +1,260 @@ +use lib::*; + +macro_rules! int_to_int { + ($dst:ident, $n:ident) => { + if $dst::min_value() as i64 <= $n as i64 && $n as i64 <= $dst::max_value() as i64 { + Some($n as $dst) + } else { + None + } + }; +} + +macro_rules! int_to_uint { + ($dst:ident, $n:ident) => { + if 0 <= $n && $n as u64 <= $dst::max_value() as u64 { + Some($n as $dst) + } else { + None + } + }; +} + +macro_rules! uint_to { + ($dst:ident, $n:ident) => { + if $n as u64 <= $dst::max_value() as u64 { + Some($n as $dst) + } else { + None + } + }; +} + +pub trait FromPrimitive: Sized { + fn from_i8(n: i8) -> Option<Self>; + fn from_i16(n: i16) -> Option<Self>; + fn from_i32(n: i32) -> Option<Self>; + fn from_i64(n: i64) -> Option<Self>; + fn from_u8(n: u8) -> Option<Self>; + fn from_u16(n: u16) -> Option<Self>; + fn from_u32(n: u32) -> Option<Self>; + fn from_u64(n: u64) -> Option<Self>; +} + +macro_rules! impl_from_primitive_for_int { + ($t:ident) => { + impl FromPrimitive for $t { + #[inline] + fn from_i8(n: i8) -> Option<Self> { + int_to_int!($t, n) + } + #[inline] + fn from_i16(n: i16) -> Option<Self> { + int_to_int!($t, n) + } + #[inline] + fn from_i32(n: i32) -> Option<Self> { + int_to_int!($t, n) + } + #[inline] + fn from_i64(n: i64) -> Option<Self> { + int_to_int!($t, n) + } + #[inline] + fn from_u8(n: u8) -> Option<Self> { + uint_to!($t, n) + } + #[inline] + fn from_u16(n: u16) -> Option<Self> { + uint_to!($t, n) + } + #[inline] + fn from_u32(n: u32) -> Option<Self> { + uint_to!($t, n) + } + #[inline] + fn from_u64(n: u64) -> Option<Self> { + uint_to!($t, n) + } + } + }; +} + +macro_rules! impl_from_primitive_for_uint { + ($t:ident) => { + impl FromPrimitive for $t { + #[inline] + fn from_i8(n: i8) -> Option<Self> { + int_to_uint!($t, n) + } + #[inline] + fn from_i16(n: i16) -> Option<Self> { + int_to_uint!($t, n) + } + #[inline] + fn from_i32(n: i32) -> Option<Self> { + int_to_uint!($t, n) + } + #[inline] + fn from_i64(n: i64) -> Option<Self> { + int_to_uint!($t, n) + } + #[inline] + fn from_u8(n: u8) -> Option<Self> { + uint_to!($t, n) + } + #[inline] + fn from_u16(n: u16) -> Option<Self> { + uint_to!($t, n) + } + #[inline] + fn from_u32(n: u32) -> Option<Self> { + uint_to!($t, n) + } + #[inline] + fn from_u64(n: u64) -> Option<Self> { + uint_to!($t, n) + } + } + }; +} + +macro_rules! impl_from_primitive_for_float { + ($t:ident) => { + impl FromPrimitive for $t { + #[inline] + fn from_i8(n: i8) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_i16(n: i16) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_i32(n: i32) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_i64(n: i64) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_u8(n: u8) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_u16(n: u16) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_u32(n: u32) -> Option<Self> { + Some(n as Self) + } + #[inline] + fn from_u64(n: u64) -> Option<Self> { + Some(n as Self) + } + } + }; +} + +impl_from_primitive_for_int!(isize); +impl_from_primitive_for_int!(i8); +impl_from_primitive_for_int!(i16); +impl_from_primitive_for_int!(i32); +impl_from_primitive_for_int!(i64); +impl_from_primitive_for_uint!(usize); +impl_from_primitive_for_uint!(u8); +impl_from_primitive_for_uint!(u16); +impl_from_primitive_for_uint!(u32); +impl_from_primitive_for_uint!(u64); +impl_from_primitive_for_float!(f32); +impl_from_primitive_for_float!(f64); + +serde_if_integer128! { + impl FromPrimitive for i128 { + #[inline] + fn from_i8(n: i8) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_i16(n: i16) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_i32(n: i32) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_i64(n: i64) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_u8(n: u8) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_u16(n: u16) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_u32(n: u32) -> Option<Self> { + Some(n as i128) + } + #[inline] + fn from_u64(n: u64) -> Option<Self> { + Some(n as i128) + } + } + + impl FromPrimitive for u128 { + #[inline] + fn from_i8(n: i8) -> Option<Self> { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_i16(n: i16) -> Option<Self> { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_i32(n: i32) -> Option<Self> { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_i64(n: i64) -> Option<Self> { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_u8(n: u8) -> Option<Self> { + Some(n as u128) + } + #[inline] + fn from_u16(n: u16) -> Option<Self> { + Some(n as u128) + } + #[inline] + fn from_u32(n: u32) -> Option<Self> { + Some(n as u128) + } + #[inline] + fn from_u64(n: u64) -> Option<Self> { + Some(n as u128) + } + } +} diff --git a/third_party/rust/serde/src/de/ignored_any.rs b/third_party/rust/serde/src/de/ignored_any.rs new file mode 100644 index 0000000000..68a644e0d1 --- /dev/null +++ b/third_party/rust/serde/src/de/ignored_any.rs @@ -0,0 +1,227 @@ +use lib::*; + +use de::{ + Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor, +}; + +/// An efficient way of discarding data from a deserializer. +/// +/// Think of this like `serde_json::Value` in that it can be deserialized from +/// any type, except that it does not store any information about the data that +/// gets deserialized. +/// +/// ```edition2018 +/// use std::fmt; +/// use std::marker::PhantomData; +/// +/// use serde::de::{ +/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor, +/// }; +/// +/// /// A seed that can be used to deserialize only the `n`th element of a sequence +/// /// while efficiently discarding elements of any type before or after index `n`. +/// /// +/// /// For example to deserialize only the element at index 3: +/// /// +/// /// ``` +/// /// NthElement::new(3).deserialize(deserializer) +/// /// ``` +/// pub struct NthElement<T> { +/// n: usize, +/// marker: PhantomData<T>, +/// } +/// +/// impl<T> NthElement<T> { +/// pub fn new(n: usize) -> Self { +/// NthElement { +/// n: n, +/// marker: PhantomData, +/// } +/// } +/// } +/// +/// impl<'de, T> Visitor<'de> for NthElement<T> +/// where +/// T: Deserialize<'de>, +/// { +/// type Value = T; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!( +/// formatter, +/// "a sequence in which we care about element {}", +/// self.n +/// ) +/// } +/// +/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> +/// where +/// A: SeqAccess<'de>, +/// { +/// // Skip over the first `n` elements. +/// for i in 0..self.n { +/// // It is an error if the sequence ends before we get to element `n`. +/// if seq.next_element::<IgnoredAny>()?.is_none() { +/// return Err(de::Error::invalid_length(i, &self)); +/// } +/// } +/// +/// // Deserialize the one we care about. +/// let nth = match seq.next_element()? { +/// Some(nth) => nth, +/// None => { +/// return Err(de::Error::invalid_length(self.n, &self)); +/// } +/// }; +/// +/// // Skip over any remaining elements in the sequence after `n`. +/// while let Some(IgnoredAny) = seq.next_element()? { +/// // ignore +/// } +/// +/// Ok(nth) +/// } +/// } +/// +/// impl<'de, T> DeserializeSeed<'de> for NthElement<T> +/// where +/// T: Deserialize<'de>, +/// { +/// type Value = T; +/// +/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> +/// where +/// D: Deserializer<'de>, +/// { +/// deserializer.deserialize_seq(self) +/// } +/// } +/// +/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> +/// # where +/// # D: Deserializer<'de>, +/// # { +/// // Deserialize only the sequence element at index 3 from this deserializer. +/// // The element at index 3 is required to be a string. Elements before and +/// // after index 3 are allowed to be of any type. +/// let s: String = NthElement::new(3).deserialize(deserializer)?; +/// # Ok(()) +/// # } +/// ``` +#[derive(Copy, Clone, Debug, Default)] +pub struct IgnoredAny; + +impl<'de> Visitor<'de> for IgnoredAny { + type Value = IgnoredAny; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("anything at all") + } + + #[inline] + fn visit_bool<E>(self, x: bool) -> Result<Self::Value, E> { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_i64<E>(self, x: i64) -> Result<Self::Value, E> { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_u64<E>(self, x: u64) -> Result<Self::Value, E> { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + let _ = s; + Ok(IgnoredAny) + } + + #[inline] + fn visit_none<E>(self) -> Result<Self::Value, E> { + Ok(IgnoredAny) + } + + #[inline] + fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + IgnoredAny::deserialize(deserializer) + } + + #[inline] + fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + IgnoredAny::deserialize(deserializer) + } + + #[inline] + fn visit_unit<E>(self) -> Result<Self::Value, E> { + Ok(IgnoredAny) + } + + #[inline] + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + while let Some(IgnoredAny) = try!(seq.next_element()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + while let Some((IgnoredAny, IgnoredAny)) = try!(map.next_entry()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + let _ = bytes; + Ok(IgnoredAny) + } + + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + data.variant::<IgnoredAny>()?.1.newtype_variant() + } +} + +impl<'de> Deserialize<'de> for IgnoredAny { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<IgnoredAny, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_ignored_any(IgnoredAny) + } +} diff --git a/third_party/rust/serde/src/de/impls.rs b/third_party/rust/serde/src/de/impls.rs new file mode 100644 index 0000000000..ae4f9dc806 --- /dev/null +++ b/third_party/rust/serde/src/de/impls.rs @@ -0,0 +1,2612 @@ +use lib::*; + +use de::{ + Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor, +}; + +#[cfg(any(core_duration, feature = "std", feature = "alloc"))] +use de::MapAccess; + +use de::from_primitive::FromPrimitive; +use private::de::InPlaceSeed; + +#[cfg(any(feature = "std", feature = "alloc"))] +use private::de::size_hint; + +//////////////////////////////////////////////////////////////////////////////// + +struct UnitVisitor; + +impl<'de> Visitor<'de> for UnitVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("unit") + } + + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(()) + } +} + +impl<'de> Deserialize<'de> for () { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_unit(UnitVisitor) + } +} + +#[cfg(feature = "unstable")] +impl<'de> Deserialize<'de> for ! { + fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Err(Error::custom("cannot deserialize `!`")) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct BoolVisitor; + +impl<'de> Visitor<'de> for BoolVisitor { + type Value = bool; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a boolean") + } + + fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) + } +} + +impl<'de> Deserialize<'de> for bool { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_bool(BoolVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! visit_integer_method { + ($src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => { + #[inline] + fn $method<E>(self, v: $src_ty) -> Result<Self::Value, E> + where + E: Error, + { + match FromPrimitive::$from_method(v) { + Some(v) => Ok(v), + None => Err(Error::invalid_value( + Unexpected::$group(v as $group_ty), + &self, + )), + } + } + }; +} + +macro_rules! visit_float_method { + ($src_ty:ident, $method:ident) => { + #[inline] + fn $method<E>(self, v: $src_ty) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v as Self::Value) + } + }; +} + +macro_rules! impl_deserialize_num { + ($ty:ident, $method:ident, $($visit:ident),*) => { + impl<'de> Deserialize<'de> for $ty { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct PrimitiveVisitor; + + impl<'de> Visitor<'de> for PrimitiveVisitor { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(stringify!($ty)) + } + + $( + impl_deserialize_num!($visit $ty); + )* + } + + deserializer.$method(PrimitiveVisitor) + } + } + }; + + (integer $ty:ident) => { + visit_integer_method!(i8, visit_i8, from_i8, Signed, i64); + visit_integer_method!(i16, visit_i16, from_i16, Signed, i64); + visit_integer_method!(i32, visit_i32, from_i32, Signed, i64); + visit_integer_method!(i64, visit_i64, from_i64, Signed, i64); + + visit_integer_method!(u8, visit_u8, from_u8, Unsigned, u64); + visit_integer_method!(u16, visit_u16, from_u16, Unsigned, u64); + visit_integer_method!(u32, visit_u32, from_u32, Unsigned, u64); + visit_integer_method!(u64, visit_u64, from_u64, Unsigned, u64); + }; + + (float $ty:ident) => { + visit_float_method!(f32, visit_f32); + visit_float_method!(f64, visit_f64); + }; +} + +impl_deserialize_num!(i8, deserialize_i8, integer); +impl_deserialize_num!(i16, deserialize_i16, integer); +impl_deserialize_num!(i32, deserialize_i32, integer); +impl_deserialize_num!(i64, deserialize_i64, integer); +impl_deserialize_num!(isize, deserialize_i64, integer); + +impl_deserialize_num!(u8, deserialize_u8, integer); +impl_deserialize_num!(u16, deserialize_u16, integer); +impl_deserialize_num!(u32, deserialize_u32, integer); +impl_deserialize_num!(u64, deserialize_u64, integer); +impl_deserialize_num!(usize, deserialize_u64, integer); + +impl_deserialize_num!(f32, deserialize_f32, integer, float); +impl_deserialize_num!(f64, deserialize_f64, integer, float); + +serde_if_integer128! { + impl<'de> Deserialize<'de> for i128 { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct PrimitiveVisitor; + + impl<'de> Visitor<'de> for PrimitiveVisitor { + type Value = i128; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("i128") + } + + impl_deserialize_num!(integer i128); + + #[inline] + fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) + } + + #[inline] + fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> + where + E: Error, + { + if v <= i128::max_value() as u128 { + Ok(v as i128) + } else { + Err(Error::invalid_value(Unexpected::Other("u128"), &self)) + } + } + } + + deserializer.deserialize_i128(PrimitiveVisitor) + } + } + + impl<'de> Deserialize<'de> for u128 { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct PrimitiveVisitor; + + impl<'de> Visitor<'de> for PrimitiveVisitor { + type Value = u128; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("u128") + } + + impl_deserialize_num!(integer u128); + + #[inline] + fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E> + where + E: Error, + { + if v >= 0 { + Ok(v as u128) + } else { + Err(Error::invalid_value(Unexpected::Other("i128"), &self)) + } + } + + #[inline] + fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) + } + } + + deserializer.deserialize_u128(PrimitiveVisitor) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct CharVisitor; + +impl<'de> Visitor<'de> for CharVisitor { + type Value = char; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a character") + } + + #[inline] + fn visit_char<E>(self, v: char) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) + } + + #[inline] + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + let mut iter = v.chars(); + match (iter.next(), iter.next()) { + (Some(c), None) => Ok(c), + _ => Err(Error::invalid_value(Unexpected::Str(v), &self)), + } + } +} + +impl<'de> Deserialize<'de> for char { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_char(CharVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +struct StringVisitor; +#[cfg(any(feature = "std", feature = "alloc"))] +struct StringInPlaceVisitor<'a>(&'a mut String); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Visitor<'de> for StringVisitor { + type Value = String; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v.to_owned()) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => Ok(s.to_owned()), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + match String::from_utf8(v) { + Ok(s) => Ok(s), + Err(e) => Err(Error::invalid_value( + Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + self.0.clear(); + self.0.push_str(v); + Ok(()) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + *self.0 = v; + Ok(()) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => { + self.0.clear(); + self.0.push_str(s); + Ok(()) + } + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + match String::from_utf8(v) { + Ok(s) => { + *self.0 = s; + Ok(()) + } + Err(e) => Err(Error::invalid_value( + Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for String { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(StringVisitor) + } + + fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(StringInPlaceVisitor(place)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct StrVisitor; + +impl<'a> Visitor<'a> for StrVisitor { + type Value = &'a str; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed string") + } + + fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) // so easy + } + + fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E> + where + E: Error, + { + str::from_utf8(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a str { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(StrVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct BytesVisitor; + +impl<'a> Visitor<'a> for BytesVisitor { + type Value = &'a [u8]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed byte array") + } + + fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v) + } + + fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v.as_bytes()) + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_bytes(BytesVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +struct CStringVisitor; + +#[cfg(feature = "std")] +impl<'de> Visitor<'de> for CStringVisitor { + type Value = CString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let len = size_hint::cautious(seq.size_hint()); + let mut values = Vec::with_capacity(len); + + while let Some(value) = try!(seq.next_element()) { + values.push(value); + } + + CString::new(values).map_err(Error::custom) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for CString { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_byte_buf(CStringVisitor) + } +} + +macro_rules! forwarded_impl { + ( + $(#[doc = $doc:tt])* + ( $($id: ident),* ), $ty: ty, $func: expr + ) => { + $(#[doc = $doc])* + impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map($func) + } + } + } +} + +#[cfg(all(feature = "std", de_boxed_c_str))] +forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str); + +#[cfg(core_reverse)] +forwarded_impl!((T), Reverse<T>, Reverse); + +//////////////////////////////////////////////////////////////////////////////// + +struct OptionVisitor<T> { + marker: PhantomData<T>, +} + +impl<'de, T> Visitor<'de> for OptionVisitor<T> +where + T: Deserialize<'de>, +{ + type Value = Option<T>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("option") + } + + #[inline] + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(None) + } + + #[inline] + fn visit_none<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(None) + } + + #[inline] + fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + T::deserialize(deserializer).map(Some) + } + + #[doc(hidden)] + fn __private_visit_untagged_option<D>(self, deserializer: D) -> Result<Self::Value, ()> + where + D: Deserializer<'de>, + { + Ok(T::deserialize(deserializer).ok()) + } +} + +impl<'de, T> Deserialize<'de> for Option<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_option(OptionVisitor { + marker: PhantomData, + }) + } + + // The Some variant's repr is opaque, so we can't play cute tricks with its + // tag to have deserialize_in_place build the content in place unconditionally. + // + // FIXME: investigate whether branching on the old value being Some to + // deserialize_in_place the value is profitable (probably data-dependent?) +} + +//////////////////////////////////////////////////////////////////////////////// + +struct PhantomDataVisitor<T: ?Sized> { + marker: PhantomData<T>, +} + +impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor<T> { + type Value = PhantomData<T>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("unit") + } + + #[inline] + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(PhantomData) + } +} + +impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let visitor = PhantomDataVisitor { + marker: PhantomData, + }; + deserializer.deserialize_unit_struct("PhantomData", visitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +macro_rules! seq_impl { + ( + $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, + $access:ident, + $clear:expr, + $with_capacity:expr, + $reserve:expr, + $insert:expr + ) => { + impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty<T $(, $typaram)*> + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct SeqVisitor<T $(, $typaram)*> { + marker: PhantomData<$ty<T $(, $typaram)*>>, + } + + impl<'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor<T $(, $typaram)*> + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + type Value = $ty<T $(, $typaram)*>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq<A>(self, mut $access: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut values = $with_capacity; + + while let Some(value) = try!($access.next_element()) { + $insert(&mut values, value); + } + + Ok(values) + } + } + + let visitor = SeqVisitor { marker: PhantomData }; + deserializer.deserialize_seq(visitor) + } + + fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct SeqInPlaceVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>); + + impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqInPlaceVisitor<'a, T $(, $typaram)*> + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq<A>(mut self, mut $access: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + $clear(&mut self.0); + $reserve(&mut self.0, size_hint::cautious($access.size_hint())); + + // FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList) + while let Some(value) = try!($access.next_element()) { + $insert(&mut self.0, value); + } + + Ok(()) + } + } + + deserializer.deserialize_seq(SeqInPlaceVisitor(place)) + } + } + } +} + +// Dummy impl of reserve +#[cfg(any(feature = "std", feature = "alloc"))] +fn nop_reserve<T>(_seq: T, _n: usize) {} + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!( + BinaryHeap<T: Ord>, + seq, + BinaryHeap::clear, + BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())), + BinaryHeap::reserve, + BinaryHeap::push +); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!( + BTreeSet<T: Eq + Ord>, + seq, + BTreeSet::clear, + BTreeSet::new(), + nop_reserve, + BTreeSet::insert +); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!( + LinkedList<T>, + seq, + LinkedList::clear, + LinkedList::new(), + nop_reserve, + LinkedList::push_back +); + +#[cfg(feature = "std")] +seq_impl!( + HashSet<T: Eq + Hash, S: BuildHasher + Default>, + seq, + HashSet::clear, + HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()), + HashSet::reserve, + HashSet::insert); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!( + VecDeque<T>, + seq, + VecDeque::clear, + VecDeque::with_capacity(size_hint::cautious(seq.size_hint())), + VecDeque::reserve, + VecDeque::push_back +); + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, T> Deserialize<'de> for Vec<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct VecVisitor<T> { + marker: PhantomData<T>, + } + + impl<'de, T> Visitor<'de> for VecVisitor<T> + where + T: Deserialize<'de>, + { + type Value = Vec<T>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut values = Vec::with_capacity(size_hint::cautious(seq.size_hint())); + + while let Some(value) = try!(seq.next_element()) { + values.push(value); + } + + Ok(values) + } + } + + let visitor = VecVisitor { + marker: PhantomData, + }; + deserializer.deserialize_seq(visitor) + } + + fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec<T>); + + impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T> + where + T: Deserialize<'de>, + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let hint = size_hint::cautious(seq.size_hint()); + if let Some(additional) = hint.checked_sub(self.0.len()) { + self.0.reserve(additional); + } + + for i in 0..self.0.len() { + let next = { + let next_place = InPlaceSeed(&mut self.0[i]); + try!(seq.next_element_seed(next_place)) + }; + if next.is_none() { + self.0.truncate(i); + return Ok(()); + } + } + + while let Some(value) = try!(seq.next_element()) { + self.0.push(value); + } + + Ok(()) + } + } + + deserializer.deserialize_seq(VecInPlaceVisitor(place)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct ArrayVisitor<A> { + marker: PhantomData<A>, +} +struct ArrayInPlaceVisitor<'a, A: 'a>(&'a mut A); + +impl<A> ArrayVisitor<A> { + fn new() -> Self { + ArrayVisitor { + marker: PhantomData, + } + } +} + +impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> { + type Value = [T; 0]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an empty array") + } + + #[inline] + fn visit_seq<A>(self, _: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + Ok([]) + } +} + +// Does not require T: Deserialize<'de>. +impl<'de, T> Deserialize<'de> for [T; 0] { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple(0, ArrayVisitor::<[T; 0]>::new()) + } +} + +macro_rules! array_impls { + ($($len:expr => ($($n:tt)+))+) => { + $( + impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]> + where + T: Deserialize<'de>, + { + type Value = [T; $len]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("an array of length ", $len)) + } + + #[inline] + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + Ok([$( + match try!(seq.next_element()) { + Some(val) => val, + None => return Err(Error::invalid_length($n, &self)), + } + ),+]) + } + } + + impl<'a, 'de, T> Visitor<'de> for ArrayInPlaceVisitor<'a, [T; $len]> + where + T: Deserialize<'de>, + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("an array of length ", $len)) + } + + #[inline] + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut fail_idx = None; + for (idx, dest) in self.0[..].iter_mut().enumerate() { + if try!(seq.next_element_seed(InPlaceSeed(dest))).is_none() { + fail_idx = Some(idx); + break; + } + } + if let Some(idx) = fail_idx { + return Err(Error::invalid_length(idx, &self)); + } + Ok(()) + } + } + + impl<'de, T> Deserialize<'de> for [T; $len] + where + T: Deserialize<'de>, + { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new()) + } + + fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple($len, ArrayInPlaceVisitor(place)) + } + } + )+ + } +} + +array_impls! { + 1 => (0) + 2 => (0 1) + 3 => (0 1 2) + 4 => (0 1 2 3) + 5 => (0 1 2 3 4) + 6 => (0 1 2 3 4 5) + 7 => (0 1 2 3 4 5 6) + 8 => (0 1 2 3 4 5 6 7) + 9 => (0 1 2 3 4 5 6 7 8) + 10 => (0 1 2 3 4 5 6 7 8 9) + 11 => (0 1 2 3 4 5 6 7 8 9 10) + 12 => (0 1 2 3 4 5 6 7 8 9 10 11) + 13 => (0 1 2 3 4 5 6 7 8 9 10 11 12) + 14 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13) + 15 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14) + 16 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) + 17 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) + 18 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17) + 19 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18) + 20 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19) + 21 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) + 22 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21) + 23 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22) + 24 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23) + 25 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) + 26 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25) + 27 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26) + 28 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27) + 29 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28) + 30 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29) + 31 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30) + 32 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31) +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! tuple_impls { + ($($len:tt => ($($n:tt $name:ident)+))+) => { + $( + impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct TupleVisitor<$($name,)+> { + marker: PhantomData<($($name,)+)>, + } + + impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> { + type Value = ($($name,)+); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a tuple of size ", $len)) + } + + #[inline] + #[allow(non_snake_case)] + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + $( + let $name = match try!(seq.next_element()) { + Some(value) => value, + None => return Err(Error::invalid_length($n, &self)), + }; + )+ + + Ok(($($name,)+)) + } + } + + deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData }) + } + + #[inline] + fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct TupleInPlaceVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+)); + + impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleInPlaceVisitor<'a, $($name,)+> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a tuple of size ", $len)) + } + + #[inline] + #[allow(non_snake_case)] + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + $( + if try!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() { + return Err(Error::invalid_length($n, &self)); + } + )+ + + Ok(()) + } + } + + deserializer.deserialize_tuple($len, TupleInPlaceVisitor(place)) + } + } + )+ + } +} + +tuple_impls! { + 1 => (0 T0) + 2 => (0 T0 1 T1) + 3 => (0 T0 1 T1 2 T2) + 4 => (0 T0 1 T1 2 T2 3 T3) + 5 => (0 T0 1 T1 2 T2 3 T3 4 T4) + 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) + 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) + 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) + 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) + 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) + 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) + 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) + 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) + 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) + 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) + 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +macro_rules! map_impl { + ( + $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, + $access:ident, + $with_capacity:expr + ) => { + impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*> + where + K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*, + V: Deserialize<'de>, + $($typaram: $bound1 $(+ $bound2)*),* + { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct MapVisitor<K, V $(, $typaram)*> { + marker: PhantomData<$ty<K, V $(, $typaram)*>>, + } + + impl<'de, K, V $(, $typaram)*> Visitor<'de> for MapVisitor<K, V $(, $typaram)*> + where + K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*, + V: Deserialize<'de>, + $($typaram: $bound1 $(+ $bound2)*),* + { + type Value = $ty<K, V $(, $typaram)*>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_map<A>(self, mut $access: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut values = $with_capacity; + + while let Some((key, value)) = try!($access.next_entry()) { + values.insert(key, value); + } + + Ok(values) + } + } + + let visitor = MapVisitor { marker: PhantomData }; + deserializer.deserialize_map(visitor) + } + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +map_impl!( + BTreeMap<K: Ord, V>, + map, + BTreeMap::new()); + +#[cfg(feature = "std")] +map_impl!( + HashMap<K: Eq + Hash, V, S: BuildHasher + Default>, + map, + HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default())); + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +macro_rules! parse_ip_impl { + ($expecting:tt $ty:ty; $size:tt) => { + impl<'de> Deserialize<'de> for $ty { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + struct IpAddrVisitor; + + impl<'de> Visitor<'de> for IpAddrVisitor { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str($expecting) + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + s.parse().map_err(Error::custom) + } + } + + deserializer.deserialize_str(IpAddrVisitor) + } else { + <[u8; $size]>::deserialize(deserializer).map(<$ty>::from) + } + } + } + }; +} + +#[cfg(feature = "std")] +macro_rules! variant_identifier { + ( + $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* ) + $expecting_message: expr, + $variants_name: ident + ) => { + enum $name_kind { + $( $variant ),* + } + + static $variants_name: &'static [&'static str] = &[ $( stringify!($variant) ),*]; + + impl<'de> Deserialize<'de> for $name_kind { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct KindVisitor; + + impl<'de> Visitor<'de> for KindVisitor { + type Value = $name_kind; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str($expecting_message) + } + + fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> + where + E: Error, + { + match value { + $( + $index => Ok($name_kind :: $variant), + )* + _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self),), + } + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + $( + stringify!($variant) => Ok($name_kind :: $variant), + )* + _ => Err(Error::unknown_variant(value, $variants_name)), + } + } + + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match value { + $( + $bytes => Ok($name_kind :: $variant), + )* + _ => { + match str::from_utf8(value) { + Ok(value) => Err(Error::unknown_variant(value, $variants_name)), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)), + } + } + } + } + } + + deserializer.deserialize_identifier(KindVisitor) + } + } + } +} + +#[cfg(feature = "std")] +macro_rules! deserialize_enum { + ( + $name: ident $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* ) + $expecting_message: expr, + $deserializer: expr + ) => { + variant_identifier!{ + $name_kind ( $($variant; $bytes; $index),* ) + $expecting_message, + VARIANTS + } + + struct EnumVisitor; + impl<'de> Visitor<'de> for EnumVisitor { + type Value = $name; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a ", stringify!($name))) + } + + + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + match try!(data.variant()) { + $( + ($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant), + )* + } + } + } + $deserializer.deserialize_enum(stringify!($name), VARIANTS, EnumVisitor) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for net::IpAddr { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + struct IpAddrVisitor; + + impl<'de> Visitor<'de> for IpAddrVisitor { + type Value = net::IpAddr; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("IP address") + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + s.parse().map_err(Error::custom) + } + } + + deserializer.deserialize_str(IpAddrVisitor) + } else { + use lib::net::IpAddr; + deserialize_enum! { + IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) + "`V4` or `V6`", + deserializer + } + } + } +} + +#[cfg(feature = "std")] +parse_ip_impl!("IPv4 address" net::Ipv4Addr; 4); + +#[cfg(feature = "std")] +parse_ip_impl!("IPv6 address" net::Ipv6Addr; 16); + +#[cfg(feature = "std")] +macro_rules! parse_socket_impl { + ($expecting:tt $ty:ty, $new:expr) => { + impl<'de> Deserialize<'de> for $ty { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + struct SocketAddrVisitor; + + impl<'de> Visitor<'de> for SocketAddrVisitor { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str($expecting) + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + s.parse().map_err(Error::custom) + } + } + + deserializer.deserialize_str(SocketAddrVisitor) + } else { + <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port)) + } + } + } + }; +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for net::SocketAddr { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + struct SocketAddrVisitor; + + impl<'de> Visitor<'de> for SocketAddrVisitor { + type Value = net::SocketAddr; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("socket address") + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + s.parse().map_err(Error::custom) + } + } + + deserializer.deserialize_str(SocketAddrVisitor) + } else { + use lib::net::SocketAddr; + deserialize_enum! { + SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) + "`V4` or `V6`", + deserializer + } + } + } +} + +#[cfg(feature = "std")] +parse_socket_impl!("IPv4 socket address" net::SocketAddrV4, net::SocketAddrV4::new); + +#[cfg(feature = "std")] +parse_socket_impl!("IPv6 socket address" net::SocketAddrV6, |ip, port| net::SocketAddrV6::new( + ip, port, 0, 0 +)); + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +struct PathVisitor; + +#[cfg(feature = "std")] +impl<'a> Visitor<'a> for PathVisitor { + type Value = &'a Path; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed path") + } + + fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v.as_ref()) + } + + fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E> + where + E: Error, + { + str::from_utf8(v) + .map(AsRef::as_ref) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } +} + +#[cfg(feature = "std")] +impl<'de: 'a, 'a> Deserialize<'de> for &'a Path { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(PathVisitor) + } +} + +#[cfg(feature = "std")] +struct PathBufVisitor; + +#[cfg(feature = "std")] +impl<'de> Visitor<'de> for PathBufVisitor { + type Value = PathBuf; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("path string") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(From::from(v)) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + Ok(From::from(v)) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + str::from_utf8(v) + .map(From::from) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + String::from_utf8(v) + .map(From::from) + .map_err(|e| Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for PathBuf { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(PathBufVisitor) + } +} + +#[cfg(all(feature = "std", de_boxed_path))] +forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path); + +//////////////////////////////////////////////////////////////////////////////// + +// If this were outside of the serde crate, it would just use: +// +// #[derive(Deserialize)] +// #[serde(variant_identifier)] +#[cfg(all(feature = "std", any(unix, windows)))] +variant_identifier! { + OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1) + "`Unix` or `Windows`", + OSSTR_VARIANTS +} + +#[cfg(all(feature = "std", any(unix, windows)))] +struct OsStringVisitor; + +#[cfg(all(feature = "std", any(unix, windows)))] +impl<'de> Visitor<'de> for OsStringVisitor { + type Value = OsString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("os string") + } + + #[cfg(unix)] + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + use std::os::unix::ffi::OsStringExt; + + match try!(data.variant()) { + (OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec), + (OsStringKind::Windows, _) => Err(Error::custom( + "cannot deserialize Windows OS string on Unix", + )), + } + } + + #[cfg(windows)] + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + use std::os::windows::ffi::OsStringExt; + + match try!(data.variant()) { + (OsStringKind::Windows, v) => v + .newtype_variant::<Vec<u16>>() + .map(|vec| OsString::from_wide(&vec)), + (OsStringKind::Unix, _) => Err(Error::custom( + "cannot deserialize Unix OS string on Windows", + )), + } + } +} + +#[cfg(all(feature = "std", any(unix, windows)))] +impl<'de> Deserialize<'de> for OsString { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +forwarded_impl!((T), Box<T>, Box::new); + +#[cfg(any(feature = "std", feature = "alloc"))] +forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice); + +#[cfg(any(feature = "std", feature = "alloc"))] +forwarded_impl!((), Box<str>, String::into_boxed_str); + +#[cfg(all( + not(de_rc_dst), + feature = "rc", + any(feature = "std", feature = "alloc") +))] +forwarded_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Deserializing a data structure containing `Arc` will not attempt to + /// deduplicate `Arc` references to the same data. Every deserialized `Arc` + /// will end up with a strong count of 1. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + (T), Arc<T>, Arc::new +} + +#[cfg(all( + not(de_rc_dst), + feature = "rc", + any(feature = "std", feature = "alloc") +))] +forwarded_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Deserializing a data structure containing `Rc` will not attempt to + /// deduplicate `Rc` references to the same data. Every deserialized `Rc` + /// will end up with a strong count of 1. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + (T), Rc<T>, Rc::new +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> +where + T: ToOwned, + T::Owned: Deserialize<'de>, +{ + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + T::Owned::deserialize(deserializer).map(Cow::Owned) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting +/// `Weak<T>` has a reference count of 0 and cannot be upgraded. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +impl<'de, T: ?Sized> Deserialize<'de> for RcWeak<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + try!(Option::<T>::deserialize(deserializer)); + Ok(RcWeak::new()) + } +} + +/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting +/// `Weak<T>` has a reference count of 0 and cannot be upgraded. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +impl<'de, T: ?Sized> Deserialize<'de> for ArcWeak<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + try!(Option::<T>::deserialize(deserializer)); + Ok(ArcWeak::new()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] +macro_rules! box_forwarded_impl { + ( + $(#[doc = $doc:tt])* + $t:ident + ) => { + $(#[doc = $doc])* + impl<'de, T: ?Sized> Deserialize<'de> for $t<T> + where + Box<T>: Deserialize<'de>, + { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Box::deserialize(deserializer).map(Into::into) + } + } + }; +} + +#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] +box_forwarded_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Deserializing a data structure containing `Rc` will not attempt to + /// deduplicate `Rc` references to the same data. Every deserialized `Rc` + /// will end up with a strong count of 1. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + Rc +} + +#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] +box_forwarded_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Deserializing a data structure containing `Arc` will not attempt to + /// deduplicate `Arc` references to the same data. Every deserialized `Arc` + /// will end up with a strong count of 1. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + Arc +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, T> Deserialize<'de> for Cell<T> +where + T: Deserialize<'de> + Copy, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + T::deserialize(deserializer).map(Cell::new) + } +} + +forwarded_impl!((T), RefCell<T>, RefCell::new); + +#[cfg(feature = "std")] +forwarded_impl!((T), Mutex<T>, Mutex::new); + +#[cfg(feature = "std")] +forwarded_impl!((T), RwLock<T>, RwLock::new); + +//////////////////////////////////////////////////////////////////////////////// + +// This is a cleaned-up version of the impl generated by: +// +// #[derive(Deserialize)] +// #[serde(deny_unknown_fields)] +// struct Duration { +// secs: u64, +// nanos: u32, +// } +#[cfg(any(core_duration, feature = "std"))] +impl<'de> Deserialize<'de> for Duration { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Secs, + Nanos, + }; + + impl<'de> Deserialize<'de> for Field { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`secs` or `nanos`") + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + "secs" => Ok(Field::Secs), + "nanos" => Ok(Field::Nanos), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match value { + b"secs" => Ok(Field::Secs), + b"nanos" => Ok(Field::Nanos), + _ => { + let value = ::export::from_utf8_lossy(value); + Err(Error::unknown_field(&value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct DurationVisitor; + + impl<'de> Visitor<'de> for DurationVisitor { + type Value = Duration; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct Duration") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let secs: u64 = match try!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + let nanos: u32 = match try!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(1, &self)); + } + }; + Ok(Duration::new(secs, nanos)) + } + + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut secs: Option<u64> = None; + let mut nanos: Option<u32> = None; + while let Some(key) = try!(map.next_key()) { + match key { + Field::Secs => { + if secs.is_some() { + return Err(<A::Error as Error>::duplicate_field("secs")); + } + secs = Some(try!(map.next_value())); + } + Field::Nanos => { + if nanos.is_some() { + return Err(<A::Error as Error>::duplicate_field("nanos")); + } + nanos = Some(try!(map.next_value())); + } + } + } + let secs = match secs { + Some(secs) => secs, + None => return Err(<A::Error as Error>::missing_field("secs")), + }; + let nanos = match nanos { + Some(nanos) => nanos, + None => return Err(<A::Error as Error>::missing_field("nanos")), + }; + Ok(Duration::new(secs, nanos)) + } + } + + const FIELDS: &'static [&'static str] = &["secs", "nanos"]; + deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for SystemTime { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + // Reuse duration + enum Field { + Secs, + Nanos, + }; + + impl<'de> Deserialize<'de> for Field { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`") + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + "secs_since_epoch" => Ok(Field::Secs), + "nanos_since_epoch" => Ok(Field::Nanos), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match value { + b"secs_since_epoch" => Ok(Field::Secs), + b"nanos_since_epoch" => Ok(Field::Nanos), + _ => { + let value = String::from_utf8_lossy(value); + Err(Error::unknown_field(&value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct DurationVisitor; + + impl<'de> Visitor<'de> for DurationVisitor { + type Value = Duration; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct SystemTime") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let secs: u64 = match try!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + let nanos: u32 = match try!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(1, &self)); + } + }; + Ok(Duration::new(secs, nanos)) + } + + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut secs: Option<u64> = None; + let mut nanos: Option<u32> = None; + while let Some(key) = try!(map.next_key()) { + match key { + Field::Secs => { + if secs.is_some() { + return Err(<A::Error as Error>::duplicate_field( + "secs_since_epoch", + )); + } + secs = Some(try!(map.next_value())); + } + Field::Nanos => { + if nanos.is_some() { + return Err(<A::Error as Error>::duplicate_field( + "nanos_since_epoch", + )); + } + nanos = Some(try!(map.next_value())); + } + } + } + let secs = match secs { + Some(secs) => secs, + None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")), + }; + let nanos = match nanos { + Some(nanos) => nanos, + None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")), + }; + Ok(Duration::new(secs, nanos)) + } + } + + const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"]; + let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor)); + Ok(UNIX_EPOCH + duration) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Similar to: +// +// #[derive(Deserialize)] +// #[serde(deny_unknown_fields)] +// struct Range { +// start: u64, +// end: u32, +// } +impl<'de, Idx> Deserialize<'de> for Range<Idx> +where + Idx: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let (start, end) = deserializer.deserialize_struct( + "Range", + range::FIELDS, + range::RangeVisitor { + expecting: "struct Range", + phantom: PhantomData, + }, + )?; + Ok(start..end) + } +} + +#[cfg(range_inclusive)] +impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx> +where + Idx: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let (start, end) = deserializer.deserialize_struct( + "RangeInclusive", + range::FIELDS, + range::RangeVisitor { + expecting: "struct RangeInclusive", + phantom: PhantomData, + }, + )?; + Ok(RangeInclusive::new(start, end)) + } +} + +mod range { + use lib::*; + + use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + + pub const FIELDS: &'static [&'static str] = &["start", "end"]; + + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Start, + End, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`start` or `end`") + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + "start" => Ok(Field::Start), + "end" => Ok(Field::End), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match value { + b"start" => Ok(Field::Start), + b"end" => Ok(Field::End), + _ => { + let value = ::export::from_utf8_lossy(value); + Err(Error::unknown_field(&value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + pub struct RangeVisitor<Idx> { + pub expecting: &'static str, + pub phantom: PhantomData<Idx>, + } + + impl<'de, Idx> Visitor<'de> for RangeVisitor<Idx> + where + Idx: Deserialize<'de>, + { + type Value = (Idx, Idx); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.expecting) + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let start: Idx = match try!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + let end: Idx = match try!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(1, &self)); + } + }; + Ok((start, end)) + } + + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut start: Option<Idx> = None; + let mut end: Option<Idx> = None; + while let Some(key) = try!(map.next_key()) { + match key { + Field::Start => { + if start.is_some() { + return Err(<A::Error as Error>::duplicate_field("start")); + } + start = Some(try!(map.next_value())); + } + Field::End => { + if end.is_some() { + return Err(<A::Error as Error>::duplicate_field("end")); + } + end = Some(try!(map.next_value())); + } + } + } + let start = match start { + Some(start) => start, + None => return Err(<A::Error as Error>::missing_field("start")), + }; + let end = match end { + Some(end) => end, + None => return Err(<A::Error as Error>::missing_field("end")), + }; + Ok((start, end)) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(ops_bound, collections_bound))] +impl<'de, T> Deserialize<'de> for Bound<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + enum Field { + Unbounded, + Included, + Excluded, + } + + impl<'de> Deserialize<'de> for Field { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`Unbounded`, `Included` or `Excluded`") + } + + fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> + where + E: Error, + { + match value { + 0 => Ok(Field::Unbounded), + 1 => Ok(Field::Included), + 2 => Ok(Field::Excluded), + _ => Err(Error::invalid_value( + Unexpected::Unsigned(value), + &self, + )), + } + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + "Unbounded" => Ok(Field::Unbounded), + "Included" => Ok(Field::Included), + "Excluded" => Ok(Field::Excluded), + _ => Err(Error::unknown_variant(value, VARIANTS)), + } + } + + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match value { + b"Unbounded" => Ok(Field::Unbounded), + b"Included" => Ok(Field::Included), + b"Excluded" => Ok(Field::Excluded), + _ => match str::from_utf8(value) { + Ok(value) => Err(Error::unknown_variant(value, VARIANTS)), + Err(_) => { + Err(Error::invalid_value(Unexpected::Bytes(value), &self)) + } + }, + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct BoundVisitor<T>(PhantomData<Bound<T>>); + + impl<'de, T> Visitor<'de> for BoundVisitor<T> + where + T: Deserialize<'de>, + { + type Value = Bound<T>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("enum Bound") + } + + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + match try!(data.variant()) { + (Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded), + (Field::Included, v) => v.newtype_variant().map(Bound::Included), + (Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded), + } + } + } + + const VARIANTS: &'static [&'static str] = &["Unbounded", "Included", "Excluded"]; + + deserializer.deserialize_enum("Bound", VARIANTS, BoundVisitor(PhantomData)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! nonzero_integers { + ( $( $T: ident, )+ ) => { + $( + #[cfg(num_nonzero)] + impl<'de> Deserialize<'de> for num::$T { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let value = try!(Deserialize::deserialize(deserializer)); + match <num::$T>::new(value) { + Some(nonzero) => Ok(nonzero), + None => Err(Error::custom("expected a non-zero value")), + } + } + } + )+ + }; +} + +nonzero_integers! { + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroUsize, +} + +#[cfg(num_nonzero_signed)] +nonzero_integers! { + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroIsize, +} + +// Currently 128-bit integers do not work on Emscripten targets so we need an +// additional `#[cfg]` +serde_if_integer128! { + nonzero_integers! { + NonZeroU128, + } + + #[cfg(num_nonzero_signed)] + nonzero_integers! { + NonZeroI128, + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, T, E> Deserialize<'de> for Result<T, E> +where + T: Deserialize<'de>, + E: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(variant_identifier)] + enum Field { + Ok, + Err, + } + + impl<'de> Deserialize<'de> for Field { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`Ok` or `Err`") + } + + fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> + where + E: Error, + { + match value { + 0 => Ok(Field::Ok), + 1 => Ok(Field::Err), + _ => Err(Error::invalid_value( + Unexpected::Unsigned(value), + &self, + )), + } + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + "Ok" => Ok(Field::Ok), + "Err" => Ok(Field::Err), + _ => Err(Error::unknown_variant(value, VARIANTS)), + } + } + + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match value { + b"Ok" => Ok(Field::Ok), + b"Err" => Ok(Field::Err), + _ => match str::from_utf8(value) { + Ok(value) => Err(Error::unknown_variant(value, VARIANTS)), + Err(_) => { + Err(Error::invalid_value(Unexpected::Bytes(value), &self)) + } + }, + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct ResultVisitor<T, E>(PhantomData<Result<T, E>>); + + impl<'de, T, E> Visitor<'de> for ResultVisitor<T, E> + where + T: Deserialize<'de>, + E: Deserialize<'de>, + { + type Value = Result<T, E>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("enum Result") + } + + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + match try!(data.variant()) { + (Field::Ok, v) => v.newtype_variant().map(Ok), + (Field::Err, v) => v.newtype_variant().map(Err), + } + } + } + + const VARIANTS: &'static [&'static str] = &["Ok", "Err"]; + + deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl<'de, T> Deserialize<'de> for Wrapping<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Wrapping) + } +} + +#[cfg(all(feature = "std", std_atomic))] +macro_rules! atomic_impl { + ($($ty:ident)*) => { + $( + impl<'de> Deserialize<'de> for $ty { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Self::new) + } + } + )* + }; +} + +#[cfg(all(feature = "std", std_atomic))] +atomic_impl! { + AtomicBool + AtomicI8 AtomicI16 AtomicI32 AtomicIsize + AtomicU8 AtomicU16 AtomicU32 AtomicUsize +} + +#[cfg(all(feature = "std", std_atomic64))] +atomic_impl! { + AtomicI64 AtomicU64 +} diff --git a/third_party/rust/serde/src/de/mod.rs b/third_party/rust/serde/src/de/mod.rs new file mode 100644 index 0000000000..6d39473633 --- /dev/null +++ b/third_party/rust/serde/src/de/mod.rs @@ -0,0 +1,2276 @@ +//! Generic data structure deserialization framework. +//! +//! The two most important traits in this module are [`Deserialize`] and +//! [`Deserializer`]. +//! +//! - **A type that implements `Deserialize` is a data structure** that can be +//! deserialized from any data format supported by Serde, and conversely +//! - **A type that implements `Deserializer` is a data format** that can +//! deserialize any data structure supported by Serde. +//! +//! # The Deserialize trait +//! +//! Serde provides [`Deserialize`] implementations for many Rust primitive and +//! standard library types. The complete list is below. All of these can be +//! deserialized using Serde out of the box. +//! +//! Additionally, Serde provides a procedural macro called [`serde_derive`] to +//! automatically generate [`Deserialize`] implementations for structs and enums +//! in your program. See the [derive section of the manual] for how to use this. +//! +//! In rare cases it may be necessary to implement [`Deserialize`] manually for +//! some type in your program. See the [Implementing `Deserialize`] section of +//! the manual for more about this. +//! +//! Third-party crates may provide [`Deserialize`] implementations for types +//! that they expose. For example the [`linked-hash-map`] crate provides a +//! [`LinkedHashMap<K, V>`] type that is deserializable by Serde because the +//! crate provides an implementation of [`Deserialize`] for it. +//! +//! # The Deserializer trait +//! +//! [`Deserializer`] implementations are provided by third-party crates, for +//! example [`serde_json`], [`serde_yaml`] and [`bincode`]. +//! +//! A partial list of well-maintained formats is given on the [Serde +//! website][data formats]. +//! +//! # Implementations of Deserialize provided by Serde +//! +//! This is a slightly different set of types than what is supported for +//! serialization. Some types can be serialized by Serde but not deserialized. +//! One example is `OsStr`. +//! +//! - **Primitive types**: +//! - bool +//! - i8, i16, i32, i64, i128, isize +//! - u8, u16, u32, u64, u128, usize +//! - f32, f64 +//! - char +//! - **Compound types**: +//! - \[T; 0\] through \[T; 32\] +//! - tuples up to size 16 +//! - **Common standard library types**: +//! - String +//! - Option\<T\> +//! - Result\<T, E\> +//! - PhantomData\<T\> +//! - **Wrapper types**: +//! - Box\<T\> +//! - Box\<\[T\]\> +//! - Box\<str\> +//! - Cow\<'a, T\> +//! - Cell\<T\> +//! - RefCell\<T\> +//! - Mutex\<T\> +//! - RwLock\<T\> +//! - Rc\<T\> *(if* features = ["rc"] *is enabled)* +//! - Arc\<T\> *(if* features = ["rc"] *is enabled)* +//! - **Collection types**: +//! - BTreeMap\<K, V\> +//! - BTreeSet\<T\> +//! - BinaryHeap\<T\> +//! - HashMap\<K, V, H\> +//! - HashSet\<T, H\> +//! - LinkedList\<T\> +//! - VecDeque\<T\> +//! - Vec\<T\> +//! - **Zero-copy types**: +//! - &str +//! - &\[u8\] +//! - **FFI types**: +//! - CString +//! - Box\<CStr\> +//! - OsString +//! - **Miscellaneous standard library types**: +//! - Duration +//! - SystemTime +//! - Path +//! - PathBuf +//! - Range\<T\> +//! - RangeInclusive\<T\> +//! - Bound\<T\> +//! - num::NonZero* +//! - `!` *(unstable)* +//! - **Net types**: +//! - IpAddr +//! - Ipv4Addr +//! - Ipv6Addr +//! - SocketAddr +//! - SocketAddrV4 +//! - SocketAddrV6 +//! +//! [Implementing `Deserialize`]: https://serde.rs/impl-deserialize.html +//! [`Deserialize`]: ../trait.Deserialize.html +//! [`Deserializer`]: ../trait.Deserializer.html +//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +//! [`bincode`]: https://github.com/servo/bincode +//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +//! [`serde_derive`]: https://crates.io/crates/serde_derive +//! [`serde_json`]: https://github.com/serde-rs/json +//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml +//! [derive section of the manual]: https://serde.rs/derive.html +//! [data formats]: https://serde.rs/#data-formats + +use lib::*; + +//////////////////////////////////////////////////////////////////////////////// + +pub mod value; + +mod from_primitive; +mod ignored_any; +mod impls; +mod utf8; + +pub use self::ignored_any::IgnoredAny; + +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use std::error::Error as StdError; +#[cfg(not(feature = "std"))] +#[doc(no_inline)] +pub use std_error::Error as StdError; + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! declare_error_trait { + (Error: Sized $(+ $($supertrait:ident)::+)*) => { + /// The `Error` trait allows `Deserialize` implementations to create descriptive + /// error messages belonging to the `Deserializer` against which they are + /// currently running. + /// + /// Every `Deserializer` declares an `Error` type that encompasses both + /// general-purpose deserialization errors as well as errors specific to the + /// particular deserialization format. For example the `Error` type of + /// `serde_json` can represent errors like an invalid JSON escape sequence or an + /// unterminated string literal, in addition to the error cases that are part of + /// this trait. + /// + /// Most deserializers should only need to provide the `Error::custom` method + /// and inherit the default behavior for the other methods. + /// + /// # Example implementation + /// + /// The [example data format] presented on the website shows an error + /// type appropriate for a basic JSON data format. + /// + /// [example data format]: https://serde.rs/data-format.html + pub trait Error: Sized $(+ $($supertrait)::+)* { + /// Raised when there is general error when deserializing a type. + /// + /// The message should not be capitalized and should not end with a period. + /// + /// ```edition2018 + /// # use std::str::FromStr; + /// # + /// # struct IpAddr; + /// # + /// # impl FromStr for IpAddr { + /// # type Err = String; + /// # + /// # fn from_str(_: &str) -> Result<Self, String> { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::de::{self, Deserialize, Deserializer}; + /// + /// impl<'de> Deserialize<'de> for IpAddr { + /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + /// where + /// D: Deserializer<'de>, + /// { + /// let s = String::deserialize(deserializer)?; + /// s.parse().map_err(de::Error::custom) + /// } + /// } + /// ``` + fn custom<T>(msg: T) -> Self + where + T: Display; + + /// Raised when a `Deserialize` receives a type different from what it was + /// expecting. + /// + /// The `unexp` argument provides information about what type was received. + /// This is the type that was present in the input file or other source data + /// of the Deserializer. + /// + /// The `exp` argument provides information about what type was being + /// expected. This is the type that is written in the program. + /// + /// For example if we try to deserialize a String out of a JSON file + /// containing an integer, the unexpected type is the integer and the + /// expected type is the string. + #[cold] + fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self { + Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) + } + + /// Raised when a `Deserialize` receives a value of the right type but that + /// is wrong for some other reason. + /// + /// The `unexp` argument provides information about what value was received. + /// This is the value that was present in the input file or other source + /// data of the Deserializer. + /// + /// The `exp` argument provides information about what value was being + /// expected. This is the type that is written in the program. + /// + /// For example if we try to deserialize a String out of some binary data + /// that is not valid UTF-8, the unexpected value is the bytes and the + /// expected value is a string. + #[cold] + fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self { + Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp)) + } + + /// Raised when deserializing a sequence or map and the input data contains + /// too many or too few elements. + /// + /// The `len` argument is the number of elements encountered. The sequence + /// or map may have expected more arguments or fewer arguments. + /// + /// The `exp` argument provides information about what data was being + /// expected. For example `exp` might say that a tuple of size 6 was + /// expected. + #[cold] + fn invalid_length(len: usize, exp: &Expected) -> Self { + Error::custom(format_args!("invalid length {}, expected {}", len, exp)) + } + + /// Raised when a `Deserialize` enum type received a variant with an + /// unrecognized name. + #[cold] + fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { + if expected.is_empty() { + Error::custom(format_args!( + "unknown variant `{}`, there are no variants", + variant + )) + } else { + Error::custom(format_args!( + "unknown variant `{}`, expected {}", + variant, + OneOf { names: expected } + )) + } + } + + /// Raised when a `Deserialize` struct type received a field with an + /// unrecognized name. + #[cold] + fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { + if expected.is_empty() { + Error::custom(format_args!( + "unknown field `{}`, there are no fields", + field + )) + } else { + Error::custom(format_args!( + "unknown field `{}`, expected {}", + field, + OneOf { names: expected } + )) + } + } + + /// Raised when a `Deserialize` struct type expected to receive a required + /// field with a particular name but that field was not present in the + /// input. + #[cold] + fn missing_field(field: &'static str) -> Self { + Error::custom(format_args!("missing field `{}`", field)) + } + + /// Raised when a `Deserialize` struct type received more than one of the + /// same field. + #[cold] + fn duplicate_field(field: &'static str) -> Self { + Error::custom(format_args!("duplicate field `{}`", field)) + } + } + } +} + +#[cfg(feature = "std")] +declare_error_trait!(Error: Sized + StdError); + +#[cfg(not(feature = "std"))] +declare_error_trait!(Error: Sized + Debug + Display); + +/// `Unexpected` represents an unexpected invocation of any one of the `Visitor` +/// trait methods. +/// +/// This is used as an argument to the `invalid_type`, `invalid_value`, and +/// `invalid_length` methods of the `Error` trait to build error messages. +/// +/// ```edition2018 +/// # use std::fmt; +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # +/// # struct Example; +/// # +/// # impl<'de> Visitor<'de> for Example { +/// # type Value = (); +/// # +/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// # write!(formatter, "definitely not a boolean") +/// # } +/// # +/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> +/// where +/// E: de::Error, +/// { +/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) +/// } +/// # } +/// ``` +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum Unexpected<'a> { + /// The input contained a boolean value that was not expected. + Bool(bool), + + /// The input contained an unsigned integer `u8`, `u16`, `u32` or `u64` that + /// was not expected. + Unsigned(u64), + + /// The input contained a signed integer `i8`, `i16`, `i32` or `i64` that + /// was not expected. + Signed(i64), + + /// The input contained a floating point `f32` or `f64` that was not + /// expected. + Float(f64), + + /// The input contained a `char` that was not expected. + Char(char), + + /// The input contained a `&str` or `String` that was not expected. + Str(&'a str), + + /// The input contained a `&[u8]` or `Vec<u8>` that was not expected. + Bytes(&'a [u8]), + + /// The input contained a unit `()` that was not expected. + Unit, + + /// The input contained an `Option<T>` that was not expected. + Option, + + /// The input contained a newtype struct that was not expected. + NewtypeStruct, + + /// The input contained a sequence that was not expected. + Seq, + + /// The input contained a map that was not expected. + Map, + + /// The input contained an enum that was not expected. + Enum, + + /// The input contained a unit variant that was not expected. + UnitVariant, + + /// The input contained a newtype variant that was not expected. + NewtypeVariant, + + /// The input contained a tuple variant that was not expected. + TupleVariant, + + /// The input contained a struct variant that was not expected. + StructVariant, + + /// A message stating what uncategorized thing the input contained that was + /// not expected. + /// + /// The message should be a noun or noun phrase, not capitalized and without + /// a period. An example message is "unoriginal superhero". + Other(&'a str), +} + +impl<'a> fmt::Display for Unexpected<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + use self::Unexpected::*; + match *self { + Bool(b) => write!(formatter, "boolean `{}`", b), + Unsigned(i) => write!(formatter, "integer `{}`", i), + Signed(i) => write!(formatter, "integer `{}`", i), + Float(f) => write!(formatter, "floating point `{}`", f), + Char(c) => write!(formatter, "character `{}`", c), + Str(s) => write!(formatter, "string {:?}", s), + Bytes(_) => write!(formatter, "byte array"), + Unit => write!(formatter, "unit value"), + Option => write!(formatter, "Option value"), + NewtypeStruct => write!(formatter, "newtype struct"), + Seq => write!(formatter, "sequence"), + Map => write!(formatter, "map"), + Enum => write!(formatter, "enum"), + UnitVariant => write!(formatter, "unit variant"), + NewtypeVariant => write!(formatter, "newtype variant"), + TupleVariant => write!(formatter, "tuple variant"), + StructVariant => write!(formatter, "struct variant"), + Other(other) => formatter.write_str(other), + } + } +} + +/// `Expected` represents an explanation of what data a `Visitor` was expecting +/// to receive. +/// +/// This is used as an argument to the `invalid_type`, `invalid_value`, and +/// `invalid_length` methods of the `Error` trait to build error messages. The +/// message should be a noun or noun phrase that completes the sentence "This +/// Visitor expects to receive ...", for example the message could be "an +/// integer between 0 and 64". The message should not be capitalized and should +/// not end with a period. +/// +/// Within the context of a `Visitor` implementation, the `Visitor` itself +/// (`&self`) is an implementation of this trait. +/// +/// ```edition2018 +/// # use std::fmt; +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # +/// # struct Example; +/// # +/// # impl<'de> Visitor<'de> for Example { +/// # type Value = (); +/// # +/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// # write!(formatter, "definitely not a boolean") +/// # } +/// # +/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> +/// where +/// E: de::Error, +/// { +/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) +/// } +/// # } +/// ``` +/// +/// Outside of a `Visitor`, `&"..."` can be used. +/// +/// ```edition2018 +/// # use serde::de::{self, Unexpected}; +/// # +/// # fn example<E>() -> Result<(), E> +/// # where +/// # E: de::Error, +/// # { +/// # let v = true; +/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer")); +/// # } +/// ``` +pub trait Expected { + /// Format an explanation of what data was being expected. Same signature as + /// the `Display` and `Debug` traits. + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result; +} + +impl<'de, T> Expected for T +where + T: Visitor<'de>, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.expecting(formatter) + } +} + +impl<'a> Expected for &'a str { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self) + } +} + +impl<'a> Display for Expected + 'a { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Expected::fmt(self, formatter) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data structure** that can be deserialized from any data format supported +/// by Serde. +/// +/// Serde provides `Deserialize` implementations for many Rust primitive and +/// standard library types. The complete list is [here][de]. All of these can +/// be deserialized using Serde out of the box. +/// +/// Additionally, Serde provides a procedural macro called `serde_derive` to +/// automatically generate `Deserialize` implementations for structs and enums +/// in your program. See the [derive section of the manual][derive] for how to +/// use this. +/// +/// In rare cases it may be necessary to implement `Deserialize` manually for +/// some type in your program. See the [Implementing +/// `Deserialize`][impl-deserialize] section of the manual for more about this. +/// +/// Third-party crates may provide `Deserialize` implementations for types that +/// they expose. For example the `linked-hash-map` crate provides a +/// `LinkedHashMap<K, V>` type that is deserializable by Serde because the crate +/// provides an implementation of `Deserialize` for it. +/// +/// [de]: https://docs.serde.rs/serde/de/index.html +/// [derive]: https://serde.rs/derive.html +/// [impl-deserialize]: https://serde.rs/impl-deserialize.html +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by `Self` when deserialized. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +pub trait Deserialize<'de>: Sized { + /// Deserialize this value from the given Serde deserializer. + /// + /// See the [Implementing `Deserialize`][impl-deserialize] section of the + /// manual for more information about how to implement this method. + /// + /// [impl-deserialize]: https://serde.rs/impl-deserialize.html + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>; + + /// Deserializes a value into `self` from the given Deserializer. + /// + /// The purpose of this method is to allow the deserializer to reuse + /// resources and avoid copies. As such, if this method returns an error, + /// `self` will be in an indeterminate state where some parts of the struct + /// have been overwritten. Although whatever state that is will be + /// memory-safe. + /// + /// This is generally useful when repeatedly deserializing values that + /// are processed one at a time, where the value of `self` doesn't matter + /// when the next deserialization occurs. + /// + /// If you manually implement this, your recursive deserializations should + /// use `deserialize_in_place`. + /// + /// This method is stable and an official public API, but hidden from the + /// documentation because it is almost never what newbies are looking for. + /// Showing it in rustdoc would cause it to be featured more prominently + /// than it deserves. + #[doc(hidden)] + fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + // Default implementation just delegates to `deserialize` impl. + *place = Deserialize::deserialize(deserializer)?; + Ok(()) + } +} + +/// A data structure that can be deserialized without borrowing any data from +/// the deserializer. +/// +/// This is primarily useful for trait bounds on functions. For example a +/// `from_str` function may be able to deserialize a data structure that borrows +/// from the input string, but a `from_reader` function may only deserialize +/// owned data. +/// +/// ```edition2018 +/// # use serde::de::{Deserialize, DeserializeOwned}; +/// # use std::io::{Read, Result}; +/// # +/// # trait Ignore { +/// fn from_str<'a, T>(s: &'a str) -> Result<T> +/// where +/// T: Deserialize<'a>; +/// +/// fn from_reader<R, T>(rdr: R) -> Result<T> +/// where +/// R: Read, +/// T: DeserializeOwned; +/// # } +/// ``` +/// +/// # Lifetime +/// +/// The relationship between `Deserialize` and `DeserializeOwned` in trait +/// bounds is explained in more detail on the page [Understanding deserializer +/// lifetimes]. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +pub trait DeserializeOwned: for<'de> Deserialize<'de> {} +impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {} + +/// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you +/// ever find yourself looking for a way to pass data into a `Deserialize` impl, +/// this trait is the way to do it. +/// +/// As one example of stateful deserialization consider deserializing a JSON +/// array into an existing buffer. Using the `Deserialize` trait we could +/// deserialize a JSON array into a `Vec<T>` but it would be a freshly allocated +/// `Vec<T>`; there is no way for `Deserialize` to reuse a previously allocated +/// buffer. Using `DeserializeSeed` instead makes this possible as in the +/// example code below. +/// +/// The canonical API for stateless deserialization looks like this: +/// +/// ```edition2018 +/// # use serde::Deserialize; +/// # +/// # enum Error {} +/// # +/// fn func<'de, T: Deserialize<'de>>() -> Result<T, Error> +/// # { +/// # unimplemented!() +/// # } +/// ``` +/// +/// Adjusting an API like this to support stateful deserialization is a matter +/// of accepting a seed as input: +/// +/// ```edition2018 +/// # use serde::de::DeserializeSeed; +/// # +/// # enum Error {} +/// # +/// fn func_seed<'de, T: DeserializeSeed<'de>>(seed: T) -> Result<T::Value, Error> +/// # { +/// # let _ = seed; +/// # unimplemented!() +/// # } +/// ``` +/// +/// In practice the majority of deserialization is stateless. An API expecting a +/// seed can be appeased by passing `std::marker::PhantomData` as a seed in the +/// case of stateless deserialization. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by `Self::Value` when deserialized. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example +/// +/// Suppose we have JSON that looks like `[[1, 2], [3, 4, 5], [6]]` and we need +/// to deserialize it into a flat representation like `vec![1, 2, 3, 4, 5, 6]`. +/// Allocating a brand new `Vec<T>` for each subarray would be slow. Instead we +/// would like to allocate a single `Vec<T>` and then deserialize each subarray +/// into it. This requires stateful deserialization using the `DeserializeSeed` +/// trait. +/// +/// ```edition2018 +/// use std::fmt; +/// use std::marker::PhantomData; +/// +/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor}; +/// +/// // A DeserializeSeed implementation that uses stateful deserialization to +/// // append array elements onto the end of an existing vector. The preexisting +/// // state ("seed") in this case is the Vec<T>. The `deserialize` method of +/// // `ExtendVec` will be traversing the inner arrays of the JSON input and +/// // appending each integer into the existing Vec. +/// struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>); +/// +/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T> +/// where +/// T: Deserialize<'de>, +/// { +/// // The return type of the `deserialize` method. This implementation +/// // appends onto an existing vector but does not create any new data +/// // structure, so the return type is (). +/// type Value = (); +/// +/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> +/// where +/// D: Deserializer<'de>, +/// { +/// // Visitor implementation that will walk an inner array of the JSON +/// // input. +/// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>); +/// +/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T> +/// where +/// T: Deserialize<'de>, +/// { +/// type Value = (); +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "an array of integers") +/// } +/// +/// fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error> +/// where +/// A: SeqAccess<'de>, +/// { +/// // Visit each element in the inner array and push it onto +/// // the existing vector. +/// while let Some(elem) = seq.next_element()? { +/// self.0.push(elem); +/// } +/// Ok(()) +/// } +/// } +/// +/// deserializer.deserialize_seq(ExtendVecVisitor(self.0)) +/// } +/// } +/// +/// // Visitor implementation that will walk the outer array of the JSON input. +/// struct FlattenedVecVisitor<T>(PhantomData<T>); +/// +/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor<T> +/// where +/// T: Deserialize<'de>, +/// { +/// // This Visitor constructs a single Vec<T> to hold the flattened +/// // contents of the inner arrays. +/// type Value = Vec<T>; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "an array of arrays") +/// } +/// +/// fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error> +/// where +/// A: SeqAccess<'de>, +/// { +/// // Create a single Vec to hold the flattened contents. +/// let mut vec = Vec::new(); +/// +/// // Each iteration through this loop is one inner array. +/// while let Some(()) = seq.next_element_seed(ExtendVec(&mut vec))? { +/// // Nothing to do; inner array has been appended into `vec`. +/// } +/// +/// // Return the finished vec. +/// Ok(vec) +/// } +/// } +/// +/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> +/// # where +/// # D: Deserializer<'de>, +/// # { +/// let visitor = FlattenedVecVisitor(PhantomData); +/// let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?; +/// # Ok(()) +/// # } +/// ``` +pub trait DeserializeSeed<'de>: Sized { + /// The type produced by using this seed. + type Value; + + /// Equivalent to the more common `Deserialize::deserialize` method, except + /// with some initial piece of data (the seed) passed in. + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>; +} + +impl<'de, T> DeserializeSeed<'de> for PhantomData<T> +where + T: Deserialize<'de>, +{ + type Value = T; + + #[inline] + fn deserialize<D>(self, deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + { + T::deserialize(deserializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data format** that can deserialize any data structure supported by +/// Serde. +/// +/// The role of this trait is to define the deserialization half of the [Serde +/// data model], which is a way to categorize every Rust data type into one of +/// 29 possible types. Each method of the `Deserializer` trait corresponds to one +/// of the types of the data model. +/// +/// Implementations of `Deserialize` map themselves into this data model by +/// passing to the `Deserializer` a `Visitor` implementation that can receive +/// these various types. +/// +/// The types that make up the Serde data model are: +/// +/// - **14 primitive types** +/// - bool +/// - i8, i16, i32, i64, i128 +/// - u8, u16, u32, u64, u128 +/// - f32, f64 +/// - char +/// - **string** +/// - UTF-8 bytes with a length and no null terminator. +/// - When serializing, all strings are handled equally. When deserializing, +/// there are three flavors of strings: transient, owned, and borrowed. +/// - **byte array** - \[u8\] +/// - Similar to strings, during deserialization byte arrays can be +/// transient, owned, or borrowed. +/// - **option** +/// - Either none or some value. +/// - **unit** +/// - The type of `()` in Rust. It represents an anonymous value containing +/// no data. +/// - **unit_struct** +/// - For example `struct Unit` or `PhantomData<T>`. It represents a named +/// value containing no data. +/// - **unit_variant** +/// - For example the `E::A` and `E::B` in `enum E { A, B }`. +/// - **newtype_struct** +/// - For example `struct Millimeters(u8)`. +/// - **newtype_variant** +/// - For example the `E::N` in `enum E { N(u8) }`. +/// - **seq** +/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` +/// or `HashSet<T>`. When serializing, the length may or may not be known +/// before iterating through all the data. When deserializing, the length +/// is determined by looking at the serialized data. +/// - **tuple** +/// - A statically sized heterogeneous sequence of values for which the +/// length will be known at deserialization time without looking at the +/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or +/// `[u64; 10]`. +/// - **tuple_struct** +/// - A named tuple, for example `struct Rgb(u8, u8, u8)`. +/// - **tuple_variant** +/// - For example the `E::T` in `enum E { T(u8, u8) }`. +/// - **map** +/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`. +/// - **struct** +/// - A heterogeneous key-value pairing in which the keys are strings and +/// will be known at deserialization time without looking at the serialized +/// data, for example `struct S { r: u8, g: u8, b: u8 }`. +/// - **struct_variant** +/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. +/// +/// The `Deserializer` trait supports two entry point styles which enables +/// different kinds of deserialization. +/// +/// 1. The `deserialize` method. Self-describing data formats like JSON are able +/// to look at the serialized data and tell what it represents. For example +/// the JSON deserializer may see an opening curly brace (`{`) and know that +/// it is seeing a map. If the data format supports +/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever +/// type it sees in the input. JSON uses this approach when deserializing +/// `serde_json::Value` which is an enum that can represent any JSON +/// document. Without knowing what is in a JSON document, we can deserialize +/// it to `serde_json::Value` by going through +/// `Deserializer::deserialize_any`. +/// +/// 2. The various `deserialize_*` methods. Non-self-describing formats like +/// Bincode need to be told what is in the input in order to deserialize it. +/// The `deserialize_*` methods are hints to the deserializer for how to +/// interpret the next piece of input. Non-self-describing formats are not +/// able to deserialize something like `serde_json::Value` which relies on +/// `Deserializer::deserialize_any`. +/// +/// When implementing `Deserialize`, you should avoid relying on +/// `Deserializer::deserialize_any` unless you need to be told by the +/// Deserializer what type is in the input. Know that relying on +/// `Deserializer::deserialize_any` means your data type will be able to +/// deserialize from self-describing formats only, ruling out Bincode and many +/// others. +/// +/// [Serde data model]: https://serde.rs/data-model.html +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed from the input when deserializing. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website contains example code for +/// a basic JSON `Deserializer`. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait Deserializer<'de>: Sized { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + + /// Require the `Deserializer` to figure out how to drive the visitor based + /// on what data type is in the input. + /// + /// When implementing `Deserialize`, you should avoid relying on + /// `Deserializer::deserialize_any` unless you need to be told by the + /// Deserializer what type is in the input. Know that relying on + /// `Deserializer::deserialize_any` means your data type will be able to + /// deserialize from self-describing formats only, ruling out Bincode and + /// many others. + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `bool` value. + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i8` value. + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i16` value. + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i32` value. + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i64` value. + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + serde_if_integer128! { + /// Hint that the `Deserialize` type is expecting an `i128` value. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de> + { + let _ = visitor; + Err(Error::custom("i128 is not supported")) + } + } + + /// Hint that the `Deserialize` type is expecting a `u8` value. + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u16` value. + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u32` value. + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u64` value. + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + serde_if_integer128! { + /// Hint that the `Deserialize` type is expecting an `u128` value. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de> + { + let _ = visitor; + Err(Error::custom("u128 is not supported")) + } + } + + /// Hint that the `Deserialize` type is expecting a `f32` value. + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `f64` value. + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `char` value. + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a string value and does + /// not benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would benefit from taking ownership of `String` data, + /// indiciate this to the `Deserializer` by using `deserialize_string` + /// instead. + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a string value and would + /// benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would not benefit from taking ownership of `String` + /// data, indicate that to the `Deserializer` by using `deserialize_str` + /// instead. + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a byte array and does not + /// benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would benefit from taking ownership of `Vec<u8>` data, + /// indicate this to the `Deserializer` by using `deserialize_byte_buf` + /// instead. + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a byte array and would + /// benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would not benefit from taking ownership of `Vec<u8>` + /// data, indicate that to the `Deserializer` by using `deserialize_bytes` + /// instead. + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an optional value. + /// + /// This allows deserializers that encode an optional value as a nullable + /// value to convert the null value into `None` and a regular value into + /// `Some(value)`. + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a unit value. + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a unit struct with a + /// particular name. + fn deserialize_unit_struct<V>( + self, + name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a newtype struct with a + /// particular name. + fn deserialize_newtype_struct<V>( + self, + name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a sequence of values. + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a sequence of values and + /// knows how many values there are without looking at the serialized data. + fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a tuple struct with a + /// particular name and number of fields. + fn deserialize_tuple_struct<V>( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a map of key-value pairs. + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a struct with a particular + /// name and fields. + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an enum value with a + /// particular name and possible variants. + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting the name of a struct + /// field or the discriminant of an enum variant. + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type needs to deserialize a value whose type + /// doesn't matter because it is ignored. + /// + /// Deserializers for non-self-describing formats may not support this mode. + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Determine whether `Deserialize` implementations should expect to + /// deserialize their human-readable form. + /// + /// Some types have a human-readable form that may be somewhat expensive to + /// construct, as well as a binary form that is compact and efficient. + /// Generally text-based formats like JSON and YAML will prefer to use the + /// human-readable one and binary formats like Bincode will prefer the + /// compact one. + /// + /// ```edition2018 + /// # use std::ops::Add; + /// # use std::str::FromStr; + /// # + /// # struct Timestamp; + /// # + /// # impl Timestamp { + /// # const EPOCH: Timestamp = Timestamp; + /// # } + /// # + /// # impl FromStr for Timestamp { + /// # type Err = String; + /// # fn from_str(_: &str) -> Result<Self, Self::Err> { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # struct Duration; + /// # + /// # impl Duration { + /// # fn seconds(_: u64) -> Self { unimplemented!() } + /// # } + /// # + /// # impl Add<Duration> for Timestamp { + /// # type Output = Timestamp; + /// # fn add(self, _: Duration) -> Self::Output { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::de::{self, Deserialize, Deserializer}; + /// + /// impl<'de> Deserialize<'de> for Timestamp { + /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + /// where + /// D: Deserializer<'de>, + /// { + /// if deserializer.is_human_readable() { + /// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z". + /// let s = String::deserialize(deserializer)?; + /// Timestamp::from_str(&s).map_err(de::Error::custom) + /// } else { + /// // Deserialize from a compact binary representation, seconds since + /// // the Unix epoch. + /// let n = u64::deserialize(deserializer)?; + /// Ok(Timestamp::EPOCH + Duration::seconds(n)) + /// } + /// } + /// } + /// ``` + /// + /// The default implementation of this method returns `true`. Data formats + /// may override this to `false` to request a compact form for types that + /// support one. Note that modifying this method to change a format from + /// human-readable to compact or vice versa should be regarded as a breaking + /// change, as a value serialized in human-readable mode is not required to + /// deserialize from the same data in compact mode. + #[inline] + fn is_human_readable(&self) -> bool { + true + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// This trait represents a visitor that walks through a deserializer. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the requirement for lifetime of data +/// that may be borrowed by `Self::Value`. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example +/// +/// ```edition2018 +/// # use std::fmt; +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # +/// /// A visitor that deserializes a long string - a string containing at least +/// /// some minimum number of bytes. +/// struct LongString { +/// min: usize, +/// } +/// +/// impl<'de> Visitor<'de> for LongString { +/// type Value = String; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "a string containing at least {} bytes", self.min) +/// } +/// +/// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> +/// where +/// E: de::Error, +/// { +/// if s.len() >= self.min { +/// Ok(s.to_owned()) +/// } else { +/// Err(de::Error::invalid_value(Unexpected::Str(s), &self)) +/// } +/// } +/// } +/// ``` +pub trait Visitor<'de>: Sized { + /// The value produced by this visitor. + type Value; + + /// Format a message stating what data this Visitor expects to receive. + /// + /// This is used in error messages. The message should complete the sentence + /// "This Visitor expects to receive ...", for example the message could be + /// "an integer between 0 and 64". The message should not be capitalized and + /// should not end with a period. + /// + /// ```edition2018 + /// # use std::fmt; + /// # + /// # struct S { + /// # max: usize, + /// # } + /// # + /// # impl<'de> serde::de::Visitor<'de> for S { + /// # type Value = (); + /// # + /// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// write!(formatter, "an integer between 0 and {}", self.max) + /// } + /// # } + /// ``` + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result; + + /// The input contains a boolean. + /// + /// The default implementation fails with a type error. + fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Bool(v), &self)) + } + + /// The input contains an `i8`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 + fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_i64(v as i64) + } + + /// The input contains an `i16`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 + fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_i64(v as i64) + } + + /// The input contains an `i32`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 + fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_i64(v as i64) + } + + /// The input contains an `i64`. + /// + /// The default implementation fails with a type error. + fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Signed(v), &self)) + } + + serde_if_integer128! { + /// The input contains a `i128`. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default implementation fails with a type error. + fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E> + where + E: Error, + { + let _ = v; + Err(Error::invalid_type(Unexpected::Other("i128"), &self)) + } + } + + /// The input contains a `u8`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 + fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_u64(v as u64) + } + + /// The input contains a `u16`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 + fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_u64(v as u64) + } + + /// The input contains a `u32`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 + fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_u64(v as u64) + } + + /// The input contains a `u64`. + /// + /// The default implementation fails with a type error. + fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Unsigned(v), &self)) + } + + serde_if_integer128! { + /// The input contains a `u128`. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default implementation fails with a type error. + fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> + where + E: Error, + { + let _ = v; + Err(Error::invalid_type(Unexpected::Other("u128"), &self)) + } + } + + /// The input contains an `f32`. + /// + /// The default implementation forwards to [`visit_f64`]. + /// + /// [`visit_f64`]: #method.visit_f64 + fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_f64(v as f64) + } + + /// The input contains an `f64`. + /// + /// The default implementation fails with a type error. + fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Float(v), &self)) + } + + /// The input contains a `char`. + /// + /// The default implementation forwards to [`visit_str`] as a one-character + /// string. + /// + /// [`visit_str`]: #method.visit_str + #[inline] + fn visit_char<E>(self, v: char) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_str(utf8::encode(v).as_str()) + } + + /// The input contains a string. The lifetime of the string is ephemeral and + /// it may be destroyed after this method returns. + /// + /// This method allows the `Deserializer` to avoid a copy by retaining + /// ownership of any buffered data. `Deserialize` implementations that do + /// not benefit from taking ownership of `String` data should indicate that + /// to the deserializer by using `Deserializer::deserialize_str` rather than + /// `Deserializer::deserialize_string`. + /// + /// It is never correct to implement `visit_string` without implementing + /// `visit_str`. Implement neither, both, or just `visit_str`. + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Str(v), &self)) + } + + /// The input contains a string that lives at least as long as the + /// `Deserializer`. + /// + /// This enables zero-copy deserialization of strings in some formats. For + /// example JSON input containing the JSON string `"borrowed"` can be + /// deserialized with zero copying into a `&'a str` as long as the input + /// data outlives `'a`. + /// + /// The default implementation forwards to `visit_str`. + #[inline] + fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_str(v) + } + + /// The input contains a string and ownership of the string is being given + /// to the `Visitor`. + /// + /// This method allows the `Visitor` to avoid a copy by taking ownership of + /// a string created by the `Deserializer`. `Deserialize` implementations + /// that benefit from taking ownership of `String` data should indicate that + /// to the deserializer by using `Deserializer::deserialize_string` rather + /// than `Deserializer::deserialize_str`, although not every deserializer + /// will honor such a request. + /// + /// It is never correct to implement `visit_string` without implementing + /// `visit_str`. Implement neither, both, or just `visit_str`. + /// + /// The default implementation forwards to `visit_str` and then drops the + /// `String`. + #[inline] + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_str(&v) + } + + /// The input contains a byte array. The lifetime of the byte array is + /// ephemeral and it may be destroyed after this method returns. + /// + /// This method allows the `Deserializer` to avoid a copy by retaining + /// ownership of any buffered data. `Deserialize` implementations that do + /// not benefit from taking ownership of `Vec<u8>` data should indicate that + /// to the deserializer by using `Deserializer::deserialize_bytes` rather + /// than `Deserializer::deserialize_byte_buf`. + /// + /// It is never correct to implement `visit_byte_buf` without implementing + /// `visit_bytes`. Implement neither, both, or just `visit_bytes`. + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + let _ = v; + Err(Error::invalid_type(Unexpected::Bytes(v), &self)) + } + + /// The input contains a byte array that lives at least as long as the + /// `Deserializer`. + /// + /// This enables zero-copy deserialization of bytes in some formats. For + /// example Bincode data containing bytes can be deserialized with zero + /// copying into a `&'a [u8]` as long as the input data outlives `'a`. + /// + /// The default implementation forwards to `visit_bytes`. + #[inline] + fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_bytes(v) + } + + /// The input contains a byte array and ownership of the byte array is being + /// given to the `Visitor`. + /// + /// This method allows the `Visitor` to avoid a copy by taking ownership of + /// a byte buffer created by the `Deserializer`. `Deserialize` + /// implementations that benefit from taking ownership of `Vec<u8>` data + /// should indicate that to the deserializer by using + /// `Deserializer::deserialize_byte_buf` rather than + /// `Deserializer::deserialize_bytes`, although not every deserializer will + /// honor such a request. + /// + /// It is never correct to implement `visit_byte_buf` without implementing + /// `visit_bytes`. Implement neither, both, or just `visit_bytes`. + /// + /// The default implementation forwards to `visit_bytes` and then drops the + /// `Vec<u8>`. + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_bytes(&v) + } + + /// The input contains an optional that is absent. + /// + /// The default implementation fails with a type error. + fn visit_none<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Option, &self)) + } + + /// The input contains an optional that is present. + /// + /// The default implementation fails with a type error. + fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + let _ = deserializer; + Err(Error::invalid_type(Unexpected::Option, &self)) + } + + /// The input contains a unit `()`. + /// + /// The default implementation fails with a type error. + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Unit, &self)) + } + + /// The input contains a newtype struct. + /// + /// The content of the newtype struct may be read from the given + /// `Deserializer`. + /// + /// The default implementation fails with a type error. + fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + let _ = deserializer; + Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) + } + + /// The input contains a sequence of elements. + /// + /// The default implementation fails with a type error. + fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let _ = seq; + Err(Error::invalid_type(Unexpected::Seq, &self)) + } + + /// The input contains a key-value map. + /// + /// The default implementation fails with a type error. + fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let _ = map; + Err(Error::invalid_type(Unexpected::Map, &self)) + } + + /// The input contains an enum. + /// + /// The default implementation fails with a type error. + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: EnumAccess<'de>, + { + let _ = data; + Err(Error::invalid_type(Unexpected::Enum, &self)) + } + + // Used when deserializing a flattened Option field. Not public API. + #[doc(hidden)] + fn __private_visit_untagged_option<D>(self, _: D) -> Result<Self::Value, ()> + where + D: Deserializer<'de>, + { + Err(()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Provides a `Visitor` access to each element of a sequence in the input. +/// +/// This is a trait that a `Deserializer` passes to a `Visitor` implementation, +/// which deserializes each item in a sequence. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by deserialized sequence elements. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SeqAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SeqAccess<'de> { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + + /// This returns `Ok(Some(value))` for the next value in the sequence, or + /// `Ok(None)` if there are no more remaining items. + /// + /// `Deserialize` implementations should typically use + /// `SeqAccess::next_element` instead. + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: DeserializeSeed<'de>; + + /// This returns `Ok(Some(value))` for the next value in the sequence, or + /// `Ok(None)` if there are no more remaining items. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `SeqAccess` implementations should not override the default behavior. + #[inline] + fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error> + where + T: Deserialize<'de>, + { + self.next_element_seed(PhantomData) + } + + /// Returns the number of elements remaining in the sequence, if known. + #[inline] + fn size_hint(&self) -> Option<usize> { + None + } +} + +impl<'de, 'a, A> SeqAccess<'de> for &'a mut A +where + A: SeqAccess<'de>, +{ + type Error = A::Error; + + #[inline] + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: DeserializeSeed<'de>, + { + (**self).next_element_seed(seed) + } + + #[inline] + fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error> + where + T: Deserialize<'de>, + { + (**self).next_element() + } + + #[inline] + fn size_hint(&self) -> Option<usize> { + (**self).size_hint() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Provides a `Visitor` access to each entry of a map in the input. +/// +/// This is a trait that a `Deserializer` passes to a `Visitor` implementation. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by deserialized map entries. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `MapAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait MapAccess<'de> { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + + /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)` + /// if there are no more remaining entries. + /// + /// `Deserialize` implementations should typically use + /// `MapAccess::next_key` or `MapAccess::next_entry` instead. + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: DeserializeSeed<'de>; + + /// This returns a `Ok(value)` for the next value in the map. + /// + /// `Deserialize` implementations should typically use + /// `MapAccess::next_value` instead. + /// + /// # Panics + /// + /// Calling `next_value_seed` before `next_key_seed` is incorrect and is + /// allowed to panic or return bogus results. + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + where + V: DeserializeSeed<'de>; + + /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in + /// the map, or `Ok(None)` if there are no more remaining items. + /// + /// `MapAccess` implementations should override the default behavior if a + /// more efficient implementation is possible. + /// + /// `Deserialize` implementations should typically use + /// `MapAccess::next_entry` instead. + #[inline] + fn next_entry_seed<K, V>( + &mut self, + kseed: K, + vseed: V, + ) -> Result<Option<(K::Value, V::Value)>, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, + { + match try!(self.next_key_seed(kseed)) { + Some(key) => { + let value = try!(self.next_value_seed(vseed)); + Ok(Some((key, value))) + } + None => Ok(None), + } + } + + /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)` + /// if there are no more remaining entries. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `MapAccess` implementations should not override the default behavior. + #[inline] + fn next_key<K>(&mut self) -> Result<Option<K>, Self::Error> + where + K: Deserialize<'de>, + { + self.next_key_seed(PhantomData) + } + + /// This returns a `Ok(value)` for the next value in the map. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `MapAccess` implementations should not override the default behavior. + /// + /// # Panics + /// + /// Calling `next_value` before `next_key` is incorrect and is allowed to + /// panic or return bogus results. + #[inline] + fn next_value<V>(&mut self) -> Result<V, Self::Error> + where + V: Deserialize<'de>, + { + self.next_value_seed(PhantomData) + } + + /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in + /// the map, or `Ok(None)` if there are no more remaining items. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `MapAccess` implementations should not override the default behavior. + #[inline] + fn next_entry<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error> + where + K: Deserialize<'de>, + V: Deserialize<'de>, + { + self.next_entry_seed(PhantomData, PhantomData) + } + + /// Returns the number of entries remaining in the map, if known. + #[inline] + fn size_hint(&self) -> Option<usize> { + None + } +} + +impl<'de, 'a, A> MapAccess<'de> for &'a mut A +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + #[inline] + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: DeserializeSeed<'de>, + { + (**self).next_key_seed(seed) + } + + #[inline] + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + where + V: DeserializeSeed<'de>, + { + (**self).next_value_seed(seed) + } + + #[inline] + fn next_entry_seed<K, V>( + &mut self, + kseed: K, + vseed: V, + ) -> Result<Option<(K::Value, V::Value)>, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, + { + (**self).next_entry_seed(kseed, vseed) + } + + #[inline] + fn next_entry<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error> + where + K: Deserialize<'de>, + V: Deserialize<'de>, + { + (**self).next_entry() + } + + #[inline] + fn next_key<K>(&mut self) -> Result<Option<K>, Self::Error> + where + K: Deserialize<'de>, + { + (**self).next_key() + } + + #[inline] + fn next_value<V>(&mut self) -> Result<V, Self::Error> + where + V: Deserialize<'de>, + { + (**self).next_value() + } + + #[inline] + fn size_hint(&self) -> Option<usize> { + (**self).size_hint() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Provides a `Visitor` access to the data of an enum in the input. +/// +/// `EnumAccess` is created by the `Deserializer` and passed to the +/// `Visitor` in order to identify which variant of an enum to deserialize. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by the deserialized enum variant. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `EnumAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait EnumAccess<'de>: Sized { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + /// The `Visitor` that will be used to deserialize the content of the enum + /// variant. + type Variant: VariantAccess<'de, Error = Self::Error>; + + /// `variant` is called to identify which variant to deserialize. + /// + /// `Deserialize` implementations should typically use `EnumAccess::variant` + /// instead. + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: DeserializeSeed<'de>; + + /// `variant` is called to identify which variant to deserialize. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `EnumAccess` implementations should not override the default behavior. + #[inline] + fn variant<V>(self) -> Result<(V, Self::Variant), Self::Error> + where + V: Deserialize<'de>, + { + self.variant_seed(PhantomData) + } +} + +/// `VariantAccess` is a visitor that is created by the `Deserializer` and +/// passed to the `Deserialize` to deserialize the content of a particular enum +/// variant. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by the deserialized enum variant. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `VariantAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait VariantAccess<'de>: Sized { + /// The error type that can be returned if some error occurs during + /// deserialization. Must match the error type of our `EnumAccess`. + type Error: Error; + + /// Called when deserializing a variant with no values. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2018 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// fn unit_variant(self) -> Result<(), Self::Error> { + /// // What the data actually contained; suppose it is a tuple variant. + /// let unexp = Unexpected::TupleVariant; + /// Err(de::Error::invalid_type(unexp, &"unit variant")) + /// } + /// # + /// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error> + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error> + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error> + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` + fn unit_variant(self) -> Result<(), Self::Error>; + + /// Called when deserializing a variant with a single value. + /// + /// `Deserialize` implementations should typically use + /// `VariantAccess::newtype_variant` instead. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2018 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> + /// where + /// T: DeserializeSeed<'de>, + /// { + /// // What the data actually contained; suppose it is a unit variant. + /// let unexp = Unexpected::UnitVariant; + /// Err(de::Error::invalid_type(unexp, &"newtype variant")) + /// } + /// # + /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error> + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error> + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> + where + T: DeserializeSeed<'de>; + + /// Called when deserializing a variant with a single value. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `VariantAccess` implementations should not override the default + /// behavior. + #[inline] + fn newtype_variant<T>(self) -> Result<T, Self::Error> + where + T: Deserialize<'de>, + { + self.newtype_variant_seed(PhantomData) + } + + /// Called when deserializing a tuple-like variant. + /// + /// The `len` is the number of fields expected in the tuple variant. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2018 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error> + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// fn tuple_variant<V>( + /// self, + /// _len: usize, + /// _visitor: V, + /// ) -> Result<V::Value, Self::Error> + /// where + /// V: Visitor<'de>, + /// { + /// // What the data actually contained; suppose it is a unit variant. + /// let unexp = Unexpected::UnitVariant; + /// Err(de::Error::invalid_type(unexp, &"tuple variant")) + /// } + /// # + /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error> + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` + fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; + + /// Called when deserializing a struct-like variant. + /// + /// The `fields` are the names of the fields of the struct variant. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2018 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error> + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error> + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// fn struct_variant<V>( + /// self, + /// _fields: &'static [&'static str], + /// _visitor: V, + /// ) -> Result<V::Value, Self::Error> + /// where + /// V: Visitor<'de>, + /// { + /// // What the data actually contained; suppose it is a unit variant. + /// let unexp = Unexpected::UnitVariant; + /// Err(de::Error::invalid_type(unexp, &"struct variant")) + /// } + /// # } + /// ``` + fn struct_variant<V>( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Converts an existing value into a `Deserializer` from which other values can +/// be deserialized. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed from the resulting `Deserializer`. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example +/// +/// ```edition2018 +/// use std::str::FromStr; +/// use serde::Deserialize; +/// use serde::de::{value, IntoDeserializer}; +/// +/// #[derive(Deserialize)] +/// enum Setting { +/// On, +/// Off, +/// } +/// +/// impl FromStr for Setting { +/// type Err = value::Error; +/// +/// fn from_str(s: &str) -> Result<Self, Self::Err> { +/// Self::deserialize(s.into_deserializer()) +/// } +/// } +/// ``` +pub trait IntoDeserializer<'de, E: Error = value::Error> { + /// The type of the deserializer being converted into. + type Deserializer: Deserializer<'de, Error = E>; + + /// Convert this value into a deserializer. + fn into_deserializer(self) -> Self::Deserializer; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Used in error messages. +/// +/// - expected `a` +/// - expected `a` or `b` +/// - expected one of `a`, `b`, `c` +/// +/// The slice of names must not be empty. +struct OneOf { + names: &'static [&'static str], +} + +impl Display for OneOf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.names.len() { + 0 => panic!(), // special case elsewhere + 1 => write!(formatter, "`{}`", self.names[0]), + 2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]), + _ => { + try!(write!(formatter, "one of ")); + for (i, alt) in self.names.iter().enumerate() { + if i > 0 { + try!(write!(formatter, ", ")); + } + try!(write!(formatter, "`{}`", alt)); + } + Ok(()) + } + } + } +} diff --git a/third_party/rust/serde/src/de/utf8.rs b/third_party/rust/serde/src/de/utf8.rs new file mode 100644 index 0000000000..576fd03cfa --- /dev/null +++ b/third_party/rust/serde/src/de/utf8.rs @@ -0,0 +1,46 @@ +use lib::*; + +const TAG_CONT: u8 = 0b1000_0000; +const TAG_TWO_B: u8 = 0b1100_0000; +const TAG_THREE_B: u8 = 0b1110_0000; +const TAG_FOUR_B: u8 = 0b1111_0000; +const MAX_ONE_B: u32 = 0x80; +const MAX_TWO_B: u32 = 0x800; +const MAX_THREE_B: u32 = 0x10000; + +#[inline] +pub fn encode(c: char) -> Encode { + let code = c as u32; + let mut buf = [0; 4]; + let pos = if code < MAX_ONE_B { + buf[3] = code as u8; + 3 + } else if code < MAX_TWO_B { + buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 2 + } else if code < MAX_THREE_B { + buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 1 + } else { + buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; + buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 0 + }; + Encode { buf: buf, pos: pos } +} + +pub struct Encode { + buf: [u8; 4], + pos: usize, +} + +impl Encode { + pub fn as_str(&self) -> &str { + str::from_utf8(&self.buf[self.pos..]).unwrap() + } +} diff --git a/third_party/rust/serde/src/de/value.rs b/third_party/rust/serde/src/de/value.rs new file mode 100644 index 0000000000..d0a185da2e --- /dev/null +++ b/third_party/rust/serde/src/de/value.rs @@ -0,0 +1,1497 @@ +//! Building blocks for deserializing basic values using the `IntoDeserializer` +//! trait. +//! +//! ```edition2018 +//! use std::str::FromStr; +//! use serde::Deserialize; +//! use serde::de::{value, IntoDeserializer}; +//! +//! #[derive(Deserialize)] +//! enum Setting { +//! On, +//! Off, +//! } +//! +//! impl FromStr for Setting { +//! type Err = value::Error; +//! +//! fn from_str(s: &str) -> Result<Self, Self::Err> { +//! Self::deserialize(s.into_deserializer()) +//! } +//! } +//! ``` + +use lib::*; + +use self::private::{First, Second}; +use de::{self, Expected, IntoDeserializer, SeqAccess}; +use private::de::size_hint; +use ser; + +//////////////////////////////////////////////////////////////////////////////// + +// For structs that contain a PhantomData. We do not want the trait +// bound `E: Clone` inferred by derive(Clone). +macro_rules! impl_copy_clone { + ($ty:ident $(<$lifetime:tt>)*) => { + impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {} + + impl<$($lifetime,)* E> Clone for $ty<$($lifetime,)* E> { + fn clone(&self) -> Self { + *self + } + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A minimal representation of all possible errors that can occur using the +/// `IntoDeserializer` trait. +#[derive(Clone, Debug, PartialEq)] +pub struct Error { + err: ErrorImpl, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +type ErrorImpl = Box<str>; +#[cfg(not(any(feature = "std", feature = "alloc")))] +type ErrorImpl = (); + +impl de::Error for Error { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cold] + fn custom<T>(msg: T) -> Self + where + T: Display, + { + Error { + err: msg.to_string().into_boxed_str(), + } + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + #[cold] + fn custom<T>(msg: T) -> Self + where + T: Display, + { + let _ = msg; + Error { err: () } + } +} + +impl ser::Error for Error { + #[cold] + fn custom<T>(msg: T) -> Self + where + T: Display, + { + de::Error::custom(msg) + } +} + +impl Display for Error { + #[cfg(any(feature = "std", feature = "alloc"))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + formatter.write_str(&self.err) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + formatter.write_str("Serde deserialization error") + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + fn description(&self) -> &str { + &self.err + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, E> IntoDeserializer<'de, E> for () +where + E: de::Error, +{ + type Deserializer = UnitDeserializer<E>; + + fn into_deserializer(self) -> UnitDeserializer<E> { + UnitDeserializer { + marker: PhantomData, + } + } +} + +/// A deserializer holding a `()`. +#[derive(Debug)] +pub struct UnitDeserializer<E> { + marker: PhantomData<E>, +} + +impl_copy_clone!(UnitDeserializer); + +impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E> +where + E: de::Error, +{ + type Error = E; + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_none() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer that cannot be instantiated. +#[cfg(feature = "unstable")] +pub struct NeverDeserializer<E> { + never: !, + marker: PhantomData<E>, +} + +#[cfg(feature = "unstable")] +impl<'de, E> IntoDeserializer<'de, E> for ! +where + E: de::Error, +{ + type Deserializer = NeverDeserializer<E>; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +#[cfg(feature = "unstable")] +impl<'de, E> de::Deserializer<'de> for NeverDeserializer<E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.never + } + + 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! primitive_deserializer { + ($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => { + #[doc = "A deserializer holding"] + #[doc = $doc] + #[derive(Debug)] + pub struct $name<E> { + value: $ty, + marker: PhantomData<E> + } + + impl_copy_clone!($name); + + impl<'de, E> IntoDeserializer<'de, E> for $ty + where + E: de::Error, + { + type Deserializer = $name<E>; + + fn into_deserializer(self) -> $name<E> { + $name { + value: self, + marker: PhantomData, + } + } + } + + impl<'de, E> de::Deserializer<'de> for $name<E> + where + E: de::Error, + { + type Error = E; + + 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 + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.$method(self.value $($cast)*) + } + } + } +} + +primitive_deserializer!(bool, "a `bool`.", BoolDeserializer, visit_bool); +primitive_deserializer!(i8, "an `i8`.", I8Deserializer, visit_i8); +primitive_deserializer!(i16, "an `i16`.", I16Deserializer, visit_i16); +primitive_deserializer!(i32, "an `i32`.", I32Deserializer, visit_i32); +primitive_deserializer!(i64, "an `i64`.", I64Deserializer, visit_i64); +primitive_deserializer!(isize, "an `isize`.", IsizeDeserializer, visit_i64 as i64); +primitive_deserializer!(u8, "a `u8`.", U8Deserializer, visit_u8); +primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16); +primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64); +primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64); +primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32); +primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64); +primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char); + +serde_if_integer128! { + primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128); + primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128); +} + +/// A deserializer holding a `u32`. +#[derive(Debug)] +pub struct U32Deserializer<E> { + value: u32, + marker: PhantomData<E>, +} + +impl_copy_clone!(U32Deserializer); + +impl<'de, E> IntoDeserializer<'de, E> for u32 +where + E: de::Error, +{ + type Deserializer = U32Deserializer<E>; + + fn into_deserializer(self) -> U32Deserializer<E> { + U32Deserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, E> de::Deserializer<'de> for U32Deserializer<E> +where + E: de::Error, +{ + type Error = E; + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_u32(self.value) + } + + fn deserialize_enum<V>( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } +} + +impl<'de, E> de::EnumAccess<'de> for U32Deserializer<E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly<E>; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `&str`. +#[derive(Debug)] +pub struct StrDeserializer<'a, E> { + value: &'a str, + marker: PhantomData<E>, +} + +impl_copy_clone!(StrDeserializer<'de>); + +impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str +where + E: de::Error, +{ + type Deserializer = StrDeserializer<'a, E>; + + fn into_deserializer(self) -> StrDeserializer<'a, E> { + StrDeserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_str(self.value) + } + + fn deserialize_enum<V>( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly<E>; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `&str` with a lifetime tied to another +/// deserializer. +#[derive(Debug)] +pub struct BorrowedStrDeserializer<'de, E> { + value: &'de str, + marker: PhantomData<E>, +} + +impl_copy_clone!(BorrowedStrDeserializer<'de>); + +impl<'de, E> BorrowedStrDeserializer<'de, E> { + /// Create a new borrowed deserializer from the given string. + pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> { + BorrowedStrDeserializer { + value: value, + marker: PhantomData, + } + } +} + +impl<'de, E> de::Deserializer<'de> for BorrowedStrDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(self.value) + } + + fn deserialize_enum<V>( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, E> de::EnumAccess<'de> for BorrowedStrDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly<E>; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `String`. +#[cfg(any(feature = "std", feature = "alloc"))] +#[derive(Debug)] +pub struct StringDeserializer<E> { + value: String, + marker: PhantomData<E>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<E> Clone for StringDeserializer<E> { + fn clone(&self) -> Self { + StringDeserializer { + value: self.value.clone(), + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, E> IntoDeserializer<'de, E> for String +where + E: de::Error, +{ + type Deserializer = StringDeserializer<E>; + + fn into_deserializer(self) -> StringDeserializer<E> { + StringDeserializer { + value: self, + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, E> de::Deserializer<'de> for StringDeserializer<E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_string(self.value) + } + + fn deserialize_enum<V>( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly<E>; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `Cow<str>`. +#[cfg(any(feature = "std", feature = "alloc"))] +#[derive(Debug)] +pub struct CowStrDeserializer<'a, E> { + value: Cow<'a, str>, + marker: PhantomData<E>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, E> Clone for CowStrDeserializer<'a, E> { + fn clone(&self) -> Self { + CowStrDeserializer { + value: self.value.clone(), + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> +where + E: de::Error, +{ + type Deserializer = CowStrDeserializer<'a, E>; + + fn into_deserializer(self) -> CowStrDeserializer<'a, E> { + CowStrDeserializer { + value: self, + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.value { + Cow::Borrowed(string) => visitor.visit_str(string), + Cow::Owned(string) => visitor.visit_string(string), + } + } + + fn deserialize_enum<V>( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly<E>; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `&[u8]` with a lifetime tied to another +/// deserializer. +#[derive(Debug)] +pub struct BorrowedBytesDeserializer<'de, E> { + value: &'de [u8], + marker: PhantomData<E>, +} + +impl_copy_clone!(BorrowedBytesDeserializer<'de>); + +impl<'de, E> BorrowedBytesDeserializer<'de, E> { + /// Create a new borrowed deserializer from the given byte slice. + pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> { + BorrowedBytesDeserializer { + value: value, + marker: PhantomData, + } + } +} + +impl<'de, E> de::Deserializer<'de> for BorrowedBytesDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_bytes(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any enum + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer that iterates over a sequence. +#[derive(Clone, Debug)] +pub struct SeqDeserializer<I, E> { + iter: iter::Fuse<I>, + count: usize, + marker: PhantomData<E>, +} + +impl<I, E> SeqDeserializer<I, E> +where + I: Iterator, +{ + /// Construct a new `SeqDeserializer<I, E>`. + pub fn new(iter: I) -> Self { + SeqDeserializer { + iter: iter.fuse(), + count: 0, + marker: PhantomData, + } + } +} + +impl<I, E> SeqDeserializer<I, E> +where + I: Iterator, + E: de::Error, +{ + /// Check for remaining elements after passing a `SeqDeserializer` to + /// `Visitor::visit_seq`. + pub fn end(self) -> Result<(), E> { + let remaining = self.iter.count(); + if remaining == 0 { + Ok(()) + } else { + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length( + self.count + remaining, + &ExpectedInSeq(self.count), + )) + } + } +} + +impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer<I, E> +where + I: Iterator<Item = T>, + T: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let v = try!(visitor.visit_seq(&mut self)); + try!(self.end()); + Ok(v) + } + + 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, I, T, E> de::SeqAccess<'de> for SeqDeserializer<I, E> +where + I: Iterator<Item = T>, + T: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_element_seed<V>(&mut self, seed: V) -> Result<Option<V::Value>, Self::Error> + where + V: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => { + self.count += 1; + seed.deserialize(value.into_deserializer()).map(Some) + } + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } +} + +struct ExpectedInSeq(usize); + +impl Expected for ExpectedInSeq { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.0 == 1 { + write!(formatter, "1 element in sequence") + } else { + write!(formatter, "{} elements in sequence", self.0) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T> +where + T: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + SeqDeserializer::new(self.into_iter()) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T> +where + T: IntoDeserializer<'de, E> + Eq + Ord, + E: de::Error, +{ + type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + SeqDeserializer::new(self.into_iter()) + } +} + +#[cfg(feature = "std")] +impl<'de, T, S, E> IntoDeserializer<'de, E> for HashSet<T, S> +where + T: IntoDeserializer<'de, E> + Eq + Hash, + S: BuildHasher, + E: de::Error, +{ + type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + SeqDeserializer::new(self.into_iter()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `SeqAccess`. +#[derive(Clone, Debug)] +pub struct SeqAccessDeserializer<A> { + seq: A, +} + +impl<A> SeqAccessDeserializer<A> { + /// Construct a new `SeqAccessDeserializer<A>`. + pub fn new(seq: A) -> Self { + SeqAccessDeserializer { seq: seq } + } +} + +impl<'de, A> de::Deserializer<'de> for SeqAccessDeserializer<A> +where + A: de::SeqAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_seq(self.seq) + } + + 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 + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer that iterates over a map. +pub struct MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ + iter: iter::Fuse<I>, + value: Option<Second<I::Item>>, + count: usize, + lifetime: PhantomData<&'de ()>, + error: PhantomData<E>, +} + +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ + /// Construct a new `MapDeserializer<I, E>`. + pub fn new(iter: I) -> Self { + MapDeserializer { + iter: iter.fuse(), + value: None, + count: 0, + lifetime: PhantomData, + error: PhantomData, + } + } +} + +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + E: de::Error, +{ + /// Check for remaining elements after passing a `MapDeserializer` to + /// `Visitor::visit_map`. + pub fn end(self) -> Result<(), E> { + let remaining = self.iter.count(); + if remaining == 0 { + Ok(()) + } else { + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length( + self.count + remaining, + &ExpectedInMap(self.count), + )) + } + } +} + +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ + fn next_pair(&mut self) -> Option<(First<I::Item>, Second<I::Item>)> { + match self.iter.next() { + Some(kv) => { + self.count += 1; + Some(private::Pair::split(kv)) + } + None => None, + } + } +} + +impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + First<I::Item>: IntoDeserializer<'de, E>, + Second<I::Item>: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let value = try!(visitor.visit_map(&mut self)); + try!(self.end()); + Ok(value) + } + + fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let value = try!(visitor.visit_seq(&mut self)); + try!(self.end()); + Ok(value) + } + + fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let _ = len; + self.deserialize_seq(visitor) + } + + 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 tuple_struct map + struct enum identifier ignored_any + } +} + +impl<'de, I, E> de::MapAccess<'de> for MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + First<I::Item>: IntoDeserializer<'de, E>, + Second<I::Item>: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.next_pair() { + Some((key, value)) => { + self.value = Some(value); + seed.deserialize(key.into_deserializer()).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + let value = self.value.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let value = value.expect("MapAccess::visit_value called before visit_key"); + seed.deserialize(value.into_deserializer()) + } + + fn next_entry_seed<TK, TV>( + &mut self, + kseed: TK, + vseed: TV, + ) -> Result<Option<(TK::Value, TV::Value)>, Self::Error> + where + TK: de::DeserializeSeed<'de>, + TV: de::DeserializeSeed<'de>, + { + match self.next_pair() { + Some((key, value)) => { + let key = try!(kseed.deserialize(key.into_deserializer())); + let value = try!(vseed.deserialize(value.into_deserializer())); + Ok(Some((key, value))) + } + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } +} + +impl<'de, I, E> de::SeqAccess<'de> for MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + First<I::Item>: IntoDeserializer<'de, E>, + Second<I::Item>: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.next_pair() { + Some((k, v)) => { + let de = PairDeserializer(k, v, PhantomData); + seed.deserialize(de).map(Some) + } + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } +} + +// Cannot #[derive(Clone)] because of the bound `Second<I::Item>: Clone`. +impl<'de, I, E> Clone for MapDeserializer<'de, I, E> +where + I: Iterator + Clone, + I::Item: private::Pair, + Second<I::Item>: Clone, +{ + fn clone(&self) -> Self { + MapDeserializer { + iter: self.iter.clone(), + value: self.value.clone(), + count: self.count, + lifetime: self.lifetime, + error: self.error, + } + } +} + +// Cannot #[derive(Debug)] because of the bound `Second<I::Item>: Debug`. +impl<'de, I, E> Debug for MapDeserializer<'de, I, E> +where + I: Iterator + Debug, + I::Item: private::Pair, + Second<I::Item>: Debug, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("MapDeserializer") + .field("iter", &self.iter) + .field("value", &self.value) + .field("count", &self.count) + .field("lifetime", &self.lifetime) + .field("error", &self.error) + .finish() + } +} + +// Used in the `impl SeqAccess for MapDeserializer` to visit the map as a +// sequence of pairs. +struct PairDeserializer<A, B, E>(A, B, PhantomData<E>); + +impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer<A, B, E> +where + A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + 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 tuple_struct map + struct enum identifier ignored_any + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData); + let pair = try!(visitor.visit_seq(&mut pair_visitor)); + if pair_visitor.1.is_none() { + Ok(pair) + } else { + let remaining = pair_visitor.size_hint().unwrap(); + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining))) + } + } + + fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + if len == 2 { + self.deserialize_seq(visitor) + } else { + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length(2, &ExpectedInSeq(len))) + } + } +} + +struct PairVisitor<A, B, E>(Option<A>, Option<B>, PhantomData<E>); + +impl<'de, A, B, E> de::SeqAccess<'de> for PairVisitor<A, B, E> +where + A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + if let Some(k) = self.0.take() { + seed.deserialize(k.into_deserializer()).map(Some) + } else if let Some(v) = self.1.take() { + seed.deserialize(v.into_deserializer()).map(Some) + } else { + Ok(None) + } + } + + fn size_hint(&self) -> Option<usize> { + if self.0.is_some() { + Some(2) + } else if self.1.is_some() { + Some(1) + } else { + Some(0) + } + } +} + +struct ExpectedInMap(usize); + +impl Expected for ExpectedInMap { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.0 == 1 { + write!(formatter, "1 element in map") + } else { + write!(formatter, "{} elements in map", self.0) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V> +where + K: IntoDeserializer<'de, E> + Eq + Ord, + V: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + MapDeserializer::new(self.into_iter()) + } +} + +#[cfg(feature = "std")] +impl<'de, K, V, S, E> IntoDeserializer<'de, E> for HashMap<K, V, S> +where + K: IntoDeserializer<'de, E> + Eq + Hash, + V: IntoDeserializer<'de, E>, + S: BuildHasher, + E: de::Error, +{ + type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + MapDeserializer::new(self.into_iter()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `MapAccess`. +#[derive(Clone, Debug)] +pub struct MapAccessDeserializer<A> { + map: A, +} + +impl<A> MapAccessDeserializer<A> { + /// Construct a new `MapAccessDeserializer<A>`. + pub fn new(map: A) -> Self { + MapAccessDeserializer { map: map } + } +} + +impl<'de, A> de::Deserializer<'de> for MapAccessDeserializer<A> +where + A: de::MapAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_map(self.map) + } + + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer<A> +where + A: de::MapAccess<'de>, +{ + type Error = A::Error; + type Variant = private::MapAsEnum<A>; + + fn variant_seed<T>(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.map.next_key_seed(seed)? { + Some(key) => Ok((key, private::map_as_enum(self.map))), + None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")), + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +mod private { + use lib::*; + + use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor}; + + #[derive(Clone, Debug)] + pub struct UnitOnly<E> { + marker: PhantomData<E>, + } + + pub fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) { + ( + t, + UnitOnly { + marker: PhantomData, + }, + ) + } + + impl<'de, E> de::VariantAccess<'de> for UnitOnly<E> + where + E: de::Error, + { + type Error = E; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } + } + + #[derive(Clone, Debug)] + pub struct MapAsEnum<A> { + map: A, + } + + pub fn map_as_enum<A>(map: A) -> MapAsEnum<A> { + MapAsEnum { map: map } + } + + impl<'de, A> VariantAccess<'de> for MapAsEnum<A> + where + A: MapAccess<'de>, + { + type Error = A::Error; + + fn unit_variant(mut self) -> Result<(), Self::Error> { + self.map.next_value() + } + + fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: DeserializeSeed<'de>, + { + self.map.next_value_seed(seed) + } + + fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.map.next_value_seed(SeedTupleVariant { + len: len, + visitor: visitor, + }) + } + + fn struct_variant<V>( + mut self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.map + .next_value_seed(SeedStructVariant { visitor: visitor }) + } + } + + struct SeedTupleVariant<V> { + len: usize, + visitor: V, + } + + impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant<V> + where + V: Visitor<'de>, + { + type Value = V::Value; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple(self.len, self.visitor) + } + } + + struct SeedStructVariant<V> { + visitor: V, + } + + impl<'de, V> DeserializeSeed<'de> for SeedStructVariant<V> + where + V: Visitor<'de>, + { + type Value = V::Value; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_map(self.visitor) + } + } + + /// Avoid having to restate the generic types on `MapDeserializer`. The + /// `Iterator::Item` contains enough information to figure out K and V. + pub trait Pair { + type First; + type Second; + fn split(self) -> (Self::First, Self::Second); + } + + impl<A, B> Pair for (A, B) { + type First = A; + type Second = B; + fn split(self) -> (A, B) { + self + } + } + + pub type First<T> = <T as Pair>::First; + pub type Second<T> = <T as Pair>::Second; +} diff --git a/third_party/rust/serde/src/export.rs b/third_party/rust/serde/src/export.rs new file mode 100644 index 0000000000..caa1f4dc22 --- /dev/null +++ b/third_party/rust/serde/src/export.rs @@ -0,0 +1,39 @@ +pub use lib::clone::Clone; +pub use lib::convert::{From, Into}; +pub use lib::default::Default; +pub use lib::fmt::{self, Formatter}; +pub use lib::marker::PhantomData; +pub use lib::option::Option::{self, None, Some}; +pub use lib::result::Result::{self, Err, Ok}; + +pub use self::string::from_utf8_lossy; + +#[cfg(any(feature = "alloc", feature = "std"))] +pub use lib::{ToString, Vec}; + +#[cfg(core_try_from)] +pub use lib::convert::TryFrom; + +mod string { + use lib::*; + + #[cfg(any(feature = "std", feature = "alloc"))] + pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> { + String::from_utf8_lossy(bytes) + } + + // The generated code calls this like: + // + // let value = &_serde::export::from_utf8_lossy(bytes); + // Err(_serde::de::Error::unknown_variant(value, VARIANTS)) + // + // so it is okay for the return type to be different from the std case as long + // as the above works. + #[cfg(not(any(feature = "std", feature = "alloc")))] + pub fn from_utf8_lossy(bytes: &[u8]) -> &str { + // Three unicode replacement characters if it fails. They look like a + // white-on-black question mark. The user will recognize it as invalid + // UTF-8. + str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}") + } +} diff --git a/third_party/rust/serde/src/integer128.rs b/third_party/rust/serde/src/integer128.rs new file mode 100644 index 0000000000..01d6f34a1e --- /dev/null +++ b/third_party/rust/serde/src/integer128.rs @@ -0,0 +1,82 @@ +/// Conditional compilation depending on whether Serde is built with support for +/// 128-bit integers. +/// +/// Data formats that wish to support Rust compiler versions older than 1.26 +/// (or targets that lack 128-bit integers) may place the i128 / u128 methods +/// of their Serializer and Deserializer behind this macro. +/// +/// Data formats that require a minimum Rust compiler version of at least 1.26, +/// or do not target platforms that lack 128-bit integers, do not need to +/// bother with this macro and may assume support for 128-bit integers. +/// +/// ```edition2018 +/// # use serde::private::ser::Error; +/// # +/// # struct MySerializer; +/// # +/// use serde::{serde_if_integer128, Serializer}; +/// +/// impl Serializer for MySerializer { +/// type Ok = (); +/// type Error = Error; +/// +/// fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> { +/// /* ... */ +/// # unimplemented!() +/// } +/// +/// /* ... */ +/// +/// serde_if_integer128! { +/// fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> { +/// /* ... */ +/// # unimplemented!() +/// } +/// +/// fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> { +/// /* ... */ +/// # unimplemented!() +/// } +/// } +/// # +/// # serde::__serialize_unimplemented! { +/// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some +/// # unit unit_struct unit_variant newtype_struct newtype_variant seq +/// # tuple tuple_struct tuple_variant map struct struct_variant +/// # } +/// } +/// ``` +/// +/// When Serde is built with support for 128-bit integers, this macro expands +/// transparently into just the input tokens. +/// +/// ```edition2018 +/// macro_rules! serde_if_integer128 { +/// ($($tt:tt)*) => { +/// $($tt)* +/// }; +/// } +/// ``` +/// +/// When built without support for 128-bit integers, this macro expands to +/// nothing. +/// +/// ```edition2018 +/// macro_rules! serde_if_integer128 { +/// ($($tt:tt)*) => {}; +/// } +/// ``` +#[cfg(integer128)] +#[macro_export] +macro_rules! serde_if_integer128 { + ($($tt:tt)*) => { + $($tt)* + }; +} + +#[cfg(not(integer128))] +#[macro_export] +#[doc(hidden)] +macro_rules! serde_if_integer128 { + ($($tt:tt)*) => {}; +} diff --git a/third_party/rust/serde/src/lib.rs b/third_party/rust/serde/src/lib.rs new file mode 100644 index 0000000000..fe40eb1ca8 --- /dev/null +++ b/third_party/rust/serde/src/lib.rs @@ -0,0 +1,288 @@ +//! # Serde +//! +//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data +//! structures efficiently and generically. +//! +//! The Serde ecosystem consists of data structures that know how to serialize +//! and deserialize themselves along with data formats that know how to +//! serialize and deserialize other things. Serde provides the layer by which +//! these two groups interact with each other, allowing any supported data +//! structure to be serialized and deserialized using any supported data format. +//! +//! See the Serde website [https://serde.rs/] for additional documentation and +//! usage examples. +//! +//! [https://serde.rs/]: https://serde.rs/ +//! +//! ## Design +//! +//! Where many other languages rely on runtime reflection for serializing data, +//! Serde is instead built on Rust's powerful trait system. A data structure +//! that knows how to serialize and deserialize itself is one that implements +//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive +//! attribute to automatically generate implementations at compile time). This +//! avoids any overhead of reflection or runtime type information. In fact in +//! many situations the interaction between data structure and data format can +//! be completely optimized away by the Rust compiler, leaving Serde +//! serialization to perform the same speed as a handwritten serializer for the +//! specific selection of data structure and data format. +//! +//! ## Data formats +//! +//! The following is a partial list of data formats that have been implemented +//! for Serde by the community. +//! +//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs. +//! - [Bincode], a compact binary format +//! used for IPC within the Servo rendering engine. +//! - [CBOR], a Concise Binary Object Representation designed for small message +//! size without the need for version negotiation. +//! - [YAML], a self-proclaimed human-friendly configuration language that ain't +//! markup language. +//! - [MessagePack], an efficient binary format that resembles a compact JSON. +//! - [TOML], a minimal configuration format used by [Cargo]. +//! - [Pickle], a format common in the Python world. +//! - [RON], a Rusty Object Notation. +//! - [BSON], the data storage and network transfer format used by MongoDB. +//! - [Avro], a binary format used within Apache Hadoop, with support for schema +//! definition. +//! - [JSON5], A superset of JSON including some productions from ES5. +//! - [Postcard], a no\_std and embedded-systems friendly compact binary format. +//! - [URL] query strings, in the x-www-form-urlencoded format. +//! - [Envy], a way to deserialize environment variables into Rust structs. +//! *(deserialization only)* +//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into +//! Rust structs. *(deserialization only)* +//! - [S-expressions], the textual representation of code and data used by the +//! Lisp language family. +//! - [D-Bus]'s binary wire format. +//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy serialization format. +//! +//! [JSON]: https://github.com/serde-rs/json +//! [Bincode]: https://github.com/servo/bincode +//! [CBOR]: https://github.com/pyfisch/cbor +//! [YAML]: https://github.com/dtolnay/serde-yaml +//! [MessagePack]: https://github.com/3Hren/msgpack-rust +//! [TOML]: https://github.com/alexcrichton/toml-rs +//! [Pickle]: https://github.com/birkenfeld/serde-pickle +//! [RON]: https://github.com/ron-rs/ron +//! [BSON]: https://github.com/zonyitoo/bson-rs +//! [Avro]: https://github.com/flavray/avro-rs +//! [JSON5]: https://github.com/callum-oakley/json5-rs +//! [Postcard]: https://github.com/jamesmunns/postcard +//! [URL]: https://docs.rs/serde_qs +//! [Envy]: https://github.com/softprops/envy +//! [Envy Store]: https://github.com/softprops/envy-store +//! [Cargo]: http://doc.crates.io/manifest.html +//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html +//! [S-expressions]: https://github.com/rotty/lexpr-rs +//! [D-Bus]: https://docs.rs/zvariant +//! [FlexBuffers]: https://github.com/google/flatbuffers/tree/master/rust/flexbuffers + +//////////////////////////////////////////////////////////////////////////////// + +// Serde types in rustdoc of other crates get linked to here. +#![doc(html_root_url = "https://docs.rs/serde/1.0.116")] +// Support using Serde without the standard library! +#![cfg_attr(not(feature = "std"), no_std)] +// Unstable functionality only if the user asks for it. For tracking and +// discussion of these features please refer to this issue: +// +// https://github.com/serde-rs/serde/issues/812 +#![cfg_attr(feature = "unstable", feature(never_type))] +#![allow(unknown_lints, bare_trait_objects, deprecated)] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] +#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] +// Ignored clippy and clippy_pedantic lints +#![cfg_attr( + feature = "cargo-clippy", + allow( + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 + unnested_or_patterns, + // not available in our oldest supported compiler + checked_conversions, + empty_enum, + redundant_field_names, + redundant_static_lifetimes, + // integer and float ser/de requires these sorts of casts + cast_possible_truncation, + cast_possible_wrap, + cast_sign_loss, + // things are often more readable this way + cast_lossless, + module_name_repetitions, + option_if_let_else, + single_match_else, + type_complexity, + use_self, + zero_prefixed_literal, + // correctly used + enum_glob_use, + wildcard_imports, + // not practical + needless_pass_by_value, + similar_names, + too_many_lines, + // preference + doc_markdown, + unseparated_literal_suffix, + // false positive + needless_doctest_main, + // noisy + missing_errors_doc, + must_use_candidate, + ) +)] +// Rustc lints. +#![forbid(unsafe_code)] +#![deny(missing_docs, unused_imports)] + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "alloc")] +extern crate alloc; + +/// A facade around all the types we need from the `std`, `core`, and `alloc` +/// crates. This avoids elaborate import wrangling having to happen in every +/// module. +mod lib { + mod core { + #[cfg(not(feature = "std"))] + pub use core::*; + #[cfg(feature = "std")] + pub use std::*; + } + + pub use self::core::{cmp, iter, mem, num, slice, str}; + pub use self::core::{f32, f64}; + pub use self::core::{i16, i32, i64, i8, isize}; + pub use self::core::{u16, u32, u64, u8, usize}; + + pub use self::core::cell::{Cell, RefCell}; + pub use self::core::clone::{self, Clone}; + pub use self::core::convert::{self, From, Into}; + pub use self::core::default::{self, Default}; + pub use self::core::fmt::{self, Debug, Display}; + pub use self::core::marker::{self, PhantomData}; + pub use self::core::ops::Range; + pub use self::core::option::{self, Option}; + pub use self::core::result::{self, Result}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::borrow::{Cow, ToOwned}; + #[cfg(feature = "std")] + pub use std::borrow::{Cow, ToOwned}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::string::{String, ToString}; + #[cfg(feature = "std")] + pub use std::string::{String, ToString}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::vec::Vec; + #[cfg(feature = "std")] + pub use std::vec::Vec; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::boxed::Box; + #[cfg(feature = "std")] + pub use std::boxed::Box; + + #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + pub use alloc::rc::{Rc, Weak as RcWeak}; + #[cfg(all(feature = "rc", feature = "std"))] + pub use std::rc::{Rc, Weak as RcWeak}; + + #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + pub use alloc::sync::{Arc, Weak as ArcWeak}; + #[cfg(all(feature = "rc", feature = "std"))] + pub use std::sync::{Arc, Weak as ArcWeak}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; + #[cfg(feature = "std")] + pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; + + #[cfg(feature = "std")] + pub use std::{error, net}; + + #[cfg(feature = "std")] + pub use std::collections::{HashMap, HashSet}; + #[cfg(feature = "std")] + pub use std::ffi::{CStr, CString, OsStr, OsString}; + #[cfg(feature = "std")] + pub use std::hash::{BuildHasher, Hash}; + #[cfg(feature = "std")] + pub use std::io::Write; + #[cfg(feature = "std")] + pub use std::num::Wrapping; + #[cfg(feature = "std")] + pub use std::path::{Path, PathBuf}; + #[cfg(feature = "std")] + pub use std::sync::{Mutex, RwLock}; + #[cfg(feature = "std")] + pub use std::time::{SystemTime, UNIX_EPOCH}; + + #[cfg(all(feature = "std", collections_bound))] + pub use std::collections::Bound; + + #[cfg(core_reverse)] + pub use self::core::cmp::Reverse; + + #[cfg(ops_bound)] + pub use self::core::ops::Bound; + + #[cfg(range_inclusive)] + pub use self::core::ops::RangeInclusive; + + #[cfg(all(feature = "std", std_atomic))] + pub use std::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8, + AtomicUsize, Ordering, + }; + #[cfg(all(feature = "std", std_atomic64))] + pub use std::sync::atomic::{AtomicI64, AtomicU64}; + + #[cfg(any(core_duration, feature = "std"))] + pub use self::core::time::Duration; +} + +//////////////////////////////////////////////////////////////////////////////// + +#[macro_use] +mod macros; + +#[macro_use] +mod integer128; + +pub mod de; +pub mod ser; + +#[doc(inline)] +pub use de::{Deserialize, Deserializer}; +#[doc(inline)] +pub use ser::{Serialize, Serializer}; + +// Generated code uses these to support no_std. Not public API. +#[doc(hidden)] +pub mod export; + +// Helpers used by generated code and doc tests. Not public API. +#[doc(hidden)] +pub mod private; + +#[cfg(not(feature = "std"))] +mod std_error; + +// Re-export #[derive(Serialize, Deserialize)]. +// +// The reason re-exporting is not enabled by default is that disabling it would +// be annoying for crates that provide handwritten impls or data formats. They +// would need to disable default features and then explicitly re-enable std. +#[cfg(feature = "serde_derive")] +#[allow(unused_imports)] +#[macro_use] +extern crate serde_derive; +#[cfg(feature = "serde_derive")] +#[doc(hidden)] +pub use serde_derive::*; diff --git a/third_party/rust/serde/src/macros.rs b/third_party/rust/serde/src/macros.rs new file mode 100644 index 0000000000..57600a5351 --- /dev/null +++ b/third_party/rust/serde/src/macros.rs @@ -0,0 +1,236 @@ +// Super explicit first paragraph because this shows up at the top level and +// trips up people who are just looking for basic Serialize / Deserialize +// documentation. +// +/// Helper macro when implementing the `Deserializer` part of a new data format +/// for Serde. +/// +/// Some [`Deserializer`] implementations for self-describing formats do not +/// care what hint the [`Visitor`] gives them, they just want to blindly call +/// the [`Visitor`] method corresponding to the data they can tell is in the +/// input. This requires repetitive implementations of all the [`Deserializer`] +/// trait methods. +/// +/// ```edition2018 +/// # use serde::forward_to_deserialize_any; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # +/// # struct MyDeserializer; +/// # +/// # impl<'de> Deserializer<'de> for MyDeserializer { +/// # type Error = value::Error; +/// # +/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error> +/// # where +/// # V: Visitor<'de>, +/// # { +/// # unimplemented!() +/// # } +/// # +/// #[inline] +/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> +/// where +/// V: Visitor<'de>, +/// { +/// self.deserialize_any(visitor) +/// } +/// # +/// # forward_to_deserialize_any! { +/// # 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 +/// # } +/// # } +/// ``` +/// +/// The `forward_to_deserialize_any!` macro implements these simple forwarding +/// methods so that they forward directly to [`Deserializer::deserialize_any`]. +/// You can choose which methods to forward. +/// +/// ```edition2018 +/// # use serde::forward_to_deserialize_any; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # +/// # struct MyDeserializer; +/// # +/// impl<'de> Deserializer<'de> for MyDeserializer { +/// # type Error = value::Error; +/// # +/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> +/// where +/// V: Visitor<'de>, +/// { +/// /* ... */ +/// # let _ = visitor; +/// # unimplemented!() +/// } +/// +/// 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 +/// } +/// } +/// ``` +/// +/// The macro assumes the convention that your `Deserializer` lifetime parameter +/// is called `'de` and that the `Visitor` type parameters on each method are +/// called `V`. A different type parameter and a different lifetime can be +/// specified explicitly if necessary. +/// +/// ```edition2018 +/// # use std::marker::PhantomData; +/// # +/// # use serde::forward_to_deserialize_any; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # +/// # struct MyDeserializer<V>(PhantomData<V>); +/// # +/// # impl<'q, V> Deserializer<'q> for MyDeserializer<V> { +/// # type Error = value::Error; +/// # +/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error> +/// # where +/// # W: Visitor<'q>, +/// # { +/// # unimplemented!() +/// # } +/// # +/// forward_to_deserialize_any! { +/// <W: Visitor<'q>> +/// 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 +/// } +/// # } +/// ``` +/// +/// [`Deserializer`]: trait.Deserializer.html +/// [`Visitor`]: de/trait.Visitor.html +/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any +#[macro_export(local_inner_macros)] +macro_rules! forward_to_deserialize_any { + (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => { + $(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})* + }; + // This case must be after the previous one. + ($($func:ident)*) => { + $(forward_to_deserialize_any_helper!{$func<'de, V>})* + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! forward_to_deserialize_any_method { + ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { + #[inline] + fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error> + where + $v: $crate::de::Visitor<$l>, + { + $( + let _ = $arg; + )* + self.deserialize_any(visitor) + } + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! forward_to_deserialize_any_helper { + (bool<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()} + }; + (i8<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()} + }; + (i16<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()} + }; + (i32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()} + }; + (i64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()} + }; + (i128<$l:tt, $v:ident>) => { + serde_if_integer128! { + forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()} + } + }; + (u8<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()} + }; + (u16<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()} + }; + (u32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()} + }; + (u64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()} + }; + (u128<$l:tt, $v:ident>) => { + serde_if_integer128! { + forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()} + } + }; + (f32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()} + }; + (f64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()} + }; + (char<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_char<$l, $v>()} + }; + (str<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_str<$l, $v>()} + }; + (string<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_string<$l, $v>()} + }; + (bytes<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()} + }; + (byte_buf<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()} + }; + (option<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_option<$l, $v>()} + }; + (unit<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()} + }; + (unit_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} + }; + (newtype_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} + }; + (seq<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()} + }; + (tuple<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)} + }; + (tuple_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} + }; + (map<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_map<$l, $v>()} + }; + (struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} + }; + (enum<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} + }; + (identifier<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()} + }; + (ignored_any<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()} + }; +} diff --git a/third_party/rust/serde/src/private/de.rs b/third_party/rust/serde/src/private/de.rs new file mode 100644 index 0000000000..bcb964a9c0 --- /dev/null +++ b/third_party/rust/serde/src/private/de.rs @@ -0,0 +1,2954 @@ +use lib::*; + +use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor}; + +#[cfg(any(feature = "std", feature = "alloc"))] +use de::{MapAccess, Unexpected}; + +#[cfg(any(feature = "std", feature = "alloc"))] +pub use self::content::{ + Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer, + InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor, + TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor, +}; + +/// If the missing field is of type `Option<T>` then treat is as `None`, +/// otherwise it is an error. +pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E> +where + V: Deserialize<'de>, + E: Error, +{ + struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>); + + impl<'de, E> Deserializer<'de> for MissingFieldDeserializer<E> + where + E: Error, + { + type Error = E; + + fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + Err(Error::missing_field(self.0)) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + visitor.visit_none() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } + } + + let deserializer = MissingFieldDeserializer(field, PhantomData); + Deserialize::deserialize(deserializer) +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn borrow_cow_str<'de: 'a, 'a, D, R>(deserializer: D) -> Result<R, D::Error> +where + D: Deserializer<'de>, + R: From<Cow<'a, str>>, +{ + struct CowStrVisitor; + + impl<'a> Visitor<'a> for CowStrVisitor { + type Value = Cow<'a, str>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Owned(v.to_owned())) + } + + fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Borrowed(v)) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Owned(v)) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s.to_owned())), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E> + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Borrowed(s)), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + match String::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s)), + Err(e) => Err(Error::invalid_value( + Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } + } + + deserializer.deserialize_str(CowStrVisitor).map(From::from) +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn borrow_cow_bytes<'de: 'a, 'a, D, R>(deserializer: D) -> Result<R, D::Error> +where + D: Deserializer<'de>, + R: From<Cow<'a, [u8]>>, +{ + struct CowBytesVisitor; + + impl<'a> Visitor<'a> for CowBytesVisitor { + type Value = Cow<'a, [u8]>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Owned(v.as_bytes().to_vec())) + } + + fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Borrowed(v.as_bytes())) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Owned(v.into_bytes())) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Owned(v.to_vec())) + } + + fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Borrowed(v)) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Cow::Owned(v)) + } + } + + deserializer + .deserialize_bytes(CowBytesVisitor) + .map(From::from) +} + +pub mod size_hint { + use lib::*; + + pub fn from_bounds<I>(iter: &I) -> Option<usize> + where + I: Iterator, + { + helper(iter.size_hint()) + } + + #[inline] + pub fn cautious(hint: Option<usize>) -> usize { + cmp::min(hint.unwrap_or(0), 4096) + } + + fn helper(bounds: (usize, Option<usize>)) -> Option<usize> { + match bounds { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +mod content { + // This module is private and nothing here should be used outside of + // generated code. + // + // We will iterate on the implementation for a few releases and only have to + // worry about backward compatibility for the `untagged` and `tag` attributes + // rather than for this entire mechanism. + // + // This issue is tracking making some of this stuff public: + // https://github.com/serde-rs/serde/issues/741 + + use lib::*; + + use super::size_hint; + use de::{ + self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, + MapAccess, SeqAccess, Unexpected, Visitor, + }; + + /// Used from generated code to buffer the contents of the Deserializer when + /// deserializing untagged enums and internally tagged enums. + /// + /// Not public API. Use serde-value instead. + #[derive(Debug)] + pub enum Content<'de> { + Bool(bool), + + U8(u8), + U16(u16), + U32(u32), + U64(u64), + + I8(i8), + I16(i16), + I32(i32), + I64(i64), + + F32(f32), + F64(f64), + + Char(char), + String(String), + Str(&'de str), + ByteBuf(Vec<u8>), + Bytes(&'de [u8]), + + None, + Some(Box<Content<'de>>), + + Unit, + Newtype(Box<Content<'de>>), + Seq(Vec<Content<'de>>), + Map(Vec<(Content<'de>, Content<'de>)>), + } + + impl<'de> Content<'de> { + pub fn as_str(&self) -> Option<&str> { + match *self { + Content::Str(x) => Some(x), + Content::String(ref x) => Some(x), + Content::Bytes(x) => str::from_utf8(x).ok(), + Content::ByteBuf(ref x) => str::from_utf8(x).ok(), + _ => None, + } + } + + #[cold] + fn unexpected(&self) -> Unexpected { + match *self { + Content::Bool(b) => Unexpected::Bool(b), + Content::U8(n) => Unexpected::Unsigned(n as u64), + Content::U16(n) => Unexpected::Unsigned(n as u64), + Content::U32(n) => Unexpected::Unsigned(n as u64), + Content::U64(n) => Unexpected::Unsigned(n), + Content::I8(n) => Unexpected::Signed(n as i64), + Content::I16(n) => Unexpected::Signed(n as i64), + Content::I32(n) => Unexpected::Signed(n as i64), + Content::I64(n) => Unexpected::Signed(n), + Content::F32(f) => Unexpected::Float(f as f64), + Content::F64(f) => Unexpected::Float(f), + Content::Char(c) => Unexpected::Char(c), + Content::String(ref s) => Unexpected::Str(s), + Content::Str(s) => Unexpected::Str(s), + Content::ByteBuf(ref b) => Unexpected::Bytes(b), + Content::Bytes(b) => Unexpected::Bytes(b), + Content::None | Content::Some(_) => Unexpected::Option, + Content::Unit => Unexpected::Unit, + Content::Newtype(_) => Unexpected::NewtypeStruct, + Content::Seq(_) => Unexpected::Seq, + Content::Map(_) => Unexpected::Map, + } + } + } + + impl<'de> Deserialize<'de> for Content<'de> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + // Untagged and internally tagged enums are only supported in + // self-describing formats. + let visitor = ContentVisitor { value: PhantomData }; + deserializer.deserialize_any(visitor) + } + } + + struct ContentVisitor<'de> { + value: PhantomData<Content<'de>>, + } + + impl<'de> ContentVisitor<'de> { + fn new() -> Self { + ContentVisitor { value: PhantomData } + } + } + + impl<'de> Visitor<'de> for ContentVisitor<'de> { + type Value = Content<'de>; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("any value") + } + + fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::Bool(value)) + } + + fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::I8(value)) + } + + fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::I16(value)) + } + + fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::I32(value)) + } + + fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::I64(value)) + } + + fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::U8(value)) + } + + fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::U16(value)) + } + + fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::U32(value)) + } + + fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::U64(value)) + } + + fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::F32(value)) + } + + fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::F64(value)) + } + + fn visit_char<F>(self, value: char) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::Char(value)) + } + + fn visit_str<F>(self, value: &str) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::String(value.into())) + } + + fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::Str(value)) + } + + fn visit_string<F>(self, value: String) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::String(value)) + } + + fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::ByteBuf(value.into())) + } + + fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::Bytes(value)) + } + + fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::ByteBuf(value)) + } + + fn visit_unit<F>(self) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::Unit) + } + + fn visit_none<F>(self) -> Result<Self::Value, F> + where + F: de::Error, + { + Ok(Content::None) + } + + fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) + } + + fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) + } + + fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> + where + V: SeqAccess<'de>, + { + let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint())); + while let Some(e) = try!(visitor.next_element()) { + vec.push(e); + } + Ok(Content::Seq(vec)) + } + + fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> + where + V: MapAccess<'de>, + { + let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint())); + while let Some(kv) = try!(visitor.next_entry()) { + vec.push(kv); + } + Ok(Content::Map(vec)) + } + + fn visit_enum<V>(self, _visitor: V) -> Result<Self::Value, V::Error> + where + V: EnumAccess<'de>, + { + Err(de::Error::custom( + "untagged and internally tagged enums do not support enum input", + )) + } + } + + /// This is the type of the map keys in an internally tagged enum. + /// + /// Not public API. + pub enum TagOrContent<'de> { + Tag, + Content(Content<'de>), + } + + struct TagOrContentVisitor<'de> { + name: &'static str, + value: PhantomData<TagOrContent<'de>>, + } + + impl<'de> TagOrContentVisitor<'de> { + fn new(name: &'static str) -> Self { + TagOrContentVisitor { + name: name, + value: PhantomData, + } + } + } + + impl<'de> DeserializeSeed<'de> for TagOrContentVisitor<'de> { + type Value = TagOrContent<'de>; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + // Internally tagged enums are only supported in self-describing + // formats. + deserializer.deserialize_any(self) + } + } + + impl<'de> Visitor<'de> for TagOrContentVisitor<'de> { + type Value = TagOrContent<'de>; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "a type tag `{}` or any other value", self.name) + } + + fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_bool(value) + .map(TagOrContent::Content) + } + + fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_i8(value) + .map(TagOrContent::Content) + } + + fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_i16(value) + .map(TagOrContent::Content) + } + + fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_i32(value) + .map(TagOrContent::Content) + } + + fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_i64(value) + .map(TagOrContent::Content) + } + + fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_u8(value) + .map(TagOrContent::Content) + } + + fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_u16(value) + .map(TagOrContent::Content) + } + + fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_u32(value) + .map(TagOrContent::Content) + } + + fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_u64(value) + .map(TagOrContent::Content) + } + + fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_f32(value) + .map(TagOrContent::Content) + } + + fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_f64(value) + .map(TagOrContent::Content) + } + + fn visit_char<F>(self, value: char) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_char(value) + .map(TagOrContent::Content) + } + + fn visit_str<F>(self, value: &str) -> Result<Self::Value, F> + where + F: de::Error, + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_str(value) + .map(TagOrContent::Content) + } + } + + fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F> + where + F: de::Error, + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_borrowed_str(value) + .map(TagOrContent::Content) + } + } + + fn visit_string<F>(self, value: String) -> Result<Self::Value, F> + where + F: de::Error, + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_string(value) + .map(TagOrContent::Content) + } + } + + fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F> + where + F: de::Error, + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_bytes(value) + .map(TagOrContent::Content) + } + } + + fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F> + where + F: de::Error, + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_borrowed_bytes(value) + .map(TagOrContent::Content) + } + } + + fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F> + where + F: de::Error, + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_byte_buf(value) + .map(TagOrContent::Content) + } + } + + fn visit_unit<F>(self) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_unit() + .map(TagOrContent::Content) + } + + fn visit_none<F>(self) -> Result<Self::Value, F> + where + F: de::Error, + { + ContentVisitor::new() + .visit_none() + .map(TagOrContent::Content) + } + + fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + ContentVisitor::new() + .visit_some(deserializer) + .map(TagOrContent::Content) + } + + fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + ContentVisitor::new() + .visit_newtype_struct(deserializer) + .map(TagOrContent::Content) + } + + fn visit_seq<V>(self, visitor: V) -> Result<Self::Value, V::Error> + where + V: SeqAccess<'de>, + { + ContentVisitor::new() + .visit_seq(visitor) + .map(TagOrContent::Content) + } + + fn visit_map<V>(self, visitor: V) -> Result<Self::Value, V::Error> + where + V: MapAccess<'de>, + { + ContentVisitor::new() + .visit_map(visitor) + .map(TagOrContent::Content) + } + + fn visit_enum<V>(self, visitor: V) -> Result<Self::Value, V::Error> + where + V: EnumAccess<'de>, + { + ContentVisitor::new() + .visit_enum(visitor) + .map(TagOrContent::Content) + } + } + + /// Used by generated code to deserialize an internally tagged enum. + /// + /// Not public API. + pub struct TaggedContent<'de, T> { + pub tag: T, + pub content: Content<'de>, + } + + /// Not public API. + pub struct TaggedContentVisitor<'de, T> { + tag_name: &'static str, + value: PhantomData<TaggedContent<'de, T>>, + } + + impl<'de, T> TaggedContentVisitor<'de, T> { + /// Visitor for the content of an internally tagged enum with the given + /// tag name. + pub fn new(name: &'static str) -> Self { + TaggedContentVisitor { + tag_name: name, + value: PhantomData, + } + } + } + + impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor<'de, T> + where + T: Deserialize<'de>, + { + type Value = TaggedContent<'de, T>; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + // Internally tagged enums are only supported in self-describing + // formats. + deserializer.deserialize_any(self) + } + } + + impl<'de, T> Visitor<'de> for TaggedContentVisitor<'de, T> + where + T: Deserialize<'de>, + { + type Value = TaggedContent<'de, T>; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("internally tagged enum") + } + + fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error> + where + S: SeqAccess<'de>, + { + let tag = match try!(seq.next_element()) { + Some(tag) => tag, + None => { + return Err(de::Error::missing_field(self.tag_name)); + } + }; + let rest = de::value::SeqAccessDeserializer::new(seq); + Ok(TaggedContent { + tag: tag, + content: try!(Content::deserialize(rest)), + }) + } + + fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error> + where + M: MapAccess<'de>, + { + let mut tag = None; + let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint())); + while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { + match k { + TagOrContent::Tag => { + if tag.is_some() { + return Err(de::Error::duplicate_field(self.tag_name)); + } + tag = Some(try!(map.next_value())); + } + TagOrContent::Content(k) => { + let v = try!(map.next_value()); + vec.push((k, v)); + } + } + } + match tag { + None => Err(de::Error::missing_field(self.tag_name)), + Some(tag) => Ok(TaggedContent { + tag: tag, + content: Content::Map(vec), + }), + } + } + } + + /// Used by generated code to deserialize an adjacently tagged enum. + /// + /// Not public API. + pub enum TagOrContentField { + Tag, + Content, + } + + /// Not public API. + pub struct TagOrContentFieldVisitor { + pub tag: &'static str, + pub content: &'static str, + } + + impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor { + type Value = TagOrContentField; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(self) + } + } + + impl<'de> Visitor<'de> for TagOrContentFieldVisitor { + type Value = TagOrContentField; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "{:?} or {:?}", self.tag, self.content) + } + + fn visit_str<E>(self, field: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + if field == self.tag { + Ok(TagOrContentField::Tag) + } else if field == self.content { + Ok(TagOrContentField::Content) + } else { + Err(de::Error::invalid_value(Unexpected::Str(field), &self)) + } + } + } + + /// Used by generated code to deserialize an adjacently tagged enum when + /// ignoring unrelated fields is allowed. + /// + /// Not public API. + pub enum TagContentOtherField { + Tag, + Content, + Other, + } + + /// Not public API. + pub struct TagContentOtherFieldVisitor { + pub tag: &'static str, + pub content: &'static str, + } + + impl<'de> DeserializeSeed<'de> for TagContentOtherFieldVisitor { + type Value = TagContentOtherField; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(self) + } + } + + impl<'de> Visitor<'de> for TagContentOtherFieldVisitor { + type Value = TagContentOtherField; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "{:?}, {:?}, or other ignored fields", + self.tag, self.content + ) + } + + fn visit_str<E>(self, field: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + if field == self.tag { + Ok(TagContentOtherField::Tag) + } else if field == self.content { + Ok(TagContentOtherField::Content) + } else { + Ok(TagContentOtherField::Other) + } + } + } + + /// Not public API + pub struct ContentDeserializer<'de, E> { + content: Content<'de>, + err: PhantomData<E>, + } + + impl<'de, E> ContentDeserializer<'de, E> + where + E: de::Error, + { + #[cold] + fn invalid_type(self, exp: &Expected) -> E { + de::Error::invalid_type(self.content.unexpected(), exp) + } + + fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + match self.content { + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + } + + fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + E: de::Error, + { + let seq = content.into_iter().map(ContentDeserializer::new); + let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let value = try!(visitor.visit_seq(&mut seq_visitor)); + try!(seq_visitor.end()); + Ok(value) + } + + fn visit_content_map<'de, V, E>( + content: Vec<(Content<'de>, Content<'de>)>, + visitor: V, + ) -> Result<V::Value, E> + where + V: Visitor<'de>, + E: de::Error, + { + let map = content + .into_iter() + .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); + let mut map_visitor = de::value::MapDeserializer::new(map); + let value = try!(visitor.visit_map(&mut map_visitor)); + try!(map_visitor.end()); + Ok(value) + } + + /// Used when deserializing an internally tagged enum because the content + /// will be used exactly once. + impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Bool(v) => visitor.visit_bool(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::Char(v) => visitor.visit_char(v), + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Unit => visitor.visit_unit(), + Content::None => visitor.visit_none(), + Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), + Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), + Content::Seq(v) => visit_content_seq(v, visitor), + Content::Map(v) => visit_content_map(v, visitor), + } + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::F64(v) => visitor.visit_f64(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Char(v) => visitor.visit_char(v), + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Seq(v) => visit_content_seq(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::None => visitor.visit_none(), + Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), + Content::Unit => visitor.visit_unit(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Unit => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + // As a special case, allow deserializing untagged newtype + // variant containing unit struct. + // + // #[derive(Deserialize)] + // struct Info; + // + // #[derive(Deserialize)] + // #[serde(tag = "topic")] + // enum Message { + // Info(Info), + // } + // + // We want {"topic":"Info"} to deserialize even though + // ordinarily unit structs do not deserialize from empty map. + Content::Map(ref v) if v.is_empty() => visitor.visit_unit(), + _ => self.deserialize_any(visitor), + } + } + + fn deserialize_newtype_struct<V>( + self, + _name: &str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), + _ => visitor.visit_newtype_struct(self), + } + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Seq(v) => visit_content_seq(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Map(v) => visit_content_map(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::Seq(v) => visit_content_seq(v, visitor), + Content::Map(v) => visit_content_map(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + let (variant, value) = match self.content { + Content::Map(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(de::Error::invalid_value( + de::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(de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + s @ Content::String(_) | s @ Content::Str(_) => (s, None), + other => { + return Err(de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumDeserializer::new(variant, value)) + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.content { + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U64(v) => visitor.visit_u64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } + } + + impl<'de, E> ContentDeserializer<'de, E> { + /// private API, don't use + pub fn new(content: Content<'de>) -> Self { + ContentDeserializer { + content: content, + err: PhantomData, + } + } + } + + pub struct EnumDeserializer<'de, E> + where + E: de::Error, + { + variant: Content<'de>, + value: Option<Content<'de>>, + err: PhantomData<E>, + } + + impl<'de, E> EnumDeserializer<'de, E> + where + E: de::Error, + { + pub fn new(variant: Content<'de>, value: Option<Content<'de>>) -> EnumDeserializer<'de, E> { + EnumDeserializer { + variant: variant, + value: value, + err: PhantomData, + } + } + } + + impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + type Variant = VariantDeserializer<'de, Self::Error>; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), E> + where + V: de::DeserializeSeed<'de>, + { + let visitor = VariantDeserializer { + value: self.value, + err: PhantomData, + }; + seed.deserialize(ContentDeserializer::new(self.variant)) + .map(|v| (v, visitor)) + } + } + + pub struct VariantDeserializer<'de, E> + where + E: de::Error, + { + value: Option<Content<'de>>, + err: PhantomData<E>, + } + + impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + fn unit_variant(self) -> Result<(), E> { + match self.value { + Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), + None => Ok(()), + } + } + + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, E> + where + T: de::DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.value { + Some(Content::Seq(v)) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.value { + Some(Content::Map(v)) => { + de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) + } + Some(Content::Seq(v)) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"struct variant", + )), + } + } + } + + struct SeqDeserializer<'de, E> + where + E: de::Error, + { + iter: <Vec<Content<'de>> as IntoIterator>::IntoIter, + err: PhantomData<E>, + } + + impl<'de, E> SeqDeserializer<'de, E> + where + E: de::Error, + { + fn new(vec: Vec<Content<'de>>) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + err: PhantomData, + } + } + } + + impl<'de, E> de::Deserializer<'de> for SeqDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + #[inline] + fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::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(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, E> de::SeqAccess<'de> for SeqDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } + } + + struct MapDeserializer<'de, E> + where + E: de::Error, + { + iter: <Vec<(Content<'de>, Content<'de>)> as IntoIterator>::IntoIter, + value: Option<Content<'de>>, + err: PhantomData<E>, + } + + impl<'de, E> MapDeserializer<'de, E> + where + E: de::Error, + { + fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + err: PhantomData, + } + } + } + + impl<'de, E> de::MapAccess<'de> for MapDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + seed.deserialize(ContentDeserializer::new(key)).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } + } + + impl<'de, E> de::Deserializer<'de> for MapDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::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 + } + } + + /// Not public API. + pub struct ContentRefDeserializer<'a, 'de: 'a, E> { + content: &'a Content<'de>, + err: PhantomData<E>, + } + + impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + #[cold] + fn invalid_type(self, exp: &Expected) -> E { + de::Error::invalid_type(self.content.unexpected(), exp) + } + + fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + match *self.content { + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + } + + fn visit_content_seq_ref<'a, 'de, V, E>( + content: &'a [Content<'de>], + visitor: V, + ) -> Result<V::Value, E> + where + V: Visitor<'de>, + E: de::Error, + { + let seq = content.iter().map(ContentRefDeserializer::new); + let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let value = try!(visitor.visit_seq(&mut seq_visitor)); + try!(seq_visitor.end()); + Ok(value) + } + + fn visit_content_map_ref<'a, 'de, V, E>( + content: &'a [(Content<'de>, Content<'de>)], + visitor: V, + ) -> Result<V::Value, E> + where + V: Visitor<'de>, + E: de::Error, + { + let map = content.iter().map(|&(ref k, ref v)| { + ( + ContentRefDeserializer::new(k), + ContentRefDeserializer::new(v), + ) + }); + let mut map_visitor = de::value::MapDeserializer::new(map); + let value = try!(visitor.visit_map(&mut map_visitor)); + try!(map_visitor.end()); + Ok(value) + } + + /// Used when deserializing an untagged enum because the content may need + /// to be used more than once. + impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + match *self.content { + Content::Bool(v) => visitor.visit_bool(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::Char(v) => visitor.visit_char(v), + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Unit => visitor.visit_unit(), + Content::None => visitor.visit_none(), + Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + Content::Newtype(ref v) => { + visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) + } + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + Content::Map(ref v) => visit_content_map_ref(v, visitor), + } + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::F64(v) => visitor.visit_f64(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::Char(v) => visitor.visit_char(v), + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + match *self.content { + Content::None => visitor.visit_none(), + Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + Content::Unit => visitor.visit_unit(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::Unit => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, E> + where + V: Visitor<'de>, + { + match *self.content { + Content::Newtype(ref v) => { + visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) + } + _ => visitor.visit_newtype_struct(self), + } + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::Map(ref v) => visit_content_map_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + Content::Map(ref v) => visit_content_map_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + let (variant, value) = match *self.content { + Content::Map(ref value) => { + let mut iter = value.iter(); + let &(ref variant, ref value) = match iter.next() { + Some(v) => v, + None => { + return Err(de::Error::invalid_value( + de::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(de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None), + ref other => { + return Err(de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumRefDeserializer { + variant: variant, + value: value, + err: PhantomData, + }) + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self.content { + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U64(v) => visitor.visit_u64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + } + + impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> { + /// private API, don't use + pub fn new(content: &'a Content<'de>) -> Self { + ContentRefDeserializer { + content: content, + err: PhantomData, + } + } + } + + struct EnumRefDeserializer<'a, 'de: 'a, E> + where + E: de::Error, + { + variant: &'a Content<'de>, + value: Option<&'a Content<'de>>, + err: PhantomData<E>, + } + + impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + type Variant = VariantRefDeserializer<'a, 'de, Self::Error>; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: de::DeserializeSeed<'de>, + { + let visitor = VariantRefDeserializer { + value: self.value, + err: PhantomData, + }; + seed.deserialize(ContentRefDeserializer::new(self.variant)) + .map(|v| (v, visitor)) + } + } + + struct VariantRefDeserializer<'a, 'de: 'a, E> + where + E: de::Error, + { + value: Option<&'a Content<'de>>, + err: PhantomData<E>, + } + + impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + fn unit_variant(self) -> Result<(), E> { + match self.value { + Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)), + None => Ok(()), + } + } + + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, E> + where + T: de::DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.value { + Some(&Content::Seq(ref v)) => { + de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.value { + Some(&Content::Map(ref v)) => { + de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) + } + Some(&Content::Seq(ref v)) => { + de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"struct variant", + )), + } + } + } + + struct SeqRefDeserializer<'a, 'de: 'a, E> + where + E: de::Error, + { + iter: <&'a [Content<'de>] as IntoIterator>::IntoIter, + err: PhantomData<E>, + } + + impl<'a, 'de, E> SeqRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + fn new(slice: &'a [Content<'de>]) -> Self { + SeqRefDeserializer { + iter: slice.iter(), + err: PhantomData, + } + } + } + + impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + #[inline] + fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::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(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, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed + .deserialize(ContentRefDeserializer::new(value)) + .map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } + } + + struct MapRefDeserializer<'a, 'de: 'a, E> + where + E: de::Error, + { + iter: <&'a [(Content<'de>, Content<'de>)] as IntoIterator>::IntoIter, + value: Option<&'a Content<'de>>, + err: PhantomData<E>, + } + + impl<'a, 'de, E> MapRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self { + MapRefDeserializer { + iter: map.iter(), + value: None, + err: PhantomData, + } + } + } + + impl<'de, 'a, E> de::MapAccess<'de> for MapRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some(&(ref key, ref value)) => { + self.value = Some(value); + seed.deserialize(ContentRefDeserializer::new(key)).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option<usize> { + size_hint::from_bounds(&self.iter) + } + } + + impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::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 + } + } + + impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<'de, E> + where + E: de::Error, + { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } + } + + impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } + } + + /// Visitor for deserializing an internally tagged unit variant. + /// + /// Not public API. + pub struct InternallyTaggedUnitVisitor<'a> { + type_name: &'a str, + variant_name: &'a str, + } + + impl<'a> InternallyTaggedUnitVisitor<'a> { + /// Not public API. + pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { + InternallyTaggedUnitVisitor { + type_name: type_name, + variant_name: variant_name, + } + } + } + + impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "unit variant {}::{}", + self.type_name, self.variant_name + ) + } + + fn visit_seq<S>(self, _: S) -> Result<(), S::Error> + where + S: SeqAccess<'de>, + { + Ok(()) + } + + fn visit_map<M>(self, mut access: M) -> Result<(), M::Error> + where + M: MapAccess<'de>, + { + while try!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {} + Ok(()) + } + } + + /// Visitor for deserializing an untagged unit variant. + /// + /// Not public API. + pub struct UntaggedUnitVisitor<'a> { + type_name: &'a str, + variant_name: &'a str, + } + + impl<'a> UntaggedUnitVisitor<'a> { + /// Not public API. + pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { + UntaggedUnitVisitor { + type_name: type_name, + variant_name: variant_name, + } + } + } + + impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "unit variant {}::{}", + self.type_name, self.variant_name + ) + } + + fn visit_unit<E>(self) -> Result<(), E> + where + E: de::Error, + { + Ok(()) + } + + fn visit_none<E>(self) -> Result<(), E> + where + E: de::Error, + { + Ok(()) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Like `IntoDeserializer` but also implemented for `&[u8]`. This is used for +// the newtype fallthrough case of `field_identifier`. +// +// #[derive(Deserialize)] +// #[serde(field_identifier)] +// enum F { +// A, +// B, +// Other(String), // deserialized using IdentifierDeserializer +// } +pub trait IdentifierDeserializer<'de, E: Error> { + type Deserializer: Deserializer<'de, Error = E>; + + fn from(self) -> Self::Deserializer; +} + +impl<'de, E> IdentifierDeserializer<'de, E> for u32 +where + E: Error, +{ + type Deserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer; + + fn from(self) -> Self::Deserializer { + self.into_deserializer() + } +} + +pub struct StrDeserializer<'a, E> { + value: &'a str, + marker: PhantomData<E>, +} + +impl<'a, E> IdentifierDeserializer<'a, E> for &'a str +where + E: Error, +{ + type Deserializer = StrDeserializer<'a, E>; + + fn from(self) -> Self::Deserializer { + StrDeserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_str(self.value) + } + + 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 + } +} + +pub struct BytesDeserializer<'a, E> { + value: &'a [u8], + marker: PhantomData<E>, +} + +impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8] +where + E: Error, +{ + type Deserializer = BytesDeserializer<'a, E>; + + fn from(self) -> Self::Deserializer { + BytesDeserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_bytes(self.value) + } + + 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 + } +} + +/// A DeserializeSeed helper for implementing deserialize_in_place Visitors. +/// +/// Wraps a mutable reference and calls deserialize_in_place on it. +pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T); + +impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T> +where + T: Deserialize<'de>, +{ + type Value = (); + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + T::deserialize_in_place(deserializer, self.0) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapDeserializer<'a, 'de: 'a, E>( + pub &'a mut Vec<Option<(Content<'de>, Content<'de>)>>, + pub PhantomData<E>, +); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E> +where + E: Error, +{ + fn deserialize_other<V>() -> Result<V, E> { + Err(Error::custom("can only flatten structs and maps")) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +macro_rules! forward_to_deserialize_other { + ($($func:ident ( $($arg:ty),* ))*) => { + $( + fn $func<V>(self, $(_: $arg,)* _visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + Self::deserialize_other() + } + )* + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_map(FlatInternallyTaggedAccess { + iter: self.0.iter_mut(), + pending: None, + _marker: PhantomData, + }) + } + + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + for item in self.0.iter_mut() { + // items in the vector are nulled out when used. So we can only use + // an item if it's still filled in and if the field is one we care + // about. + let use_item = match *item { + None => false, + Some((ref c, _)) => c.as_str().map_or(false, |x| variants.contains(&x)), + }; + + if use_item { + let (key, value) = item.take().unwrap(); + return visitor.visit_enum(EnumDeserializer::new(key, Some(value))); + } + } + + Err(Error::custom(format_args!( + "no variant of enum {} found in flattened data", + name + ))) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_map(FlatMapAccess::new(self.0.iter())) + } + + fn deserialize_struct<V>( + self, + _: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields)) + } + + fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match visitor.__private_visit_untagged_option(self) { + Ok(value) => Ok(value), + Err(()) => Self::deserialize_other(), + } + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + forward_to_deserialize_other! { + deserialize_bool() + deserialize_i8() + deserialize_i16() + deserialize_i32() + deserialize_i64() + deserialize_u8() + deserialize_u16() + deserialize_u32() + deserialize_u64() + deserialize_f32() + deserialize_f64() + deserialize_char() + deserialize_str() + deserialize_string() + deserialize_bytes() + deserialize_byte_buf() + deserialize_unit_struct(&'static str) + deserialize_seq() + deserialize_tuple(usize) + deserialize_tuple_struct(&'static str, usize) + deserialize_identifier() + deserialize_ignored_any() + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapAccess<'a, 'de: 'a, E> { + iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>, + pending_content: Option<&'a Content<'de>>, + _marker: PhantomData<E>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> { + fn new( + iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>, + ) -> FlatMapAccess<'a, 'de, E> { + FlatMapAccess { + iter: iter, + pending_content: None, + _marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: DeserializeSeed<'de>, + { + while let Some(item) = self.iter.next() { + // Items in the vector are nulled out when used by a struct. + if let Some((ref key, ref content)) = *item { + self.pending_content = Some(content); + return seed.deserialize(ContentRefDeserializer::new(key)).map(Some); + } + } + Ok(None) + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: DeserializeSeed<'de>, + { + match self.pending_content.take() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(Error::custom("value is missing")), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatStructAccess<'a, 'de: 'a, E> { + iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, + pending_content: Option<Content<'de>>, + fields: &'static [&'static str], + _marker: PhantomData<E>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> { + fn new( + iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, + fields: &'static [&'static str], + ) -> FlatStructAccess<'a, 'de, E> { + FlatStructAccess { + iter: iter, + pending_content: None, + fields: fields, + _marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: DeserializeSeed<'de>, + { + while let Some(item) = self.iter.next() { + // items in the vector are nulled out when used. So we can only use + // an item if it's still filled in and if the field is one we care + // about. In case we do not know which fields we want, we take them all. + let use_item = match *item { + None => false, + Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)), + }; + + if use_item { + let (key, content) = item.take().unwrap(); + self.pending_content = Some(content); + return seed.deserialize(ContentDeserializer::new(key)).map(Some); + } + } + Ok(None) + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: DeserializeSeed<'de>, + { + match self.pending_content.take() { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(Error::custom("value is missing")), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> { + iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, + pending: Option<&'a Content<'de>>, + _marker: PhantomData<E>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: DeserializeSeed<'de>, + { + while let Some(item) = self.iter.next() { + if let Some((ref key, ref content)) = *item { + // Do not take(), instead borrow this entry. The internally tagged + // enum does its own buffering so we can't tell whether this entry + // is going to be consumed. Borrowing here leaves the entry + // available for later flattened fields. + self.pending = Some(content); + return seed.deserialize(ContentRefDeserializer::new(key)).map(Some); + } + } + Ok(None) + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> + where + T: DeserializeSeed<'de>, + { + match self.pending.take() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => panic!("value is missing"), + } + } +} diff --git a/third_party/rust/serde/src/private/macros.rs b/third_party/rust/serde/src/private/macros.rs new file mode 100644 index 0000000000..4f7054f5da --- /dev/null +++ b/third_party/rust/serde/src/private/macros.rs @@ -0,0 +1,140 @@ +#[doc(hidden)] +#[macro_export] +macro_rules! __private_serialize { + () => { + trait Serialize { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: $crate::Serializer; + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __private_deserialize { + () => { + trait Deserialize<'de>: Sized { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: $crate::Deserializer<'de>; + } + }; +} + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! __serialize_unimplemented { + ($($func:ident)*) => { + $( + __serialize_unimplemented_helper!($func); + )* + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented_method { + ($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => { + fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::export::Result<Self::$ret, Self::Error> { + unimplemented!() + } + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! __serialize_unimplemented_helper { + (bool) => { + __serialize_unimplemented_method!(serialize_bool(bool) -> Ok); + }; + (i8) => { + __serialize_unimplemented_method!(serialize_i8(i8) -> Ok); + }; + (i16) => { + __serialize_unimplemented_method!(serialize_i16(i16) -> Ok); + }; + (i32) => { + __serialize_unimplemented_method!(serialize_i32(i32) -> Ok); + }; + (i64) => { + __serialize_unimplemented_method!(serialize_i64(i64) -> Ok); + }; + (u8) => { + __serialize_unimplemented_method!(serialize_u8(u8) -> Ok); + }; + (u16) => { + __serialize_unimplemented_method!(serialize_u16(u16) -> Ok); + }; + (u32) => { + __serialize_unimplemented_method!(serialize_u32(u32) -> Ok); + }; + (u64) => { + __serialize_unimplemented_method!(serialize_u64(u64) -> Ok); + }; + (f32) => { + __serialize_unimplemented_method!(serialize_f32(f32) -> Ok); + }; + (f64) => { + __serialize_unimplemented_method!(serialize_f64(f64) -> Ok); + }; + (char) => { + __serialize_unimplemented_method!(serialize_char(char) -> Ok); + }; + (str) => { + __serialize_unimplemented_method!(serialize_str(&str) -> Ok); + }; + (bytes) => { + __serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok); + }; + (none) => { + __serialize_unimplemented_method!(serialize_none() -> Ok); + }; + (some) => { + __serialize_unimplemented_method!(serialize_some<T>(&T) -> Ok); + }; + (unit) => { + __serialize_unimplemented_method!(serialize_unit() -> Ok); + }; + (unit_struct) => { + __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok); + }; + (unit_variant) => { + __serialize_unimplemented_method!(serialize_unit_variant(&str, u32, &str) -> Ok); + }; + (newtype_struct) => { + __serialize_unimplemented_method!(serialize_newtype_struct<T>(&str, &T) -> Ok); + }; + (newtype_variant) => { + __serialize_unimplemented_method!(serialize_newtype_variant<T>(&str, u32, &str, &T) -> Ok); + }; + (seq) => { + type SerializeSeq = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_seq(Option<usize>) -> SerializeSeq); + }; + (tuple) => { + type SerializeTuple = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple); + }; + (tuple_struct) => { + type SerializeTupleStruct = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct); + }; + (tuple_variant) => { + type SerializeTupleVariant = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_tuple_variant(&str, u32, &str, usize) -> SerializeTupleVariant); + }; + (map) => { + type SerializeMap = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_map(Option<usize>) -> SerializeMap); + }; + (struct) => { + type SerializeStruct = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct); + }; + (struct_variant) => { + type SerializeStructVariant = $crate::ser::Impossible<Self::Ok, Self::Error>; + __serialize_unimplemented_method!(serialize_struct_variant(&str, u32, &str, usize) -> SerializeStructVariant); + }; +} diff --git a/third_party/rust/serde/src/private/mod.rs b/third_party/rust/serde/src/private/mod.rs new file mode 100644 index 0000000000..79e0a7d008 --- /dev/null +++ b/third_party/rust/serde/src/private/mod.rs @@ -0,0 +1,4 @@ +mod macros; + +pub mod de; +pub mod ser; diff --git a/third_party/rust/serde/src/private/ser.rs b/third_party/rust/serde/src/private/ser.rs new file mode 100644 index 0000000000..eb8cfc9881 --- /dev/null +++ b/third_party/rust/serde/src/private/ser.rs @@ -0,0 +1,1338 @@ +use lib::*; + +use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}; + +#[cfg(any(feature = "std", feature = "alloc"))] +use self::content::{ + Content, ContentSerializer, SerializeStructVariantAsMapValue, SerializeTupleVariantAsMapValue, +}; + +/// Used to check that serde(getter) attributes return the expected type. +/// Not public API. +pub fn constrain<T: ?Sized>(t: &T) -> &T { + t +} + +/// Not public API. +pub fn serialize_tagged_newtype<S, T>( + serializer: S, + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + value: &T, +) -> Result<S::Ok, S::Error> +where + S: Serializer, + T: Serialize, +{ + value.serialize(TaggedSerializer { + type_ident: type_ident, + variant_ident: variant_ident, + tag: tag, + variant_name: variant_name, + delegate: serializer, + }) +} + +struct TaggedSerializer<S> { + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + delegate: S, +} + +enum Unsupported { + Boolean, + Integer, + Float, + Char, + String, + ByteArray, + Optional, + Unit, + #[cfg(any(feature = "std", feature = "alloc"))] + UnitStruct, + Sequence, + Tuple, + TupleStruct, + Enum, +} + +impl Display for Unsupported { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self { + Unsupported::Boolean => formatter.write_str("a boolean"), + Unsupported::Integer => formatter.write_str("an integer"), + Unsupported::Float => formatter.write_str("a float"), + Unsupported::Char => formatter.write_str("a char"), + Unsupported::String => formatter.write_str("a string"), + Unsupported::ByteArray => formatter.write_str("a byte array"), + Unsupported::Optional => formatter.write_str("an optional"), + Unsupported::Unit => formatter.write_str("unit"), + #[cfg(any(feature = "std", feature = "alloc"))] + Unsupported::UnitStruct => formatter.write_str("unit struct"), + Unsupported::Sequence => formatter.write_str("a sequence"), + Unsupported::Tuple => formatter.write_str("a tuple"), + Unsupported::TupleStruct => formatter.write_str("a tuple struct"), + Unsupported::Enum => formatter.write_str("an enum"), + } + } +} + +impl<S> TaggedSerializer<S> +where + S: Serializer, +{ + fn bad_type(self, what: Unsupported) -> S::Error { + ser::Error::custom(format_args!( + "cannot serialize tagged newtype variant {}::{} containing {}", + self.type_ident, self.variant_ident, what + )) + } +} + +impl<S> Serializer for TaggedSerializer<S> +where + S: Serializer, +{ + type Ok = S::Ok; + type Error = S::Error; + + type SerializeSeq = Impossible<S::Ok, S::Error>; + type SerializeTuple = Impossible<S::Ok, S::Error>; + type SerializeTupleStruct = Impossible<S::Ok, S::Error>; + type SerializeMap = S::SerializeMap; + type SerializeStruct = S::SerializeStruct; + + #[cfg(not(any(feature = "std", feature = "alloc")))] + type SerializeTupleVariant = Impossible<S::Ok, S::Error>; + #[cfg(any(feature = "std", feature = "alloc"))] + type SerializeTupleVariant = SerializeTupleVariantAsMapValue<S::SerializeMap>; + + #[cfg(not(any(feature = "std", feature = "alloc")))] + type SerializeStructVariant = Impossible<S::Ok, S::Error>; + #[cfg(any(feature = "std", feature = "alloc"))] + type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>; + + fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Boolean)) + } + + fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Float)) + } + + fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Float)) + } + + fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Char)) + } + + fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::String)) + } + + fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::ByteArray)) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Optional)) + } + + fn serialize_some<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(self.bad_type(Unsupported::Optional)) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(self.bad_type(Unsupported::Unit)) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> { + let mut map = try!(self.delegate.serialize_map(Some(1))); + try!(map.serialize_entry(self.tag, self.variant_name)); + map.end() + } + + fn serialize_unit_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_entry(inner_variant, &())); + map.end() + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + inner_value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_entry(inner_variant, inner_value)); + map.end() + } + + fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(self.bad_type(Unsupported::Sequence)) + } + + fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(self.bad_type(Unsupported::Tuple)) + } + + fn serialize_tuple_struct( + self, + _: &'static str, + _: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(self.bad_type(Unsupported::TupleStruct)) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + // Lack of push-based serialization means we need to buffer the content + // of the tuple variant, so it requires std. + Err(self.bad_type(Unsupported::Enum)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_key(inner_variant)); + Ok(SerializeTupleVariantAsMapValue::new( + map, + inner_variant, + len, + )) + } + + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + let mut map = try!(self.delegate.serialize_map(len.map(|len| len + 1))); + try!(map.serialize_entry(self.tag, self.variant_name)); + Ok(map) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + let mut state = try!(self.delegate.serialize_struct(name, len + 1)); + try!(state.serialize_field(self.tag, self.variant_name)); + Ok(state) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + // Lack of push-based serialization means we need to buffer the content + // of the struct variant, so it requires std. + Err(self.bad_type(Unsupported::Enum)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_key(inner_variant)); + Ok(SerializeStructVariantAsMapValue::new( + map, + inner_variant, + len, + )) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn collect_str<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error> + where + T: Display, + { + Err(self.bad_type(Unsupported::String)) + } +} + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[derive(Debug)] +pub struct Error; + +impl ser::Error for Error { + fn custom<T>(_: T) -> Self + where + T: Display, + { + unimplemented!() + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + fn description(&self) -> &str { + unimplemented!() + } +} + +impl Display for Error { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +mod content { + use lib::*; + + use ser::{self, Serialize, Serializer}; + + pub struct SerializeTupleVariantAsMapValue<M> { + map: M, + name: &'static str, + fields: Vec<Content>, + } + + impl<M> SerializeTupleVariantAsMapValue<M> { + pub fn new(map: M, name: &'static str, len: usize) -> Self { + SerializeTupleVariantAsMapValue { + map: map, + name: name, + fields: Vec::with_capacity(len), + } + } + } + + impl<M> ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue<M> + where + M: ser::SerializeMap, + { + type Ok = M::Ok; + type Error = M::Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), M::Error> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); + self.fields.push(value); + Ok(()) + } + + fn end(mut self) -> Result<M::Ok, M::Error> { + try!(self + .map + .serialize_value(&Content::TupleStruct(self.name, self.fields))); + self.map.end() + } + } + + pub struct SerializeStructVariantAsMapValue<M> { + map: M, + name: &'static str, + fields: Vec<(&'static str, Content)>, + } + + impl<M> SerializeStructVariantAsMapValue<M> { + pub fn new(map: M, name: &'static str, len: usize) -> Self { + SerializeStructVariantAsMapValue { + map: map, + name: name, + fields: Vec::with_capacity(len), + } + } + } + + impl<M> ser::SerializeStructVariant for SerializeStructVariantAsMapValue<M> + where + M: ser::SerializeMap, + { + type Ok = M::Ok; + type Error = M::Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), M::Error> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(mut self) -> Result<M::Ok, M::Error> { + try!(self + .map + .serialize_value(&Content::Struct(self.name, self.fields))); + self.map.end() + } + } + + #[derive(Debug)] + pub enum Content { + Bool(bool), + + U8(u8), + U16(u16), + U32(u32), + U64(u64), + + I8(i8), + I16(i16), + I32(i32), + I64(i64), + + F32(f32), + F64(f64), + + Char(char), + String(String), + Bytes(Vec<u8>), + + None, + Some(Box<Content>), + + Unit, + UnitStruct(&'static str), + UnitVariant(&'static str, u32, &'static str), + NewtypeStruct(&'static str, Box<Content>), + NewtypeVariant(&'static str, u32, &'static str, Box<Content>), + + Seq(Vec<Content>), + Tuple(Vec<Content>), + TupleStruct(&'static str, Vec<Content>), + TupleVariant(&'static str, u32, &'static str, Vec<Content>), + Map(Vec<(Content, Content)>), + Struct(&'static str, Vec<(&'static str, Content)>), + StructVariant( + &'static str, + u32, + &'static str, + Vec<(&'static str, Content)>, + ), + } + + impl Serialize for Content { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match *self { + Content::Bool(b) => serializer.serialize_bool(b), + Content::U8(u) => serializer.serialize_u8(u), + Content::U16(u) => serializer.serialize_u16(u), + Content::U32(u) => serializer.serialize_u32(u), + Content::U64(u) => serializer.serialize_u64(u), + Content::I8(i) => serializer.serialize_i8(i), + Content::I16(i) => serializer.serialize_i16(i), + Content::I32(i) => serializer.serialize_i32(i), + Content::I64(i) => serializer.serialize_i64(i), + Content::F32(f) => serializer.serialize_f32(f), + Content::F64(f) => serializer.serialize_f64(f), + Content::Char(c) => serializer.serialize_char(c), + Content::String(ref s) => serializer.serialize_str(s), + Content::Bytes(ref b) => serializer.serialize_bytes(b), + Content::None => serializer.serialize_none(), + Content::Some(ref c) => serializer.serialize_some(&**c), + Content::Unit => serializer.serialize_unit(), + Content::UnitStruct(n) => serializer.serialize_unit_struct(n), + Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v), + Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c), + Content::NewtypeVariant(n, i, v, ref c) => { + serializer.serialize_newtype_variant(n, i, v, &**c) + } + Content::Seq(ref elements) => elements.serialize(serializer), + Content::Tuple(ref elements) => { + use ser::SerializeTuple; + let mut tuple = try!(serializer.serialize_tuple(elements.len())); + for e in elements { + try!(tuple.serialize_element(e)); + } + tuple.end() + } + Content::TupleStruct(n, ref fields) => { + use ser::SerializeTupleStruct; + let mut ts = try!(serializer.serialize_tuple_struct(n, fields.len())); + for f in fields { + try!(ts.serialize_field(f)); + } + ts.end() + } + Content::TupleVariant(n, i, v, ref fields) => { + use ser::SerializeTupleVariant; + let mut tv = try!(serializer.serialize_tuple_variant(n, i, v, fields.len())); + for f in fields { + try!(tv.serialize_field(f)); + } + tv.end() + } + Content::Map(ref entries) => { + use ser::SerializeMap; + let mut map = try!(serializer.serialize_map(Some(entries.len()))); + for &(ref k, ref v) in entries { + try!(map.serialize_entry(k, v)); + } + map.end() + } + Content::Struct(n, ref fields) => { + use ser::SerializeStruct; + let mut s = try!(serializer.serialize_struct(n, fields.len())); + for &(k, ref v) in fields { + try!(s.serialize_field(k, v)); + } + s.end() + } + Content::StructVariant(n, i, v, ref fields) => { + use ser::SerializeStructVariant; + let mut sv = try!(serializer.serialize_struct_variant(n, i, v, fields.len())); + for &(k, ref v) in fields { + try!(sv.serialize_field(k, v)); + } + sv.end() + } + } + } + } + + pub struct ContentSerializer<E> { + error: PhantomData<E>, + } + + impl<E> ContentSerializer<E> { + pub fn new() -> Self { + ContentSerializer { error: PhantomData } + } + } + + impl<E> Serializer for ContentSerializer<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + type SerializeSeq = SerializeSeq<E>; + type SerializeTuple = SerializeTuple<E>; + type SerializeTupleStruct = SerializeTupleStruct<E>; + type SerializeTupleVariant = SerializeTupleVariant<E>; + type SerializeMap = SerializeMap<E>; + type SerializeStruct = SerializeStruct<E>; + type SerializeStructVariant = SerializeStructVariant<E>; + + fn serialize_bool(self, v: bool) -> Result<Content, E> { + Ok(Content::Bool(v)) + } + + fn serialize_i8(self, v: i8) -> Result<Content, E> { + Ok(Content::I8(v)) + } + + fn serialize_i16(self, v: i16) -> Result<Content, E> { + Ok(Content::I16(v)) + } + + fn serialize_i32(self, v: i32) -> Result<Content, E> { + Ok(Content::I32(v)) + } + + fn serialize_i64(self, v: i64) -> Result<Content, E> { + Ok(Content::I64(v)) + } + + fn serialize_u8(self, v: u8) -> Result<Content, E> { + Ok(Content::U8(v)) + } + + fn serialize_u16(self, v: u16) -> Result<Content, E> { + Ok(Content::U16(v)) + } + + fn serialize_u32(self, v: u32) -> Result<Content, E> { + Ok(Content::U32(v)) + } + + fn serialize_u64(self, v: u64) -> Result<Content, E> { + Ok(Content::U64(v)) + } + + fn serialize_f32(self, v: f32) -> Result<Content, E> { + Ok(Content::F32(v)) + } + + fn serialize_f64(self, v: f64) -> Result<Content, E> { + Ok(Content::F64(v)) + } + + fn serialize_char(self, v: char) -> Result<Content, E> { + Ok(Content::Char(v)) + } + + fn serialize_str(self, value: &str) -> Result<Content, E> { + Ok(Content::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<Content, E> { + Ok(Content::Bytes(value.to_owned())) + } + + fn serialize_none(self) -> Result<Content, E> { + Ok(Content::None) + } + + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Content, E> + where + T: Serialize, + { + Ok(Content::Some(Box::new(try!(value.serialize(self))))) + } + + fn serialize_unit(self) -> Result<Content, E> { + Ok(Content::Unit) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result<Content, E> { + Ok(Content::UnitStruct(name)) + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result<Content, E> { + Ok(Content::UnitVariant(name, variant_index, variant)) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + name: &'static str, + value: &T, + ) -> Result<Content, E> + where + T: Serialize, + { + Ok(Content::NewtypeStruct( + name, + Box::new(try!(value.serialize(self))), + )) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<Content, E> + where + T: Serialize, + { + Ok(Content::NewtypeVariant( + name, + variant_index, + variant, + Box::new(try!(value.serialize(self))), + )) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> { + Ok(SerializeSeq { + elements: Vec::with_capacity(len.unwrap_or(0)), + error: PhantomData, + }) + } + + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> { + Ok(SerializeTuple { + elements: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct, E> { + Ok(SerializeTupleStruct { + name: name, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, E> { + Ok(SerializeTupleVariant { + name: name, + variant_index: variant_index, + variant: variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> { + Ok(SerializeMap { + entries: Vec::with_capacity(len.unwrap_or(0)), + key: None, + error: PhantomData, + }) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, E> { + Ok(SerializeStruct { + name: name, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeStructVariant, E> { + Ok(SerializeStructVariant { + name: name, + variant_index: variant_index, + variant: variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + } + + pub struct SerializeSeq<E> { + elements: Vec<Content>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeSeq for SerializeSeq<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.elements.push(value); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::Seq(self.elements)) + } + } + + pub struct SerializeTuple<E> { + elements: Vec<Content>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeTuple for SerializeTuple<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.elements.push(value); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::Tuple(self.elements)) + } + } + + pub struct SerializeTupleStruct<E> { + name: &'static str, + fields: Vec<Content>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::TupleStruct(self.name, self.fields)) + } + } + + pub struct SerializeTupleVariant<E> { + name: &'static str, + variant_index: u32, + variant: &'static str, + fields: Vec<Content>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::TupleVariant( + self.name, + self.variant_index, + self.variant, + self.fields, + )) + } + } + + pub struct SerializeMap<E> { + entries: Vec<(Content, Content)>, + key: Option<Content>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeMap for SerializeMap<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), E> + where + T: Serialize, + { + let key = try!(key.serialize(ContentSerializer::<E>::new())); + self.key = Some(key); + Ok(()) + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { + let key = self + .key + .take() + .expect("serialize_value called before serialize_key"); + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.entries.push((key, value)); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::Map(self.entries)) + } + + fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<(), E> + where + K: Serialize, + V: Serialize, + { + let key = try!(key.serialize(ContentSerializer::<E>::new())); + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.entries.push((key, value)); + Ok(()) + } + } + + pub struct SerializeStruct<E> { + name: &'static str, + fields: Vec<(&'static str, Content)>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeStruct for SerializeStruct<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::Struct(self.name, self.fields)) + } + } + + pub struct SerializeStructVariant<E> { + name: &'static str, + variant_index: u32, + variant: &'static str, + fields: Vec<(&'static str, Content)>, + error: PhantomData<E>, + } + + impl<E> ser::SerializeStructVariant for SerializeStructVariant<E> + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<E>::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result<Content, E> { + Ok(Content::StructVariant( + self.name, + self.variant_index, + self.variant, + self.fields, + )) + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializer<'a, M: 'a>(pub &'a mut M); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializer<'a, M> +where + M: SerializeMap + 'a, +{ + fn bad_type(what: Unsupported) -> M::Error { + ser::Error::custom(format_args!( + "can only flatten structs and maps (got {})", + what + )) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> Serializer for FlatMapSerializer<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + type SerializeSeq = Impossible<Self::Ok, M::Error>; + type SerializeTuple = Impossible<Self::Ok, M::Error>; + type SerializeTupleStruct = Impossible<Self::Ok, M::Error>; + type SerializeMap = FlatMapSerializeMap<'a, M>; + type SerializeStruct = FlatMapSerializeStruct<'a, M>; + type SerializeTupleVariant = Impossible<Self::Ok, M::Error>; + type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>; + + fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Boolean)) + } + + fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Float)) + } + + fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Float)) + } + + fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Char)) + } + + fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::String)) + } + + fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::ByteArray)) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Ok(()) + } + + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Ok(()) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::UnitStruct)) + } + + fn serialize_unit_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + ) -> Result<Self::Ok, Self::Error> { + Err(Self::bad_type(Unsupported::Enum)) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _: &'static str, + _: u32, + variant: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + try!(self.0.serialize_key(variant)); + self.0.serialize_value(value) + } + + fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(Self::bad_type(Unsupported::Sequence)) + } + + fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(Self::bad_type(Unsupported::Tuple)) + } + + fn serialize_tuple_struct( + self, + _: &'static str, + _: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(Self::bad_type(Unsupported::TupleStruct)) + } + + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(Self::bad_type(Unsupported::Enum)) + } + + fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Ok(FlatMapSerializeMap(self.0)) + } + + fn serialize_struct( + self, + _: &'static str, + _: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + Ok(FlatMapSerializeStruct(self.0)) + } + + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + _: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + try!(self.0.serialize_key(inner_variant)); + Ok(FlatMapSerializeStructVariantAsMapValue::new( + self.0, + inner_variant, + )) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeMap<'a, M: 'a>(&'a mut M); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeMap for FlatMapSerializeMap<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + self.0.serialize_key(key) + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + self.0.serialize_value(value) + } + + fn serialize_entry<K: ?Sized, V: ?Sized>( + &mut self, + key: &K, + value: &V, + ) -> Result<(), Self::Error> + where + K: Serialize, + V: Serialize, + { + self.0.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeStruct<'a, M: 'a>(&'a mut M); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeStruct for FlatMapSerializeStruct<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize, + { + self.0.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> { + map: &'a mut M, + name: &'static str, + fields: Vec<(&'static str, Content)>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializeStructVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + fn new(map: &'a mut M, name: &'static str) -> FlatMapSerializeStructVariantAsMapValue<'a, M> { + FlatMapSerializeStructVariantAsMapValue { + map: map, + name: name, + fields: Vec::new(), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeStructVariant for FlatMapSerializeStructVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result<(), Self::Error> { + try!(self + .map + .serialize_value(&Content::Struct(self.name, self.fields))); + Ok(()) + } +} diff --git a/third_party/rust/serde/src/ser/fmt.rs b/third_party/rust/serde/src/ser/fmt.rs new file mode 100644 index 0000000000..e7e09a1bfe --- /dev/null +++ b/third_party/rust/serde/src/ser/fmt.rs @@ -0,0 +1,174 @@ +use lib::*; +use ser::{Error, Impossible, Serialize, Serializer}; + +impl Error for fmt::Error { + fn custom<T: Display>(_msg: T) -> Self { + fmt::Error + } +} + +macro_rules! fmt_primitives { + ($($f:ident: $t:ty,)*) => { + $( + fn $f(self, v: $t) -> fmt::Result { + Display::fmt(&v, self) + } + )* + }; +} + +/// ```edition2018 +/// use serde::Serialize; +/// use std::fmt::{self, Display}; +/// +/// #[derive(Serialize)] +/// #[serde(rename_all = "kebab-case")] +/// pub enum MessageType { +/// StartRequest, +/// EndRequest, +/// } +/// +/// impl Display for MessageType { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// self.serialize(f) +/// } +/// } +/// ``` +impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> { + type Ok = (); + type Error = fmt::Error; + type SerializeSeq = Impossible<(), fmt::Error>; + type SerializeTuple = Impossible<(), fmt::Error>; + type SerializeTupleStruct = Impossible<(), fmt::Error>; + type SerializeTupleVariant = Impossible<(), fmt::Error>; + type SerializeMap = Impossible<(), fmt::Error>; + type SerializeStruct = Impossible<(), fmt::Error>; + type SerializeStructVariant = Impossible<(), fmt::Error>; + + fmt_primitives! { + serialize_bool: bool, + serialize_i8: i8, + serialize_i16: i16, + serialize_i32: i32, + serialize_i64: i64, + serialize_u8: u8, + serialize_u16: u16, + serialize_u32: u32, + serialize_u64: u64, + serialize_f32: f32, + serialize_f64: f64, + serialize_char: char, + serialize_str: &str, + serialize_unit_struct: &'static str, + } + + serde_if_integer128! { + fmt_primitives! { + serialize_i128: i128, + serialize_u128: u128, + } + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> fmt::Result { + Display::fmt(variant, self) + } + + fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> fmt::Result + where + T: Serialize, + { + Serialize::serialize(value, self) + } + + fn serialize_bytes(self, _v: &[u8]) -> fmt::Result { + Err(fmt::Error) + } + + fn serialize_none(self) -> fmt::Result { + Err(fmt::Error) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> fmt::Result + where + T: Serialize, + { + Err(fmt::Error) + } + + fn serialize_unit(self) -> fmt::Result { + Err(fmt::Error) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> fmt::Result + where + T: Serialize, + { + Err(fmt::Error) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, fmt::Error> { + Err(fmt::Error) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, fmt::Error> { + Err(fmt::Error) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, fmt::Error> { + Err(fmt::Error) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, fmt::Error> { + Err(fmt::Error) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, fmt::Error> { + Err(fmt::Error) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, fmt::Error> { + Err(fmt::Error) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, fmt::Error> { + Err(fmt::Error) + } + + fn collect_str<T: ?Sized>(self, value: &T) -> fmt::Result + where + T: Display, + { + Display::fmt(value, self) + } +} diff --git a/third_party/rust/serde/src/ser/impls.rs b/third_party/rust/serde/src/ser/impls.rs new file mode 100644 index 0000000000..0dc8085f49 --- /dev/null +++ b/third_party/rust/serde/src/ser/impls.rs @@ -0,0 +1,883 @@ +use lib::*; + +use ser::{Error, Serialize, SerializeTuple, Serializer}; + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! primitive_impl { + ($ty:ident, $method:ident $($cast:tt)*) => { + impl Serialize for $ty { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.$method(*self $($cast)*) + } + } + } +} + +primitive_impl!(bool, serialize_bool); +primitive_impl!(isize, serialize_i64 as i64); +primitive_impl!(i8, serialize_i8); +primitive_impl!(i16, serialize_i16); +primitive_impl!(i32, serialize_i32); +primitive_impl!(i64, serialize_i64); +primitive_impl!(usize, serialize_u64 as u64); +primitive_impl!(u8, serialize_u8); +primitive_impl!(u16, serialize_u16); +primitive_impl!(u32, serialize_u32); +primitive_impl!(u64, serialize_u64); +primitive_impl!(f32, serialize_f32); +primitive_impl!(f64, serialize_f64); +primitive_impl!(char, serialize_char); + +serde_if_integer128! { + primitive_impl!(i128, serialize_i128); + primitive_impl!(u128, serialize_u128); +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for str { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Serialize for String { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(self) + } +} + +impl<'a> Serialize for fmt::Arguments<'a> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.collect_str(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl Serialize for CStr { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self.to_bytes()) + } +} + +#[cfg(feature = "std")] +impl Serialize for CString { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self.to_bytes()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<T> Serialize for Option<T> +where + T: Serialize, +{ + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match *self { + Some(ref value) => serializer.serialize_some(value), + None => serializer.serialize_none(), + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<T: ?Sized> Serialize for PhantomData<T> { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_unit_struct("PhantomData") + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Does not require T: Serialize. +impl<T> Serialize for [T; 0] { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + try!(serializer.serialize_tuple(0)).end() + } +} + +macro_rules! array_impls { + ($($len:tt)+) => { + $( + impl<T> Serialize for [T; $len] + where + T: Serialize, + { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut seq = try!(serializer.serialize_tuple($len)); + for e in self { + try!(seq.serialize_element(e)); + } + seq.end() + } + } + )+ + } +} + +array_impls! { + 01 02 03 04 05 06 07 08 09 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<T> Serialize for [T] +where + T: Serialize, +{ + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.collect_seq(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +macro_rules! seq_impl { + ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => { + impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*> + where + T: Serialize $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound,)* + { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.collect_seq(self) + } + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!(BinaryHeap<T: Ord>); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!(BTreeSet<T: Ord>); + +#[cfg(feature = "std")] +seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!(LinkedList<T>); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!(Vec<T>); + +#[cfg(any(feature = "std", feature = "alloc"))] +seq_impl!(VecDeque<T>); + +//////////////////////////////////////////////////////////////////////////////// + +impl<Idx> Serialize for Range<Idx> +where + Idx: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = try!(serializer.serialize_struct("Range", 2)); + try!(state.serialize_field("start", &self.start)); + try!(state.serialize_field("end", &self.end)); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(range_inclusive)] +impl<Idx> Serialize for RangeInclusive<Idx> +where + Idx: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = try!(serializer.serialize_struct("RangeInclusive", 2)); + try!(state.serialize_field("start", &self.start())); + try!(state.serialize_field("end", &self.end())); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(ops_bound, collections_bound))] +impl<T> Serialize for Bound<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match *self { + Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"), + Bound::Included(ref value) => { + serializer.serialize_newtype_variant("Bound", 1, "Included", value) + } + Bound::Excluded(ref value) => { + serializer.serialize_newtype_variant("Bound", 2, "Excluded", value) + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for () { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_unit() + } +} + +#[cfg(feature = "unstable")] +impl Serialize for ! { + fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + *self + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! tuple_impls { + ($($len:expr => ($($n:tt $name:ident)+))+) => { + $( + impl<$($name),+> Serialize for ($($name,)+) + where + $($name: Serialize,)+ + { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut tuple = try!(serializer.serialize_tuple($len)); + $( + try!(tuple.serialize_element(&self.$n)); + )+ + tuple.end() + } + } + )+ + } +} + +tuple_impls! { + 1 => (0 T0) + 2 => (0 T0 1 T1) + 3 => (0 T0 1 T1 2 T2) + 4 => (0 T0 1 T1 2 T2 3 T3) + 5 => (0 T0 1 T1 2 T2 3 T3 4 T4) + 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) + 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) + 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) + 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) + 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) + 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) + 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) + 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) + 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) + 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) + 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +macro_rules! map_impl { + ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => { + impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*> + where + K: Serialize $(+ $kbound1 $(+ $kbound2)*)*, + V: Serialize, + $($typaram: $bound,)* + { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.collect_map(self) + } + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +map_impl!(BTreeMap<K: Ord, V>); + +#[cfg(feature = "std")] +map_impl!(HashMap<K: Eq + Hash, V, H: BuildHasher>); + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! deref_impl { + ( + $(#[doc = $doc:tt])* + <$($desc:tt)+ + ) => { + $(#[doc = $doc])* + impl <$($desc)+ { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + (**self).serialize(serializer) + } + } + }; +} + +deref_impl!(<'a, T: ?Sized> Serialize for &'a T where T: Serialize); +deref_impl!(<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize); + +#[cfg(any(feature = "std", feature = "alloc"))] +deref_impl!(<T: ?Sized> Serialize for Box<T> where T: Serialize); + +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +deref_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Serializing a data structure containing `Rc` will serialize a copy of + /// the contents of the `Rc` each time the `Rc` is referenced within the + /// data structure. Serialization will not attempt to deduplicate these + /// repeated data. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + <T: ?Sized> Serialize for Rc<T> where T: Serialize +} + +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +deref_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Serializing a data structure containing `Arc` will serialize a copy of + /// the contents of the `Arc` each time the `Arc` is referenced within the + /// data structure. Serialization will not attempt to deduplicate these + /// repeated data. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + <T: ?Sized> Serialize for Arc<T> where T: Serialize +} + +#[cfg(any(feature = "std", feature = "alloc"))] +deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned); + +//////////////////////////////////////////////////////////////////////////////// + +/// This impl requires the [`"rc"`] Cargo feature of Serde. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +impl<T: ?Sized> Serialize for RcWeak<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.upgrade().serialize(serializer) + } +} + +/// This impl requires the [`"rc"`] Cargo feature of Serde. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +impl<T: ?Sized> Serialize for ArcWeak<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.upgrade().serialize(serializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! nonzero_integers { + ( $( $T: ident, )+ ) => { + $( + #[cfg(num_nonzero)] + impl Serialize for num::$T { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.get().serialize(serializer) + } + } + )+ + } +} + +nonzero_integers! { + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroUsize, +} + +#[cfg(num_nonzero_signed)] +nonzero_integers! { + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroIsize, +} + +// Currently 128-bit integers do not work on Emscripten targets so we need an +// additional `#[cfg]` +serde_if_integer128! { + nonzero_integers! { + NonZeroU128, + } + + #[cfg(num_nonzero_signed)] + nonzero_integers! { + NonZeroI128, + } +} + +impl<T> Serialize for Cell<T> +where + T: Serialize + Copy, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.get().serialize(serializer) + } +} + +impl<T> Serialize for RefCell<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self.try_borrow() { + Ok(value) => value.serialize(serializer), + Err(_) => Err(S::Error::custom("already mutably borrowed")), + } + } +} + +#[cfg(feature = "std")] +impl<T> Serialize for Mutex<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self.lock() { + Ok(locked) => locked.serialize(serializer), + Err(_) => Err(S::Error::custom("lock poison error while serializing")), + } + } +} + +#[cfg(feature = "std")] +impl<T> Serialize for RwLock<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self.read() { + Ok(locked) => locked.serialize(serializer), + Err(_) => Err(S::Error::custom("lock poison error while serializing")), + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<T, E> Serialize for Result<T, E> +where + T: Serialize, + E: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match *self { + Result::Ok(ref value) => serializer.serialize_newtype_variant("Result", 0, "Ok", value), + Result::Err(ref value) => { + serializer.serialize_newtype_variant("Result", 1, "Err", value) + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(core_duration, feature = "std"))] +impl Serialize for Duration { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = try!(serializer.serialize_struct("Duration", 2)); + try!(state.serialize_field("secs", &self.as_secs())); + try!(state.serialize_field("nanos", &self.subsec_nanos())); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl Serialize for SystemTime { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use super::SerializeStruct; + let duration_since_epoch = self + .duration_since(UNIX_EPOCH) + .map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?; + let mut state = try!(serializer.serialize_struct("SystemTime", 2)); + try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs())); + try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos())); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Serialize a value that implements `Display` as a string, when that string is +/// statically known to never have more than a constant `MAX_LEN` bytes. +/// +/// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes. +#[cfg(feature = "std")] +macro_rules! serialize_display_bounded_length { + ($value:expr, $max:expr, $serializer:expr) => {{ + let mut buffer = [0u8; $max]; + let remaining_len = { + let mut remaining = &mut buffer[..]; + write!(remaining, "{}", $value).unwrap(); + remaining.len() + }; + let written_len = buffer.len() - remaining_len; + let written = &buffer[..written_len]; + + // write! only provides fmt::Formatter to Display implementations, which + // has methods write_str and write_char but no method to write arbitrary + // bytes. Therefore `written` must be valid UTF-8. + let written_str = str::from_utf8(written).expect("must be valid UTF-8"); + $serializer.serialize_str(written_str) + }}; +} + +#[cfg(feature = "std")] +impl Serialize for net::IpAddr { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if serializer.is_human_readable() { + match *self { + net::IpAddr::V4(ref a) => a.serialize(serializer), + net::IpAddr::V6(ref a) => a.serialize(serializer), + } + } else { + match *self { + net::IpAddr::V4(ref a) => { + serializer.serialize_newtype_variant("IpAddr", 0, "V4", a) + } + net::IpAddr::V6(ref a) => { + serializer.serialize_newtype_variant("IpAddr", 1, "V6", a) + } + } + } + } +} + +#[cfg(feature = "std")] +impl Serialize for net::Ipv4Addr { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 15; + debug_assert_eq!(MAX_LEN, "101.102.103.104".len()); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + self.octets().serialize(serializer) + } + } +} + +#[cfg(feature = "std")] +impl Serialize for net::Ipv6Addr { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 39; + debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len()); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + self.octets().serialize(serializer) + } + } +} + +#[cfg(feature = "std")] +impl Serialize for net::SocketAddr { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if serializer.is_human_readable() { + match *self { + net::SocketAddr::V4(ref addr) => addr.serialize(serializer), + net::SocketAddr::V6(ref addr) => addr.serialize(serializer), + } + } else { + match *self { + net::SocketAddr::V4(ref addr) => { + serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr) + } + net::SocketAddr::V6(ref addr) => { + serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr) + } + } + } + } +} + +#[cfg(feature = "std")] +impl Serialize for net::SocketAddrV4 { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 21; + debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len()); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + (self.ip(), self.port()).serialize(serializer) + } + } +} + +#[cfg(feature = "std")] +impl Serialize for net::SocketAddrV6 { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 47; + debug_assert_eq!( + MAX_LEN, + "[1001:1002:1003:1004:1005:1006:1007:1008]:65000".len() + ); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + (self.ip(), self.port()).serialize(serializer) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl Serialize for Path { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self.to_str() { + Some(s) => s.serialize(serializer), + None => Err(Error::custom("path contains invalid UTF-8 characters")), + } + } +} + +#[cfg(feature = "std")] +impl Serialize for PathBuf { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.as_path().serialize(serializer) + } +} + +#[cfg(all(feature = "std", any(unix, windows)))] +impl Serialize for OsStr { + #[cfg(unix)] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use std::os::unix::ffi::OsStrExt; + serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes()) + } + + #[cfg(windows)] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use std::os::windows::ffi::OsStrExt; + let val = self.encode_wide().collect::<Vec<_>>(); + serializer.serialize_newtype_variant("OsString", 1, "Windows", &val) + } +} + +#[cfg(all(feature = "std", any(unix, windows)))] +impl Serialize for OsString { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.as_os_str().serialize(serializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl<T> Serialize for Wrapping<T> +where + T: Serialize, +{ + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(core_reverse)] +impl<T> Serialize for Reverse<T> +where + T: Serialize, +{ + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(all(feature = "std", std_atomic))] +macro_rules! atomic_impl { + ($($ty:ident)*) => { + $( + impl Serialize for $ty { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.load(Ordering::SeqCst).serialize(serializer) + } + } + )* + } +} + +#[cfg(all(feature = "std", std_atomic))] +atomic_impl! { + AtomicBool + AtomicI8 AtomicI16 AtomicI32 AtomicIsize + AtomicU8 AtomicU16 AtomicU32 AtomicUsize +} + +#[cfg(all(feature = "std", std_atomic64))] +atomic_impl! { + AtomicI64 AtomicU64 +} diff --git a/third_party/rust/serde/src/ser/impossible.rs b/third_party/rust/serde/src/ser/impossible.rs new file mode 100644 index 0000000000..90bab29a07 --- /dev/null +++ b/third_party/rust/serde/src/ser/impossible.rs @@ -0,0 +1,216 @@ +//! This module contains `Impossible` serializer and its implementations. + +use lib::*; + +use ser::{ + self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, + SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, +}; + +/// Helper type for implementing a `Serializer` that does not support +/// serializing one of the compound types. +/// +/// This type cannot be instantiated, but implements every one of the traits +/// corresponding to the [`Serializer`] compound types: [`SerializeSeq`], +/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`], +/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`]. +/// +/// ```edition2018 +/// # use serde::ser::{Serializer, Impossible}; +/// # use serde::private::ser::Error; +/// # +/// # struct MySerializer; +/// # +/// impl Serializer for MySerializer { +/// type Ok = (); +/// type Error = Error; +/// +/// type SerializeSeq = Impossible<(), Error>; +/// /* other associated types */ +/// +/// /// This data format does not support serializing sequences. +/// fn serialize_seq(self, +/// len: Option<usize>) +/// -> Result<Self::SerializeSeq, Error> { +/// // Given Impossible cannot be instantiated, the only +/// // thing we can do here is to return an error. +/// # stringify! { +/// Err(...) +/// # }; +/// # unimplemented!() +/// } +/// +/// /* other Serializer methods */ +/// # serde::__serialize_unimplemented! { +/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some +/// # unit unit_struct unit_variant newtype_struct newtype_variant +/// # tuple tuple_struct tuple_variant map struct struct_variant +/// # } +/// } +/// ``` +/// +/// [`Serializer`]: trait.Serializer.html +/// [`SerializeSeq`]: trait.SerializeSeq.html +/// [`SerializeTuple`]: trait.SerializeTuple.html +/// [`SerializeTupleStruct`]: trait.SerializeTupleStruct.html +/// [`SerializeTupleVariant`]: trait.SerializeTupleVariant.html +/// [`SerializeMap`]: trait.SerializeMap.html +/// [`SerializeStruct`]: trait.SerializeStruct.html +/// [`SerializeStructVariant`]: trait.SerializeStructVariant.html +pub struct Impossible<Ok, Error> { + void: Void, + ok: PhantomData<Ok>, + error: PhantomData<Error>, +} + +enum Void {} + +impl<Ok, Error> SerializeSeq for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} + +impl<Ok, Error> SerializeTuple for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} + +impl<Ok, Error> SerializeTupleStruct for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} + +impl<Ok, Error> SerializeTupleVariant for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} + +impl<Ok, Error> SerializeMap for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = key; + match self.void {} + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} + +impl<Ok, Error> SerializeStruct for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = key; + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} + +impl<Ok, Error> SerializeStructVariant for Impossible<Ok, Error> +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: Serialize, + { + let _ = key; + let _ = value; + match self.void {} + } + + fn end(self) -> Result<Ok, Error> { + match self.void {} + } +} diff --git a/third_party/rust/serde/src/ser/mod.rs b/third_party/rust/serde/src/ser/mod.rs new file mode 100644 index 0000000000..8a4b2e3669 --- /dev/null +++ b/third_party/rust/serde/src/ser/mod.rs @@ -0,0 +1,1964 @@ +//! Generic data structure serialization framework. +//! +//! The two most important traits in this module are [`Serialize`] and +//! [`Serializer`]. +//! +//! - **A type that implements `Serialize` is a data structure** that can be +//! serialized to any data format supported by Serde, and conversely +//! - **A type that implements `Serializer` is a data format** that can +//! serialize any data structure supported by Serde. +//! +//! # The Serialize trait +//! +//! Serde provides [`Serialize`] implementations for many Rust primitive and +//! standard library types. The complete list is below. All of these can be +//! serialized using Serde out of the box. +//! +//! Additionally, Serde provides a procedural macro called [`serde_derive`] to +//! automatically generate [`Serialize`] implementations for structs and enums +//! in your program. See the [derive section of the manual] for how to use this. +//! +//! In rare cases it may be necessary to implement [`Serialize`] manually for +//! some type in your program. See the [Implementing `Serialize`] section of the +//! manual for more about this. +//! +//! Third-party crates may provide [`Serialize`] implementations for types that +//! they expose. For example the [`linked-hash-map`] crate provides a +//! [`LinkedHashMap<K, V>`] type that is serializable by Serde because the crate +//! provides an implementation of [`Serialize`] for it. +//! +//! # The Serializer trait +//! +//! [`Serializer`] implementations are provided by third-party crates, for +//! example [`serde_json`], [`serde_yaml`] and [`bincode`]. +//! +//! A partial list of well-maintained formats is given on the [Serde +//! website][data formats]. +//! +//! # Implementations of Serialize provided by Serde +//! +//! - **Primitive types**: +//! - bool +//! - i8, i16, i32, i64, i128, isize +//! - u8, u16, u32, u64, u128, usize +//! - f32, f64 +//! - char +//! - str +//! - &T and &mut T +//! - **Compound types**: +//! - \[T\] +//! - \[T; 0\] through \[T; 32\] +//! - tuples up to size 16 +//! - **Common standard library types**: +//! - String +//! - Option\<T\> +//! - Result\<T, E\> +//! - PhantomData\<T\> +//! - **Wrapper types**: +//! - Box\<T\> +//! - Cow\<'a, T\> +//! - Cell\<T\> +//! - RefCell\<T\> +//! - Mutex\<T\> +//! - RwLock\<T\> +//! - Rc\<T\> *(if* features = ["rc"] *is enabled)* +//! - Arc\<T\> *(if* features = ["rc"] *is enabled)* +//! - **Collection types**: +//! - BTreeMap\<K, V\> +//! - BTreeSet\<T\> +//! - BinaryHeap\<T\> +//! - HashMap\<K, V, H\> +//! - HashSet\<T, H\> +//! - LinkedList\<T\> +//! - VecDeque\<T\> +//! - Vec\<T\> +//! - **FFI types**: +//! - CStr +//! - CString +//! - OsStr +//! - OsString +//! - **Miscellaneous standard library types**: +//! - Duration +//! - SystemTime +//! - Path +//! - PathBuf +//! - Range\<T\> +//! - RangeInclusive\<T\> +//! - Bound\<T\> +//! - num::NonZero* +//! - `!` *(unstable)* +//! - **Net types**: +//! - IpAddr +//! - Ipv4Addr +//! - Ipv6Addr +//! - SocketAddr +//! - SocketAddrV4 +//! - SocketAddrV6 +//! +//! [Implementing `Serialize`]: https://serde.rs/impl-serialize.html +//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +//! [`Serialize`]: ../trait.Serialize.html +//! [`Serializer`]: ../trait.Serializer.html +//! [`bincode`]: https://github.com/servo/bincode +//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +//! [`serde_derive`]: https://crates.io/crates/serde_derive +//! [`serde_json`]: https://github.com/serde-rs/json +//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml +//! [derive section of the manual]: https://serde.rs/derive.html +//! [data formats]: https://serde.rs/#data-formats + +use lib::*; + +mod fmt; +mod impls; +mod impossible; + +pub use self::impossible::Impossible; + +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use std::error::Error as StdError; +#[cfg(not(feature = "std"))] +#[doc(no_inline)] +pub use std_error::Error as StdError; + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! declare_error_trait { + (Error: Sized $(+ $($supertrait:ident)::+)*) => { + /// Trait used by `Serialize` implementations to generically construct + /// errors belonging to the `Serializer` against which they are + /// currently running. + /// + /// # Example implementation + /// + /// The [example data format] presented on the website shows an error + /// type appropriate for a basic JSON data format. + /// + /// [example data format]: https://serde.rs/data-format.html + pub trait Error: Sized $(+ $($supertrait)::+)* { + /// Used when a [`Serialize`] implementation encounters any error + /// while serializing a type. + /// + /// The message should not be capitalized and should not end with a + /// period. + /// + /// For example, a filesystem [`Path`] may refuse to serialize + /// itself if it contains invalid UTF-8 data. + /// + /// ```edition2018 + /// # struct Path; + /// # + /// # impl Path { + /// # fn to_str(&self) -> Option<&str> { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{self, Serialize, Serializer}; + /// + /// impl Serialize for Path { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match self.to_str() { + /// Some(s) => serializer.serialize_str(s), + /// None => Err(ser::Error::custom("path contains invalid UTF-8 characters")), + /// } + /// } + /// } + /// ``` + /// + /// [`Path`]: https://doc.rust-lang.org/std/path/struct.Path.html + /// [`Serialize`]: ../trait.Serialize.html + fn custom<T>(msg: T) -> Self + where + T: Display; + } + } +} + +#[cfg(feature = "std")] +declare_error_trait!(Error: Sized + StdError); + +#[cfg(not(feature = "std"))] +declare_error_trait!(Error: Sized + Debug + Display); + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data structure** that can be serialized into any data format supported +/// by Serde. +/// +/// Serde provides `Serialize` implementations for many Rust primitive and +/// standard library types. The complete list is [here][ser]. All of these can +/// be serialized using Serde out of the box. +/// +/// Additionally, Serde provides a procedural macro called [`serde_derive`] to +/// automatically generate `Serialize` implementations for structs and enums in +/// your program. See the [derive section of the manual] for how to use this. +/// +/// In rare cases it may be necessary to implement `Serialize` manually for some +/// type in your program. See the [Implementing `Serialize`] section of the +/// manual for more about this. +/// +/// Third-party crates may provide `Serialize` implementations for types that +/// they expose. For example the [`linked-hash-map`] crate provides a +/// [`LinkedHashMap<K, V>`] type that is serializable by Serde because the crate +/// provides an implementation of `Serialize` for it. +/// +/// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html +/// [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +/// [`serde_derive`]: https://crates.io/crates/serde_derive +/// [derive section of the manual]: https://serde.rs/derive.html +/// [ser]: https://docs.serde.rs/serde/ser/index.html +pub trait Serialize { + /// Serialize this value into the given Serde serializer. + /// + /// See the [Implementing `Serialize`] section of the manual for more + /// information about how to implement this method. + /// + /// ```edition2018 + /// use serde::ser::{Serialize, SerializeStruct, Serializer}; + /// + /// struct Person { + /// name: String, + /// age: u8, + /// phones: Vec<String>, + /// } + /// + /// // This is what #[derive(Serialize)] would generate. + /// impl Serialize for Person { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut s = serializer.serialize_struct("Person", 3)?; + /// s.serialize_field("name", &self.name)?; + /// s.serialize_field("age", &self.age)?; + /// s.serialize_field("phones", &self.phones)?; + /// s.end() + /// } + /// } + /// ``` + /// + /// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data format** that can serialize any data structure supported by Serde. +/// +/// The role of this trait is to define the serialization half of the [Serde +/// data model], which is a way to categorize every Rust data structure into one +/// of 29 possible types. Each method of the `Serializer` trait corresponds to +/// one of the types of the data model. +/// +/// Implementations of `Serialize` map themselves into this data model by +/// invoking exactly one of the `Serializer` methods. +/// +/// The types that make up the Serde data model are: +/// +/// - **14 primitive types** +/// - bool +/// - i8, i16, i32, i64, i128 +/// - u8, u16, u32, u64, u128 +/// - f32, f64 +/// - char +/// - **string** +/// - UTF-8 bytes with a length and no null terminator. +/// - When serializing, all strings are handled equally. When deserializing, +/// there are three flavors of strings: transient, owned, and borrowed. +/// - **byte array** - \[u8\] +/// - Similar to strings, during deserialization byte arrays can be +/// transient, owned, or borrowed. +/// - **option** +/// - Either none or some value. +/// - **unit** +/// - The type of `()` in Rust. It represents an anonymous value containing +/// no data. +/// - **unit_struct** +/// - For example `struct Unit` or `PhantomData<T>`. It represents a named +/// value containing no data. +/// - **unit_variant** +/// - For example the `E::A` and `E::B` in `enum E { A, B }`. +/// - **newtype_struct** +/// - For example `struct Millimeters(u8)`. +/// - **newtype_variant** +/// - For example the `E::N` in `enum E { N(u8) }`. +/// - **seq** +/// - A variably sized heterogeneous sequence of values, for example +/// `Vec<T>` or `HashSet<T>`. When serializing, the length may or may not +/// be known before iterating through all the data. When deserializing, +/// the length is determined by looking at the serialized data. +/// - **tuple** +/// - A statically sized heterogeneous sequence of values for which the +/// length will be known at deserialization time without looking at the +/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or +/// `[u64; 10]`. +/// - **tuple_struct** +/// - A named tuple, for example `struct Rgb(u8, u8, u8)`. +/// - **tuple_variant** +/// - For example the `E::T` in `enum E { T(u8, u8) }`. +/// - **map** +/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`. +/// - **struct** +/// - A heterogeneous key-value pairing in which the keys are strings and +/// will be known at deserialization time without looking at the +/// serialized data, for example `struct S { r: u8, g: u8, b: u8 }`. +/// - **struct_variant** +/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. +/// +/// Many Serde serializers produce text or binary data as output, for example +/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and +/// there are serializers that do not produce text or binary output. One example +/// is the `serde_json::value::Serializer` (distinct from the main `serde_json` +/// serializer) that produces a `serde_json::Value` data structure in memory as +/// output. +/// +/// [Serde data model]: https://serde.rs/data-model.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website contains example code for +/// a basic JSON `Serializer`. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait Serializer: Sized { + /// The output type produced by this `Serializer` during successful + /// serialization. Most serializers that produce text or binary output + /// should set `Ok = ()` and serialize into an [`io::Write`] or buffer + /// contained within the `Serializer` instance. Serializers that build + /// in-memory data structures may be simplified by using `Ok` to propagate + /// the data structure around. + /// + /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html + type Ok; + + /// The error type when some error occurs during serialization. + type Error: Error; + + /// Type returned from [`serialize_seq`] for serializing the content of the + /// sequence. + /// + /// [`serialize_seq`]: #tymethod.serialize_seq + type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>; + + /// Type returned from [`serialize_tuple`] for serializing the content of + /// the tuple. + /// + /// [`serialize_tuple`]: #tymethod.serialize_tuple + type SerializeTuple: SerializeTuple<Ok = Self::Ok, Error = Self::Error>; + + /// Type returned from [`serialize_tuple_struct`] for serializing the + /// content of the tuple struct. + /// + /// [`serialize_tuple_struct`]: #tymethod.serialize_tuple_struct + type SerializeTupleStruct: SerializeTupleStruct<Ok = Self::Ok, Error = Self::Error>; + + /// Type returned from [`serialize_tuple_variant`] for serializing the + /// content of the tuple variant. + /// + /// [`serialize_tuple_variant`]: #tymethod.serialize_tuple_variant + type SerializeTupleVariant: SerializeTupleVariant<Ok = Self::Ok, Error = Self::Error>; + + /// Type returned from [`serialize_map`] for serializing the content of the + /// map. + /// + /// [`serialize_map`]: #tymethod.serialize_map + type SerializeMap: SerializeMap<Ok = Self::Ok, Error = Self::Error>; + + /// Type returned from [`serialize_struct`] for serializing the content of + /// the struct. + /// + /// [`serialize_struct`]: #tymethod.serialize_struct + type SerializeStruct: SerializeStruct<Ok = Self::Ok, Error = Self::Error>; + + /// Type returned from [`serialize_struct_variant`] for serializing the + /// content of the struct variant. + /// + /// [`serialize_struct_variant`]: #tymethod.serialize_struct_variant + type SerializeStructVariant: SerializeStructVariant<Ok = Self::Ok, Error = Self::Error>; + + /// Serialize a `bool` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for bool { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_bool(*self) + /// } + /// } + /// ``` + fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>; + + /// Serialize an `i8` value. + /// + /// If the format does not differentiate between `i8` and `i64`, a + /// reasonable implementation would be to cast the value to `i64` and + /// forward to `serialize_i64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i8 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i8(*self) + /// } + /// } + /// ``` + fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>; + + /// Serialize an `i16` value. + /// + /// If the format does not differentiate between `i16` and `i64`, a + /// reasonable implementation would be to cast the value to `i64` and + /// forward to `serialize_i64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i16 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i16(*self) + /// } + /// } + /// ``` + fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>; + + /// Serialize an `i32` value. + /// + /// If the format does not differentiate between `i32` and `i64`, a + /// reasonable implementation would be to cast the value to `i64` and + /// forward to `serialize_i64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i32 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i32(*self) + /// } + /// } + /// ``` + fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>; + + /// Serialize an `i64` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i64 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i64(*self) + /// } + /// } + /// ``` + fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>; + + serde_if_integer128! { + /// Serialize an `i128` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i128 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i128(*self) + /// } + /// } + /// ``` + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> { + let _ = v; + Err(Error::custom("i128 is not supported")) + } + } + + /// Serialize a `u8` value. + /// + /// If the format does not differentiate between `u8` and `u64`, a + /// reasonable implementation would be to cast the value to `u64` and + /// forward to `serialize_u64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u8 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u8(*self) + /// } + /// } + /// ``` + fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>; + + /// Serialize a `u16` value. + /// + /// If the format does not differentiate between `u16` and `u64`, a + /// reasonable implementation would be to cast the value to `u64` and + /// forward to `serialize_u64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u16 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u16(*self) + /// } + /// } + /// ``` + fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>; + + /// Serialize a `u32` value. + /// + /// If the format does not differentiate between `u32` and `u64`, a + /// reasonable implementation would be to cast the value to `u64` and + /// forward to `serialize_u64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u32 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u32(*self) + /// } + /// } + /// ``` + fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>; + + /// Serialize a `u64` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u64 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u64(*self) + /// } + /// } + /// ``` + fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>; + + serde_if_integer128! { + /// Serialize a `u128` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u128 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u128(*self) + /// } + /// } + /// ``` + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> { + let _ = v; + Err(Error::custom("u128 is not supported")) + } + } + + /// Serialize an `f32` value. + /// + /// If the format does not differentiate between `f32` and `f64`, a + /// reasonable implementation would be to cast the value to `f64` and + /// forward to `serialize_f64`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for f32 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_f32(*self) + /// } + /// } + /// ``` + fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>; + + /// Serialize an `f64` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for f64 { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_f64(*self) + /// } + /// } + /// ``` + fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>; + + /// Serialize a character. + /// + /// If the format does not support characters, it is reasonable to serialize + /// it as a single element `str` or a `u32`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for char { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_char(*self) + /// } + /// } + /// ``` + fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>; + + /// Serialize a `&str`. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for str { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_str(self) + /// } + /// } + /// ``` + fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>; + + /// Serialize a chunk of raw byte data. + /// + /// Enables serializers to serialize byte slices more compactly or more + /// efficiently than other types of slices. If no efficient implementation + /// is available, a reasonable implementation would be to forward to + /// `serialize_seq`. If forwarded, the implementation looks usually just + /// like this: + /// + /// ```edition2018 + /// # use serde::ser::{Serializer, SerializeSeq}; + /// # use serde::private::ser::Error; + /// # + /// # struct MySerializer; + /// # + /// # impl Serializer for MySerializer { + /// # type Ok = (); + /// # type Error = Error; + /// # + /// fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> { + /// let mut seq = self.serialize_seq(Some(v.len()))?; + /// for b in v { + /// seq.serialize_element(b)?; + /// } + /// seq.end() + /// } + /// # + /// # serde::__serialize_unimplemented! { + /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some + /// # unit unit_struct unit_variant newtype_struct newtype_variant + /// # seq tuple tuple_struct tuple_variant map struct struct_variant + /// # } + /// # } + /// ``` + fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error>; + + /// Serialize a [`None`] value. + /// + /// ```edition2018 + /// # use serde::{Serialize, Serializer}; + /// # + /// # enum Option<T> { + /// # Some(T), + /// # None, + /// # } + /// # + /// # use self::Option::{Some, None}; + /// # + /// impl<T> Serialize for Option<T> + /// where + /// T: Serialize, + /// { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match *self { + /// Some(ref value) => serializer.serialize_some(value), + /// None => serializer.serialize_none(), + /// } + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None + fn serialize_none(self) -> Result<Self::Ok, Self::Error>; + + /// Serialize a [`Some(T)`] value. + /// + /// ```edition2018 + /// # use serde::{Serialize, Serializer}; + /// # + /// # enum Option<T> { + /// # Some(T), + /// # None, + /// # } + /// # + /// # use self::Option::{Some, None}; + /// # + /// impl<T> Serialize for Option<T> + /// where + /// T: Serialize, + /// { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match *self { + /// Some(ref value) => serializer.serialize_some(value), + /// None => serializer.serialize_none(), + /// } + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// [`Some(T)`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: Serialize; + + /// Serialize a `()` value. + /// + /// ```edition2018 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for () { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_unit() + /// } + /// } + /// ``` + fn serialize_unit(self) -> Result<Self::Ok, Self::Error>; + + /// Serialize a unit struct like `struct Unit` or `PhantomData<T>`. + /// + /// A reasonable implementation would be to forward to `serialize_unit`. + /// + /// ```edition2018 + /// use serde::{Serialize, Serializer}; + /// + /// struct Nothing; + /// + /// impl Serialize for Nothing { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_unit_struct("Nothing") + /// } + /// } + /// ``` + fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error>; + + /// Serialize a unit variant like `E::A` in `enum E { A, B }`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, and the `variant` is the name of the + /// variant. + /// + /// ```edition2018 + /// use serde::{Serialize, Serializer}; + /// + /// enum E { + /// A, + /// B, + /// } + /// + /// impl Serialize for E { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::A => serializer.serialize_unit_variant("E", 0, "A"), + /// E::B => serializer.serialize_unit_variant("E", 1, "B"), + /// } + /// } + /// } + /// ``` + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result<Self::Ok, Self::Error>; + + /// Serialize a newtype struct like `struct Millimeters(u8)`. + /// + /// Serializers are encouraged to treat newtype structs as insignificant + /// wrappers around the data they contain. A reasonable implementation would + /// be to forward to `value.serialize(self)`. + /// + /// ```edition2018 + /// use serde::{Serialize, Serializer}; + /// + /// struct Millimeters(u8); + /// + /// impl Serialize for Millimeters { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.serialize_newtype_struct("Millimeters", &self.0) + /// } + /// } + /// ``` + fn serialize_newtype_struct<T: ?Sized>( + self, + name: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize; + + /// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, and the `variant` is the name of the + /// variant. The `value` is the data contained within this newtype variant. + /// + /// ```edition2018 + /// use serde::{Serialize, Serializer}; + /// + /// enum E { + /// M(String), + /// N(u8), + /// } + /// + /// impl Serialize for E { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s), + /// E::N(n) => serializer.serialize_newtype_variant("E", 1, "N", &n), + /// } + /// } + /// } + /// ``` + fn serialize_newtype_variant<T: ?Sized>( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize; + + /// Begin to serialize a variably sized sequence. This call must be + /// followed by zero or more calls to `serialize_element`, then a call to + /// `end`. + /// + /// The argument is the number of elements in the sequence, which may or may + /// not be computable before the sequence is iterated. Some serializers only + /// support sequences whose length is known up front. + /// + /// ```edition2018 + /// # use std::marker::PhantomData; + /// # + /// # struct Vec<T>(PhantomData<T>); + /// # + /// # impl<T> Vec<T> { + /// # fn len(&self) -> usize { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl<'a, T> IntoIterator for &'a Vec<T> { + /// # type Item = &'a T; + /// # type IntoIter = Box<Iterator<Item = &'a T>>; + /// # + /// # fn into_iter(self) -> Self::IntoIter { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{Serialize, Serializer, SerializeSeq}; + /// + /// impl<T> Serialize for Vec<T> + /// where + /// T: Serialize, + /// { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut seq = serializer.serialize_seq(Some(self.len()))?; + /// for element in self { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } + /// } + /// ``` + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error>; + + /// Begin to serialize a statically sized sequence whose length will be + /// known at deserialization time without looking at the serialized data. + /// This call must be followed by zero or more calls to `serialize_element`, + /// then a call to `end`. + /// + /// ```edition2018 + /// use serde::ser::{Serialize, Serializer, SerializeTuple}; + /// + /// # mod fool { + /// # trait Serialize {} + /// impl<A, B, C> Serialize for (A, B, C) + /// # {} + /// # } + /// # + /// # struct Tuple3<A, B, C>(A, B, C); + /// # + /// # impl<A, B, C> Serialize for Tuple3<A, B, C> + /// where + /// A: Serialize, + /// B: Serialize, + /// C: Serialize, + /// { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut tup = serializer.serialize_tuple(3)?; + /// tup.serialize_element(&self.0)?; + /// tup.serialize_element(&self.1)?; + /// tup.serialize_element(&self.2)?; + /// tup.end() + /// } + /// } + /// ``` + /// + /// ```edition2018 + /// use serde::ser::{Serialize, SerializeTuple, Serializer}; + /// + /// const VRAM_SIZE: usize = 386; + /// struct Vram([u16; VRAM_SIZE]); + /// + /// impl Serialize for Vram { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?; + /// for element in &self.0[..] { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } + /// } + /// ``` + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error>; + + /// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This + /// call must be followed by zero or more calls to `serialize_field`, then a + /// call to `end`. + /// + /// The `name` is the name of the tuple struct and the `len` is the number + /// of data fields that will be serialized. + /// + /// ```edition2018 + /// use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; + /// + /// struct Rgb(u8, u8, u8); + /// + /// impl Serialize for Rgb { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; + /// ts.serialize_field(&self.0)?; + /// ts.serialize_field(&self.1)?; + /// ts.serialize_field(&self.2)?; + /// ts.end() + /// } + /// } + /// ``` + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error>; + + /// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8) + /// }`. This call must be followed by zero or more calls to + /// `serialize_field`, then a call to `end`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, the `variant` is the name of the variant, + /// and the `len` is the number of data fields that will be serialized. + /// + /// ```edition2018 + /// use serde::ser::{Serialize, SerializeTupleVariant, Serializer}; + /// + /// enum E { + /// T(u8, u8), + /// U(String, u32, u32), + /// } + /// + /// impl Serialize for E { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::T(ref a, ref b) => { + /// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; + /// tv.serialize_field(a)?; + /// tv.serialize_field(b)?; + /// tv.end() + /// } + /// E::U(ref a, ref b, ref c) => { + /// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?; + /// tv.serialize_field(a)?; + /// tv.serialize_field(b)?; + /// tv.serialize_field(c)?; + /// tv.end() + /// } + /// } + /// } + /// } + /// ``` + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error>; + + /// Begin to serialize a map. This call must be followed by zero or more + /// calls to `serialize_key` and `serialize_value`, then a call to `end`. + /// + /// The argument is the number of elements in the map, which may or may not + /// be computable before the map is iterated. Some serializers only support + /// maps whose length is known up front. + /// + /// ```edition2018 + /// # use std::marker::PhantomData; + /// # + /// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>); + /// # + /// # impl<K, V> HashMap<K, V> { + /// # fn len(&self) -> usize { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl<'a, K, V> IntoIterator for &'a HashMap<K, V> { + /// # type Item = (&'a K, &'a V); + /// # type IntoIter = Box<Iterator<Item = (&'a K, &'a V)>>; + /// # + /// # fn into_iter(self) -> Self::IntoIter { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{Serialize, Serializer, SerializeMap}; + /// + /// impl<K, V> Serialize for HashMap<K, V> + /// where + /// K: Serialize, + /// V: Serialize, + /// { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut map = serializer.serialize_map(Some(self.len()))?; + /// for (k, v) in self { + /// map.serialize_entry(k, v)?; + /// } + /// map.end() + /// } + /// } + /// ``` + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error>; + + /// Begin to serialize a struct like `struct Rgb { r: u8, g: u8, b: u8 }`. + /// This call must be followed by zero or more calls to `serialize_field`, + /// then a call to `end`. + /// + /// The `name` is the name of the struct and the `len` is the number of + /// data fields that will be serialized. + /// + /// ```edition2018 + /// use serde::ser::{Serialize, SerializeStruct, Serializer}; + /// + /// struct Rgb { + /// r: u8, + /// g: u8, + /// b: u8, + /// } + /// + /// impl Serialize for Rgb { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// let mut rgb = serializer.serialize_struct("Rgb", 3)?; + /// rgb.serialize_field("r", &self.r)?; + /// rgb.serialize_field("g", &self.g)?; + /// rgb.serialize_field("b", &self.b)?; + /// rgb.end() + /// } + /// } + /// ``` + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, Self::Error>; + + /// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8, + /// g: u8, b: u8 } }`. This call must be followed by zero or more calls to + /// `serialize_field`, then a call to `end`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, the `variant` is the name of the variant, + /// and the `len` is the number of data fields that will be serialized. + /// + /// ```edition2018 + /// use serde::ser::{Serialize, SerializeStructVariant, Serializer}; + /// + /// enum E { + /// S { r: u8, g: u8, b: u8 }, + /// } + /// + /// impl Serialize for E { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::S { + /// ref r, + /// ref g, + /// ref b, + /// } => { + /// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; + /// sv.serialize_field("r", r)?; + /// sv.serialize_field("g", g)?; + /// sv.serialize_field("b", b)?; + /// sv.end() + /// } + /// } + /// } + /// } + /// ``` + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error>; + + /// Collect an iterator as a sequence. + /// + /// The default implementation serializes each item yielded by the iterator + /// using [`serialize_seq`]. Implementors should not need to override this + /// method. + /// + /// ```edition2018 + /// use serde::{Serialize, Serializer}; + /// + /// struct SecretlyOneHigher { + /// data: Vec<i32>, + /// } + /// + /// impl Serialize for SecretlyOneHigher { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.collect_seq(self.data.iter().map(|x| x + 1)) + /// } + /// } + /// ``` + /// + /// [`serialize_seq`]: #tymethod.serialize_seq + fn collect_seq<I>(self, iter: I) -> Result<Self::Ok, Self::Error> + where + I: IntoIterator, + <I as IntoIterator>::Item: Serialize, + { + let iter = iter.into_iter(); + let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter))); + for item in iter { + try!(serializer.serialize_element(&item)); + } + serializer.end() + } + + /// Collect an iterator as a map. + /// + /// The default implementation serializes each pair yielded by the iterator + /// using [`serialize_map`]. Implementors should not need to override this + /// method. + /// + /// ```edition2018 + /// use serde::{Serialize, Serializer}; + /// use std::collections::BTreeSet; + /// + /// struct MapToUnit { + /// keys: BTreeSet<i32>, + /// } + /// + /// // Serializes as a map in which the values are all unit. + /// impl Serialize for MapToUnit { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.collect_map(self.keys.iter().map(|k| (k, ()))) + /// } + /// } + /// ``` + /// + /// [`serialize_map`]: #tymethod.serialize_map + fn collect_map<K, V, I>(self, iter: I) -> Result<Self::Ok, Self::Error> + where + K: Serialize, + V: Serialize, + I: IntoIterator<Item = (K, V)>, + { + let iter = iter.into_iter(); + let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter))); + for (key, value) in iter { + try!(serializer.serialize_entry(&key, &value)); + } + serializer.end() + } + + /// Serialize a string produced by an implementation of `Display`. + /// + /// The default implementation builds a heap-allocated [`String`] and + /// delegates to [`serialize_str`]. Serializers are encouraged to provide a + /// more efficient implementation if possible. + /// + /// ```edition2018 + /// # struct DateTime; + /// # + /// # impl DateTime { + /// # fn naive_local(&self) -> () { () } + /// # fn offset(&self) -> () { () } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// + /// impl Serialize for DateTime { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.collect_str(&format_args!("{:?}{:?}", + /// self.naive_local(), + /// self.offset())) + /// } + /// } + /// ``` + /// + /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html + /// [`serialize_str`]: #tymethod.serialize_str + #[cfg(any(feature = "std", feature = "alloc"))] + fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: Display, + { + self.serialize_str(&value.to_string()) + } + + /// Serialize a string produced by an implementation of `Display`. + /// + /// Serializers that use `no_std` are required to provide an implementation + /// of this method. If no more sensible behavior is possible, the + /// implementation is expected to return an error. + /// + /// ```edition2018 + /// # struct DateTime; + /// # + /// # impl DateTime { + /// # fn naive_local(&self) -> () { () } + /// # fn offset(&self) -> () { () } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// + /// impl Serialize for DateTime { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// serializer.collect_str(&format_args!("{:?}{:?}", + /// self.naive_local(), + /// self.offset())) + /// } + /// } + /// ``` + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: Display; + + /// Determine whether `Serialize` implementations should serialize in + /// human-readable form. + /// + /// Some types have a human-readable form that may be somewhat expensive to + /// construct, as well as a binary form that is compact and efficient. + /// Generally text-based formats like JSON and YAML will prefer to use the + /// human-readable one and binary formats like Bincode will prefer the + /// compact one. + /// + /// ```edition2018 + /// # use std::fmt::{self, Display}; + /// # + /// # struct Timestamp; + /// # + /// # impl Timestamp { + /// # fn seconds_since_epoch(&self) -> u64 { unimplemented!() } + /// # } + /// # + /// # impl Display for Timestamp { + /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// + /// impl Serialize for Timestamp { + /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + /// where + /// S: Serializer, + /// { + /// if serializer.is_human_readable() { + /// // Serialize to a human-readable string "2015-05-15T17:01:00Z". + /// self.to_string().serialize(serializer) + /// } else { + /// // Serialize to a compact binary representation. + /// self.seconds_since_epoch().serialize(serializer) + /// } + /// } + /// } + /// ``` + /// + /// The default implementation of this method returns `true`. Data formats + /// may override this to `false` to request a compact form for types that + /// support one. Note that modifying this method to change a format from + /// human-readable to compact or vice versa should be regarded as a breaking + /// change, as a value serialized in human-readable mode is not required to + /// deserialize from the same data in compact mode. + #[inline] + fn is_human_readable(&self) -> bool { + true + } +} + +/// Returned from `Serializer::serialize_seq`. +/// +/// # Example use +/// +/// ```edition2018 +/// # use std::marker::PhantomData; +/// # +/// # struct Vec<T>(PhantomData<T>); +/// # +/// # impl<T> Vec<T> { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, T> IntoIterator for &'a Vec<T> { +/// # type Item = &'a T; +/// # type IntoIter = Box<Iterator<Item = &'a T>>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, Serializer, SerializeSeq}; +/// +/// impl<T> Serialize for Vec<T> +/// where +/// T: Serialize, +/// { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// let mut seq = serializer.serialize_seq(Some(self.len()))?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeSeq` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeSeq { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a sequence element. + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; + + /// Finish serializing a sequence. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +/// Returned from `Serializer::serialize_tuple`. +/// +/// # Example use +/// +/// ```edition2018 +/// use serde::ser::{Serialize, Serializer, SerializeTuple}; +/// +/// # mod fool { +/// # trait Serialize {} +/// impl<A, B, C> Serialize for (A, B, C) +/// # {} +/// # } +/// # +/// # struct Tuple3<A, B, C>(A, B, C); +/// # +/// # impl<A, B, C> Serialize for Tuple3<A, B, C> +/// where +/// A: Serialize, +/// B: Serialize, +/// C: Serialize, +/// { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// let mut tup = serializer.serialize_tuple(3)?; +/// tup.serialize_element(&self.0)?; +/// tup.serialize_element(&self.1)?; +/// tup.serialize_element(&self.2)?; +/// tup.end() +/// } +/// } +/// ``` +/// +/// ```edition2018 +/// # use std::marker::PhantomData; +/// # +/// # struct Array<T>(PhantomData<T>); +/// # +/// # impl<T> Array<T> { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, T> IntoIterator for &'a Array<T> { +/// # type Item = &'a T; +/// # type IntoIter = Box<Iterator<Item = &'a T>>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, Serializer, SerializeTuple}; +/// +/// # mod fool { +/// # trait Serialize {} +/// impl<T> Serialize for [T; 16] +/// # {} +/// # } +/// # +/// # impl<T> Serialize for Array<T> +/// where +/// T: Serialize, +/// { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// let mut seq = serializer.serialize_tuple(16)?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeTuple` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeTuple { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a tuple element. + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; + + /// Finish serializing a tuple. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +/// Returned from `Serializer::serialize_tuple_struct`. +/// +/// # Example use +/// +/// ```edition2018 +/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; +/// +/// struct Rgb(u8, u8, u8); +/// +/// impl Serialize for Rgb { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; +/// ts.serialize_field(&self.0)?; +/// ts.serialize_field(&self.1)?; +/// ts.serialize_field(&self.2)?; +/// ts.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeTupleStruct` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeTupleStruct { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a tuple struct field. + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; + + /// Finish serializing a tuple struct. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +/// Returned from `Serializer::serialize_tuple_variant`. +/// +/// # Example use +/// +/// ```edition2018 +/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer}; +/// +/// enum E { +/// T(u8, u8), +/// U(String, u32, u32), +/// } +/// +/// impl Serialize for E { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// match *self { +/// E::T(ref a, ref b) => { +/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; +/// tv.serialize_field(a)?; +/// tv.serialize_field(b)?; +/// tv.end() +/// } +/// E::U(ref a, ref b, ref c) => { +/// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?; +/// tv.serialize_field(a)?; +/// tv.serialize_field(b)?; +/// tv.serialize_field(c)?; +/// tv.end() +/// } +/// } +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeTupleVariant` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeTupleVariant { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a tuple variant field. + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; + + /// Finish serializing a tuple variant. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +/// Returned from `Serializer::serialize_map`. +/// +/// # Example use +/// +/// ```edition2018 +/// # use std::marker::PhantomData; +/// # +/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>); +/// # +/// # impl<K, V> HashMap<K, V> { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, K, V> IntoIterator for &'a HashMap<K, V> { +/// # type Item = (&'a K, &'a V); +/// # type IntoIter = Box<Iterator<Item = (&'a K, &'a V)>>; +/// # +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, Serializer, SerializeMap}; +/// +/// impl<K, V> Serialize for HashMap<K, V> +/// where +/// K: Serialize, +/// V: Serialize, +/// { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// let mut map = serializer.serialize_map(Some(self.len()))?; +/// for (k, v) in self { +/// map.serialize_entry(k, v)?; +/// } +/// map.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeMap` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeMap { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a map key. + /// + /// If possible, `Serialize` implementations are encouraged to use + /// `serialize_entry` instead as it may be implemented more efficiently in + /// some formats compared to a pair of calls to `serialize_key` and + /// `serialize_value`. + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> + where + T: Serialize; + + /// Serialize a map value. + /// + /// # Panics + /// + /// Calling `serialize_value` before `serialize_key` is incorrect and is + /// allowed to panic or produce bogus results. + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; + + /// Serialize a map entry consisting of a key and a value. + /// + /// Some [`Serialize`] types are not able to hold a key and value in memory + /// at the same time so `SerializeMap` implementations are required to + /// support [`serialize_key`] and [`serialize_value`] individually. The + /// `serialize_entry` method allows serializers to optimize for the case + /// where key and value are both available. [`Serialize`] implementations + /// are encouraged to use `serialize_entry` if possible. + /// + /// The default implementation delegates to [`serialize_key`] and + /// [`serialize_value`]. This is appropriate for serializers that do not + /// care about performance or are not able to optimize `serialize_entry` any + /// better than this. + /// + /// [`Serialize`]: ../trait.Serialize.html + /// [`serialize_key`]: #tymethod.serialize_key + /// [`serialize_value`]: #tymethod.serialize_value + fn serialize_entry<K: ?Sized, V: ?Sized>( + &mut self, + key: &K, + value: &V, + ) -> Result<(), Self::Error> + where + K: Serialize, + V: Serialize, + { + try!(self.serialize_key(key)); + self.serialize_value(value) + } + + /// Finish serializing a map. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +/// Returned from `Serializer::serialize_struct`. +/// +/// # Example use +/// +/// ```edition2018 +/// use serde::ser::{Serialize, SerializeStruct, Serializer}; +/// +/// struct Rgb { +/// r: u8, +/// g: u8, +/// b: u8, +/// } +/// +/// impl Serialize for Rgb { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// let mut rgb = serializer.serialize_struct("Rgb", 3)?; +/// rgb.serialize_field("r", &self.r)?; +/// rgb.serialize_field("g", &self.g)?; +/// rgb.serialize_field("b", &self.b)?; +/// rgb.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeStruct` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeStruct { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a struct field. + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize; + + /// Indicate that a struct field has been skipped. + #[inline] + fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { + let _ = key; + Ok(()) + } + + /// Finish serializing a struct. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +/// Returned from `Serializer::serialize_struct_variant`. +/// +/// # Example use +/// +/// ```edition2018 +/// use serde::ser::{Serialize, SerializeStructVariant, Serializer}; +/// +/// enum E { +/// S { r: u8, g: u8, b: u8 }, +/// } +/// +/// impl Serialize for E { +/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> +/// where +/// S: Serializer, +/// { +/// match *self { +/// E::S { +/// ref r, +/// ref g, +/// ref b, +/// } => { +/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; +/// sv.serialize_field("r", r)?; +/// sv.serialize_field("g", g)?; +/// sv.serialize_field("b", b)?; +/// sv.end() +/// } +/// } +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeStructVariant` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeStructVariant { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a struct variant field. + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize; + + /// Indicate that a struct variant field has been skipped. + #[inline] + fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { + let _ = key; + Ok(()) + } + + /// Finish serializing a struct variant. + fn end(self) -> Result<Self::Ok, Self::Error>; +} + +fn iterator_len_hint<I>(iter: &I) -> Option<usize> +where + I: Iterator, +{ + match iter.size_hint() { + (lo, Some(hi)) if lo == hi => Some(lo), + _ => None, + } +} diff --git a/third_party/rust/serde/src/std_error.rs b/third_party/rust/serde/src/std_error.rs new file mode 100644 index 0000000000..1055e0ffbc --- /dev/null +++ b/third_party/rust/serde/src/std_error.rs @@ -0,0 +1,48 @@ +use lib::{Debug, Display}; + +/// Either a re-export of std::error::Error or a new identical trait, depending +/// on whether Serde's "std" feature is enabled. +/// +/// Serde's error traits [`serde::ser::Error`] and [`serde::de::Error`] require +/// [`std::error::Error`] as a supertrait, but only when Serde is built with +/// "std" enabled. Data formats that don't care about no\_std support should +/// generally provide their error types with a `std::error::Error` impl +/// directly: +/// +/// ```edition2018 +/// #[derive(Debug)] +/// struct MySerError {...} +/// +/// impl serde::ser::Error for MySerError {...} +/// +/// impl std::fmt::Display for MySerError {...} +/// +/// // We don't support no_std! +/// impl std::error::Error for MySerError {} +/// ``` +/// +/// Data formats that *do* support no\_std may either have a "std" feature of +/// their own: +/// +/// ```toml +/// [features] +/// std = ["serde/std"] +/// ``` +/// +/// ```edition2018 +/// #[cfg(feature = "std")] +/// impl std::error::Error for MySerError {} +/// ``` +/// +/// ... or else provide the std Error impl unconditionally via Serde's +/// re-export: +/// +/// ```edition2018 +/// impl serde::ser::StdError for MySerError {} +/// ``` +pub trait Error: Debug + Display { + /// The underlying cause of this error, if any. + fn source(&self) -> Option<&(Error + 'static)> { + None + } +} diff --git a/third_party/rust/serde_bytes/.cargo-checksum.json b/third_party/rust/serde_bytes/.cargo-checksum.json new file mode 100644 index 0000000000..83be48fe04 --- /dev/null +++ b/third_party/rust/serde_bytes/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"1f9bd3cb6643159fef378bf69aadd77ab0b1db6daf8f00cafb3d2a27e9443f31","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"ce0f467822b4c8e7427ac10f16a20c26ab2d08a3ac8189a339534f0d116e30c2","src/bytebuf.rs":"a84bc2426fbbcde9d79a1845813fb88590b5b6745d428f6bbf7900954e93b84d","src/bytes.rs":"43ae3033f97e5bd8f8c7ddb2c6e59404e5058a26b1f2d63be0dd988c801a61a2","src/de.rs":"c3041e913c2cb08452adbbec1aa90b040fabc22348fce46a691c527b26832566","src/lib.rs":"baa98727761a560731540232814a4ad180223276b5a2e9767a5c2e808bf6d22a","src/ser.rs":"874eb1cdb82344b263989f3ae1cd06daab6b250d52a1e3abb46b0dccb69fb6ab","tests/test_derive.rs":"fc37391b7b5c81e6ffc7c079c01eb61e8091d49bd6a87c6c3b46d48c94288be6","tests/test_partialeq.rs":"9daa553dfc8a6dc40d88afbfb450d70bad51d90ff7f8df7b707847335b0ffe88","tests/test_serde.rs":"10c980110505d47c7b8a876dcb911154339aa52124b6f1de5636001bcf39b56d"},"package":"45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc"}
\ No newline at end of file diff --git a/third_party/rust/serde_bytes/Cargo.toml b/third_party/rust/serde_bytes/Cargo.toml new file mode 100644 index 0000000000..ca8207a21b --- /dev/null +++ b/third_party/rust/serde_bytes/Cargo.toml @@ -0,0 +1,42 @@ +# 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] +edition = "2018" +name = "serde_bytes" +version = "0.11.2" +authors = ["David Tolnay <dtolnay@gmail.com>"] +description = "Optimized handling of `&[u8]` and `Vec<u8>` for Serde" +documentation = "https://docs.serde.rs/serde_bytes/" +readme = "README.md" +keywords = ["serde", "serialization", "no_std"] +categories = ["encoding"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/serde-rs/bytes" +[dependencies.serde] +version = "1.0" +default-features = false +[dev-dependencies.bincode] +version = "1.0" + +[dev-dependencies.serde_derive] +version = "1.0" + +[dev-dependencies.serde_test] +version = "1.0" + +[features] +alloc = ["serde/alloc"] +default = ["std"] +std = ["serde/std"] +[badges.travis-ci] +repository = "serde-rs/bytes" diff --git a/third_party/rust/serde_bytes/LICENSE-APACHE b/third_party/rust/serde_bytes/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_bytes/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/serde_bytes/LICENSE-MIT b/third_party/rust/serde_bytes/LICENSE-MIT new file mode 100644 index 0000000000..39d4bdb5ac --- /dev/null +++ b/third_party/rust/serde_bytes/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_bytes/README.md b/third_party/rust/serde_bytes/README.md new file mode 100644 index 0000000000..8546e58525 --- /dev/null +++ b/third_party/rust/serde_bytes/README.md @@ -0,0 +1,54 @@ +# serde\_bytes [![Build Status](https://api.travis-ci.org/serde-rs/bytes.svg?branch=master)](https://travis-ci.org/serde-rs/bytes) [![Latest Version](https://img.shields.io/crates/v/serde_bytes.svg)](https://crates.io/crates/serde_bytes) + +Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`. + +```toml +[dependencies] +serde_bytes = "0.11" +``` + +## Explanation + +Without specialization, Rust forces Serde to treat `&[u8]` just like any +other slice and `Vec<u8>` just like any other vector. In reality this +particular slice and vector can often be serialized and deserialized in a +more efficient, compact representation in many formats. + +When working with such a format, you can opt into specialized handling of +`&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it +in `serde_bytes::ByteBuf`. + +Additionally this crate supports the Serde `with` attribute to enable efficient +handling of `&[u8]` and `Vec<u8>` in structs without needing a wrapper type. + +## Example + +```rust +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +struct Efficient<'a> { + #[serde(with = "serde_bytes")] + bytes: &'a [u8], + + #[serde(with = "serde_bytes")] + byte_buf: Vec<u8>, +} +``` + +<br> + +#### License + +<sup> +Licensed under either of <a href="LICENSE-APACHE">Apache License, Version +2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. +</sup> + +<br> + +<sub> +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. +</sub> diff --git a/third_party/rust/serde_bytes/src/bytebuf.rs b/third_party/rust/serde_bytes/src/bytebuf.rs new file mode 100644 index 0000000000..c3f158aaa3 --- /dev/null +++ b/third_party/rust/serde_bytes/src/bytebuf.rs @@ -0,0 +1,252 @@ +use core::borrow::{Borrow, BorrowMut}; +use core::cmp::{self, Ordering}; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; +use core::ops::{Deref, DerefMut}; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor}; +use serde::ser::{Serialize, Serializer}; + +use crate::Bytes; + +/// Wrapper around `Vec<u8>` to serialize and deserialize efficiently. +/// +/// ``` +/// use std::collections::HashMap; +/// use std::io; +/// +/// use serde_bytes::ByteBuf; +/// +/// fn deserialize_bytebufs() -> bincode::Result<()> { +/// let example_data = [ +/// 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116, +/// 119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101]; +/// +/// let map: HashMap<u32, ByteBuf> = bincode::deserialize(&example_data[..])?; +/// +/// println!("{:?}", map); +/// +/// Ok(()) +/// } +/// # +/// # fn main() { +/// # deserialize_bytebufs().unwrap(); +/// # } +/// ``` +#[derive(Clone, Default, Eq, Ord)] +pub struct ByteBuf { + bytes: Vec<u8>, +} + +impl ByteBuf { + /// Construct a new, empty `ByteBuf`. + pub fn new() -> Self { + ByteBuf::from(Vec::new()) + } + + /// Construct a new, empty `ByteBuf` with the specified capacity. + pub fn with_capacity(cap: usize) -> Self { + ByteBuf::from(Vec::with_capacity(cap)) + } + + /// Wrap existing bytes in a `ByteBuf`. + pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self { + ByteBuf { + bytes: bytes.into(), + } + } + + /// Unwrap the vector of byte underlying this `ByteBuf`. + pub fn into_vec(self) -> Vec<u8> { + self.bytes + } + + #[allow(missing_docs)] + pub fn into_boxed_bytes(self) -> Box<Bytes> { + self.bytes.into_boxed_slice().into() + } + + // This would hit "cannot move out of borrowed content" if invoked through + // the Deref impl; make it just work. + #[doc(hidden)] + pub fn into_boxed_slice(self) -> Box<[u8]> { + self.bytes.into_boxed_slice() + } + + #[doc(hidden)] + pub fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter { + self.bytes.into_iter() + } +} + +impl Debug for ByteBuf { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.bytes, f) + } +} + +impl AsRef<[u8]> for ByteBuf { + fn as_ref(&self) -> &[u8] { + &self.bytes + } +} + +impl AsMut<[u8]> for ByteBuf { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.bytes + } +} + +impl Deref for ByteBuf { + type Target = Vec<u8>; + + fn deref(&self) -> &Self::Target { + &self.bytes + } +} + +impl DerefMut for ByteBuf { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bytes + } +} + +impl Borrow<Bytes> for ByteBuf { + fn borrow(&self) -> &Bytes { + Bytes::new(&self.bytes) + } +} + +impl BorrowMut<Bytes> for ByteBuf { + fn borrow_mut(&mut self) -> &mut Bytes { + unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) } + } +} + +impl<Rhs> PartialEq<Rhs> for ByteBuf +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn eq(&self, other: &Rhs) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +impl<Rhs> PartialOrd<Rhs> for ByteBuf +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> { + self.as_ref().partial_cmp(other.as_ref()) + } +} + +impl Hash for ByteBuf { + fn hash<H: Hasher>(&self, state: &mut H) { + self.bytes.hash(state); + } +} + +impl IntoIterator for ByteBuf { + type Item = u8; + type IntoIter = <Vec<u8> as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.into_iter() + } +} + +impl<'a> IntoIterator for &'a ByteBuf { + type Item = &'a u8; + type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter() + } +} + +impl<'a> IntoIterator for &'a mut ByteBuf { + type Item = &'a mut u8; + type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter_mut() + } +} + +impl Serialize for ByteBuf { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(&self.bytes) + } +} + +struct ByteBufVisitor; + +impl<'de> Visitor<'de> for ByteBufVisitor { + type Value = ByteBuf; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error> + where + V: SeqAccess<'de>, + { + let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096); + let mut values = Vec::with_capacity(len); + + while let Some(value) = visitor.next_element()? { + values.push(value); + } + + Ok(ByteBuf::from(values)) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_string<E>(self, v: String) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } +} + +impl<'de> Deserialize<'de> for ByteBuf { + fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_byte_buf(ByteBufVisitor) + } +} diff --git a/third_party/rust/serde_bytes/src/bytes.rs b/third_party/rust/serde_bytes/src/bytes.rs new file mode 100644 index 0000000000..8fafbf5d9d --- /dev/null +++ b/third_party/rust/serde_bytes/src/bytes.rs @@ -0,0 +1,195 @@ +use core::cmp::Ordering; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; +use core::ops::{Deref, DerefMut}; + +#[cfg(feature = "alloc")] +use alloc::borrow::ToOwned; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::ByteBuf; + +use serde::de::{Deserialize, Deserializer, Error, Visitor}; +use serde::ser::{Serialize, Serializer}; + +/// Wrapper around `&[u8]` to serialize and deserialize efficiently. +/// +/// ``` +/// use std::collections::HashMap; +/// use std::io; +/// +/// use serde_bytes::Bytes; +/// +/// fn print_encoded_cache() -> bincode::Result<()> { +/// let mut cache = HashMap::new(); +/// cache.insert(3, Bytes::new(b"three")); +/// cache.insert(2, Bytes::new(b"two")); +/// cache.insert(1, Bytes::new(b"one")); +/// +/// bincode::serialize_into(&mut io::stdout(), &cache) +/// } +/// # +/// # fn main() { +/// # print_encoded_cache().unwrap(); +/// # } +/// ``` +#[derive(Eq, Ord)] +#[repr(C)] +pub struct Bytes { + bytes: [u8], +} + +impl Bytes { + /// Wrap an existing `&[u8]`. + pub fn new(bytes: &[u8]) -> &Self { + unsafe { &*(bytes as *const [u8] as *const Bytes) } + } +} + +impl Debug for Bytes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.bytes, f) + } +} + +impl AsRef<[u8]> for Bytes { + fn as_ref(&self) -> &[u8] { + &self.bytes + } +} + +impl AsMut<[u8]> for Bytes { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.bytes + } +} + +impl Deref for Bytes { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.bytes + } +} + +impl DerefMut for Bytes { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bytes + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl ToOwned for Bytes { + type Owned = ByteBuf; + + fn to_owned(&self) -> Self::Owned { + ByteBuf::from(&self.bytes) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl From<Box<[u8]>> for Box<Bytes> { + fn from(bytes: Box<[u8]>) -> Self { + unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) } + } +} + +impl<'a> Default for &'a Bytes { + fn default() -> Self { + Bytes::new(&[]) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Default for Box<Bytes> { + fn default() -> Self { + ByteBuf::new().into_boxed_bytes() + } +} + +impl<Rhs> PartialEq<Rhs> for Bytes +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn eq(&self, other: &Rhs) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +impl<Rhs> PartialOrd<Rhs> for Bytes +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> { + self.as_ref().partial_cmp(other.as_ref()) + } +} + +impl Hash for Bytes { + fn hash<H: Hasher>(&self, state: &mut H) { + self.bytes.hash(state); + } +} + +impl<'a> IntoIterator for &'a Bytes { + type Item = &'a u8; + type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter() + } +} + +impl<'a> IntoIterator for &'a mut Bytes { + type Item = &'a mut u8; + type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter_mut() + } +} + +impl Serialize for Bytes { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(&self.bytes) + } +} + +struct BytesVisitor; + +impl<'de> Visitor<'de> for BytesVisitor { + type Value = &'de Bytes; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed byte array") + } + + fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Bytes::new(v)) + } + + fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Bytes::new(v.as_bytes())) + } +} + +impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_bytes(BytesVisitor) + } +} diff --git a/third_party/rust/serde_bytes/src/de.rs b/third_party/rust/serde_bytes/src/de.rs new file mode 100644 index 0000000000..862368aaee --- /dev/null +++ b/third_party/rust/serde_bytes/src/de.rs @@ -0,0 +1,105 @@ +use crate::Bytes; +use serde::Deserializer; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::ByteBuf; + +#[cfg(feature = "alloc")] +use alloc::borrow::Cow; +#[cfg(all(feature = "std", not(feature = "alloc")))] +use std::borrow::Cow; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +/// Types that can be deserialized via `#[serde(with = "serde_bytes")]`. +pub trait Deserialize<'de>: Sized { + #[allow(missing_docs)] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>; +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + // Via the serde::Deserialize impl for &[u8]. + serde::Deserialize::deserialize(deserializer) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for Vec<u8> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(ByteBuf::into_vec) + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a Bytes { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Bytes::new) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for ByteBuf { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + // Via the serde::Deserialize impl for ByteBuf. + serde::Deserialize::deserialize(deserializer) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Cow::Borrowed) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, Bytes> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Cow::Borrowed) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for Box<[u8]> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Vec::into_boxed_slice) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for Box<Bytes> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let bytes: Box<[u8]> = Deserialize::deserialize(deserializer)?; + Ok(bytes.into()) + } +} diff --git a/third_party/rust/serde_bytes/src/lib.rs b/third_party/rust/serde_bytes/src/lib.rs new file mode 100644 index 0000000000..9912623c2f --- /dev/null +++ b/third_party/rust/serde_bytes/src/lib.rs @@ -0,0 +1,108 @@ +//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`. +//! +//! Without specialization, Rust forces Serde to treat `&[u8]` just like any +//! other slice and `Vec<u8>` just like any other vector. In reality this +//! particular slice and vector can often be serialized and deserialized in a +//! more efficient, compact representation in many formats. +//! +//! When working with such a format, you can opt into specialized handling of +//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it +//! in `serde_bytes::ByteBuf`. +//! +//! Additionally this crate supports the Serde `with` attribute to enable +//! efficient handling of `&[u8]` and `Vec<u8>` in structs without needing a +//! wrapper type. +//! +//! ``` +//! # use serde_derive::{Deserialize, Serialize}; +//! use serde::{Deserialize, Serialize}; +//! +//! #[derive(Deserialize, Serialize)] +//! struct Efficient<'a> { +//! #[serde(with = "serde_bytes")] +//! bytes: &'a [u8], +//! +//! #[serde(with = "serde_bytes")] +//! byte_buf: Vec<u8>, +//! } +//! ``` + +#![doc(html_root_url = "https://docs.rs/serde_bytes/0.11.2")] +#![cfg_attr(not(feature = "std"), no_std)] +#![deny(missing_docs)] + +mod bytes; +mod de; +mod ser; + +#[cfg(any(feature = "std", feature = "alloc"))] +mod bytebuf; + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(any(feature = "std", feature = "alloc"))] +use serde::Deserializer; + +use serde::Serializer; + +pub use crate::bytes::Bytes; +pub use crate::de::Deserialize; +pub use crate::ser::Serialize; + +#[cfg(any(feature = "std", feature = "alloc"))] +pub use crate::bytebuf::ByteBuf; + +/// Serde `serialize_with` function to serialize bytes efficiently. +/// +/// This function can be used with either of the following Serde attributes: +/// +/// - `#[serde(with = "serde_bytes")]` +/// - `#[serde(serialize_with = "serde_bytes::serialize")]` +/// +/// ``` +/// # use serde_derive::Serialize; +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct Efficient<'a> { +/// #[serde(with = "serde_bytes")] +/// bytes: &'a [u8], +/// +/// #[serde(with = "serde_bytes")] +/// byte_buf: Vec<u8>, +/// } +/// ``` +pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error> +where + T: ?Sized + Serialize, + S: Serializer, +{ + Serialize::serialize(bytes, serializer) +} + +/// Serde `deserialize_with` function to deserialize bytes efficiently. +/// +/// This function can be used with either of the following Serde attributes: +/// +/// - `#[serde(with = "serde_bytes")]` +/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]` +/// +/// ``` +/// # use serde_derive::Deserialize; +/// use serde::Deserialize; +/// +/// #[derive(Deserialize)] +/// struct Packet { +/// #[serde(with = "serde_bytes")] +/// payload: Vec<u8>, +/// } +/// ``` +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error> +where + T: Deserialize<'de>, + D: Deserializer<'de>, +{ + Deserialize::deserialize(deserializer) +} diff --git a/third_party/rust/serde_bytes/src/ser.rs b/third_party/rust/serde_bytes/src/ser.rs new file mode 100644 index 0000000000..808ef96760 --- /dev/null +++ b/third_party/rust/serde_bytes/src/ser.rs @@ -0,0 +1,107 @@ +use crate::Bytes; +use serde::Serializer; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::ByteBuf; + +#[cfg(feature = "alloc")] +use alloc::borrow::Cow; +#[cfg(all(feature = "std", not(feature = "alloc")))] +use std::borrow::Cow; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +/// Types that can be serialized via `#[serde(with = "serde_bytes")]`. +pub trait Serialize { + #[allow(missing_docs)] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer; +} + +impl Serialize for [u8] { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Serialize for Vec<u8> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +impl Serialize for Bytes { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Serialize for ByteBuf { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a> Serialize for Cow<'a, [u8]> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a> Serialize for Cow<'a, Bytes> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +impl<'a, T> Serialize for &'a T +where + T: ?Sized + Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + (**self).serialize(serializer) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<T> Serialize for Box<T> +where + T: ?Sized + Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + (**self).serialize(serializer) + } +} diff --git a/third_party/rust/serde_bytes/tests/test_derive.rs b/third_party/rust/serde_bytes/tests/test_derive.rs new file mode 100644 index 0000000000..af0bbd89de --- /dev/null +++ b/third_party/rust/serde_bytes/tests/test_derive.rs @@ -0,0 +1,36 @@ +use serde_bytes::{ByteBuf, Bytes}; +use serde_derive::{Deserialize, Serialize}; +use std::borrow::Cow; + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +struct Test<'a> { + #[serde(with = "serde_bytes")] + slice: &'a [u8], + + #[serde(with = "serde_bytes")] + vec: Vec<u8>, + + #[serde(with = "serde_bytes")] + bytes: &'a Bytes, + + #[serde(with = "serde_bytes")] + byte_buf: ByteBuf, + + #[serde(with = "serde_bytes")] + cow_slice: Cow<'a, [u8]>, + + #[serde(with = "serde_bytes")] + cow_bytes: Cow<'a, Bytes>, + + #[serde(with = "serde_bytes")] + boxed_slice: Box<[u8]>, + + #[serde(with = "serde_bytes")] + boxed_bytes: Box<Bytes>, +} + +#[derive(Serialize)] +struct Dst { + #[serde(with = "serde_bytes")] + bytes: [u8], +} diff --git a/third_party/rust/serde_bytes/tests/test_partialeq.rs b/third_party/rust/serde_bytes/tests/test_partialeq.rs new file mode 100644 index 0000000000..549764135e --- /dev/null +++ b/third_party/rust/serde_bytes/tests/test_partialeq.rs @@ -0,0 +1,13 @@ +use serde_bytes::{Bytes, ByteBuf}; + +fn _bytes_eq_slice(bytes: &Bytes, slice: &[u8]) -> bool { + bytes == slice +} + +fn _bytebuf_eq_vec(bytebuf: ByteBuf, vec: Vec<u8>) -> bool { + bytebuf == vec +} + +fn _bytes_eq_bytestring(bytes: &Bytes) -> bool { + bytes == b"..." +} diff --git a/third_party/rust/serde_bytes/tests/test_serde.rs b/third_party/rust/serde_bytes/tests/test_serde.rs new file mode 100644 index 0000000000..d48e3fd434 --- /dev/null +++ b/third_party/rust/serde_bytes/tests/test_serde.rs @@ -0,0 +1,59 @@ +use serde_bytes::{ByteBuf, Bytes}; +use serde_test::{assert_de_tokens, assert_ser_tokens, assert_tokens, Token}; + +#[test] +fn test_bytes() { + let empty = Bytes::new(&[]); + assert_tokens(&empty, &[Token::BorrowedBytes(b"")]); + assert_ser_tokens(&empty, &[Token::Bytes(b"")]); + assert_ser_tokens(&empty, &[Token::ByteBuf(b"")]); + assert_de_tokens(&empty, &[Token::BorrowedStr("")]); + + let buf = vec![65, 66, 67]; + let bytes = Bytes::new(&buf); + assert_tokens(&bytes, &[Token::BorrowedBytes(b"ABC")]); + assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]); + assert_ser_tokens(&bytes, &[Token::ByteBuf(b"ABC")]); + assert_de_tokens(&bytes, &[Token::BorrowedStr("ABC")]); +} + +#[test] +fn test_byte_buf() { + let empty = ByteBuf::new(); + assert_tokens(&empty, &[Token::BorrowedBytes(b"")]); + assert_tokens(&empty, &[Token::Bytes(b"")]); + assert_tokens(&empty, &[Token::ByteBuf(b"")]); + assert_de_tokens(&empty, &[Token::BorrowedStr("")]); + assert_de_tokens(&empty, &[Token::Str("")]); + assert_de_tokens(&empty, &[Token::String("")]); + assert_de_tokens(&empty, &[Token::Seq { len: None }, Token::SeqEnd]); + assert_de_tokens(&empty, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); + + let buf = ByteBuf::from(vec![65, 66, 67]); + assert_tokens(&buf, &[Token::BorrowedBytes(b"ABC")]); + assert_tokens(&buf, &[Token::Bytes(b"ABC")]); + assert_tokens(&buf, &[Token::ByteBuf(b"ABC")]); + assert_de_tokens(&buf, &[Token::BorrowedStr("ABC")]); + assert_de_tokens(&buf, &[Token::Str("ABC")]); + assert_de_tokens(&buf, &[Token::String("ABC")]); + assert_de_tokens( + &buf, + &[ + Token::Seq { len: None }, + Token::U8(65), + Token::U8(66), + Token::U8(67), + Token::SeqEnd, + ], + ); + assert_de_tokens( + &buf, + &[ + Token::Seq { len: Some(3) }, + Token::U8(65), + Token::U8(66), + Token::U8(67), + Token::SeqEnd, + ], + ); +} diff --git a/third_party/rust/serde_derive/.cargo-checksum.json b/third_party/rust/serde_derive/.cargo-checksum.json new file mode 100644 index 0000000000..915ba422d6 --- /dev/null +++ b/third_party/rust/serde_derive/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"74677f4031ffe40137aad8407d240dfe0bd3ed5d07c518afb1983b384f4ee283","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"5cf9d2158d70048a2916360ad59d9079f6233c6f68781a7a792e70f8b772d8ce","build.rs":"17fac4a28904e90c1e46b517839bd17fd54dbc69cfbff7451f695ecf7bab34ef","crates-io.md":"25ed421fe25d0f6f74c4b78674144bef2843a5f78bf552d0a8ec633be69d282b","src/bound.rs":"66643d6cd044a2167b2bb8a1970e5b2a07069e362ce1326a4b00fef7bcfcd5c8","src/de.rs":"8bea1aa8057c824264bb4700fa6531747bfaed88be2d1f90bb6455600aa8e222","src/dummy.rs":"7bc4267039808046fe0a7fbeb462b301ac30ea1152fcbde8a3b934dc143fe468","src/fragment.rs":"5548ba65a53d90a296f60c1328a7a7fb040db467f59c2f5210b2fb320457145d","src/internals/ast.rs":"f1a1b13cf6b68e2bf27c5cdcdbde6883f86cde1ba8c0595dffdbf2e11c4ec8b1","src/internals/attr.rs":"554bf48da8fb4e8a5ac2d16143cc9dc05e9bc493b4a4c8a196ace360bce110d5","src/internals/case.rs":"b2024f414f5d832bafa53b9ae7924b2d43a29175b19bb3da36f15c9071666558","src/internals/check.rs":"9a01a0db1fc3086891e998f544836e7498ebfc7cc5e1956199d0526e6a8d9a3c","src/internals/ctxt.rs":"6fa544ae52914498a62a395818ebdc1b36ac2fb5903c60afb741a864ad559f1c","src/internals/mod.rs":"989df41dae7a9066eec3e5afd5b262fd94a12281df30f4c03f319370811beea0","src/internals/symbol.rs":"9f2b4b9cd83dc09def75165187c97d0050bffa4218782c27b478bcf93f925a74","src/lib.rs":"ae786031bb024d49a73e8c0aee126441a9e61dd2bc50ddf7aad4a586fa89081d","src/pretend.rs":"ffeb23da4c2abc4e501c378cffa8b776bab506735ea70d4ed10f4c0f3755321b","src/ser.rs":"4ac3d23e5a84b72137d42eaa38ef8ec1516c4d4d9ca040dc5ce2abbf33126443","src/try.rs":"b9a10c8690d442a57fc7097d42c9a4f13034c7b4a30b7eb02d538fdbf8ae0a8d"},"package":"f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"}
\ No newline at end of file diff --git a/third_party/rust/serde_derive/Cargo.toml b/third_party/rust/serde_derive/Cargo.toml new file mode 100644 index 0000000000..d06a1bb40a --- /dev/null +++ b/third_party/rust/serde_derive/Cargo.toml @@ -0,0 +1,45 @@ +# 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_derive" +version = "1.0.116" +authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] +include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" +homepage = "https://serde.rs" +documentation = "https://serde.rs/derive.html" +readme = "crates-io.md" +keywords = ["serde", "serialization", "no_std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/serde-rs/serde" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +name = "serde_derive" +proc-macro = true +[dependencies.proc-macro2] +version = "1.0" + +[dependencies.quote] +version = "1.0" + +[dependencies.syn] +version = "1.0.33" +features = ["visit"] +[dev-dependencies.serde] +version = "1.0" + +[features] +default = [] +deserialize_in_place = [] diff --git a/third_party/rust/serde_derive/LICENSE-APACHE b/third_party/rust/serde_derive/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_derive/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/serde_derive/LICENSE-MIT b/third_party/rust/serde_derive/LICENSE-MIT new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/third_party/rust/serde_derive/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_derive/README.md b/third_party/rust/serde_derive/README.md new file mode 100644 index 0000000000..14b00982e0 --- /dev/null +++ b/third_party/rust/serde_derive/README.md @@ -0,0 +1,111 @@ +# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31] + +[Build Status]: https://img.shields.io/github/workflow/status/serde-rs/serde/CI/master +[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster +[Latest Version]: https://img.shields.io/crates/v/serde.svg +[crates.io]: https://crates.io/crates/serde +[serde: rustc 1.13+]: https://img.shields.io/badge/serde-rustc_1.13+-lightgray.svg +[serde_derive: rustc 1.31+]: https://img.shields.io/badge/serde_derive-rustc_1.31+-lightgray.svg +[Rust 1.13]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html +[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.serde.rs/serde/) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +<details> +<summary> +Click to show Cargo.toml. +<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a> +</summary> + +```toml +[dependencies] + +# The core APIs, including the Serialize and Deserialize traits. Always +# required when using Serde. The "derive" feature is only required when +# using #[derive(Serialize, Deserialize)] to make Serde work with structs +# and enums defined in your crate. +serde = { version = "1.0", features = ["derive"] } + +# Each data format lives in its own crate; the sample code below uses JSON +# but you may be using a different one. +serde_json = "1.0" +``` + +</details> +<p></p> + +```rust +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#general] or [#beginners] channels of the unofficial community Discord, the +[#rust-usage] channel of the official Rust Project Discord, or the +[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag +on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned +weekly easy questions post, or the Rust [Discourse forum][discourse]. It's +acceptable to file a support issue in this repo but they tend not to get as many +eyes as any of the above and may get closed without a response after some time. + +[#general]: https://discord.com/channels/273534239310479360/274215136414400513 +[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org + +<br> + +#### License + +<sup> +Licensed under either of <a href="LICENSE-APACHE">Apache License, Version +2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. +</sup> + +<br> + +<sub> +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. +</sub> diff --git a/third_party/rust/serde_derive/build.rs b/third_party/rust/serde_derive/build.rs new file mode 100644 index 0000000000..6e1b7b6dd6 --- /dev/null +++ b/third_party/rust/serde_derive/build.rs @@ -0,0 +1,30 @@ +use std::env; +use std::process::Command; +use std::str; + +// 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, + }; + + // Underscore const names stabilized in Rust 1.37: + // https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros + if minor >= 37 { + println!("cargo:rustc-cfg=underscore_consts"); + } +} + +fn rustc_minor_version() -> Option<u32> { + let rustc = env::var_os("RUSTC")?; + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() +} diff --git a/third_party/rust/serde_derive/crates-io.md b/third_party/rust/serde_derive/crates-io.md new file mode 100644 index 0000000000..07757614a7 --- /dev/null +++ b/third_party/rust/serde_derive/crates-io.md @@ -0,0 +1,62 @@ +<!-- Serde readme rendered on crates.io --> + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.serde.rs/serde/) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +```rust +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#general] or [#beginners] channels of the unofficial community Discord, the +[#rust-usage] channel of the official Rust Project Discord, or the +[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag +on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned +weekly easy questions post, or the Rust [Discourse forum][discourse]. It's +acceptable to file a support issue in this repo but they tend not to get as many +eyes as any of the above and may get closed without a response after some time. + +[#general]: https://discord.com/channels/273534239310479360/274215136414400513 +[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org diff --git a/third_party/rust/serde_derive/src/bound.rs b/third_party/rust/serde_derive/src/bound.rs new file mode 100644 index 0000000000..ec2eafe89f --- /dev/null +++ b/third_party/rust/serde_derive/src/bound.rs @@ -0,0 +1,317 @@ +use std::collections::HashSet; + +use syn; +use syn::punctuated::{Pair, Punctuated}; +use syn::visit::{self, Visit}; + +use internals::ast::{Container, Data}; +use internals::{attr, ungroup}; + +use proc_macro2::Span; + +// Remove the default from every type parameter because in the generated impls +// they look like associated types: "error: associated type bindings are not +// allowed here". +pub fn without_defaults(generics: &syn::Generics) -> syn::Generics { + syn::Generics { + params: generics + .params + .iter() + .map(|param| match param { + syn::GenericParam::Type(param) => syn::GenericParam::Type(syn::TypeParam { + eq_token: None, + default: None, + ..param.clone() + }), + _ => param.clone(), + }) + .collect(), + ..generics.clone() + } +} + +pub fn with_where_predicates( + generics: &syn::Generics, + predicates: &[syn::WherePredicate], +) -> syn::Generics { + let mut generics = generics.clone(); + generics + .make_where_clause() + .predicates + .extend(predicates.iter().cloned()); + generics +} + +pub fn with_where_predicates_from_fields( + cont: &Container, + generics: &syn::Generics, + from_field: fn(&attr::Field) -> Option<&[syn::WherePredicate]>, +) -> syn::Generics { + let predicates = cont + .data + .all_fields() + .flat_map(|field| from_field(&field.attrs)) + .flat_map(|predicates| predicates.to_vec()); + + let mut generics = generics.clone(); + generics.make_where_clause().predicates.extend(predicates); + generics +} + +pub fn with_where_predicates_from_variants( + cont: &Container, + generics: &syn::Generics, + from_variant: fn(&attr::Variant) -> Option<&[syn::WherePredicate]>, +) -> syn::Generics { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => { + return generics.clone(); + } + }; + + let predicates = variants + .iter() + .flat_map(|variant| from_variant(&variant.attrs)) + .flat_map(|predicates| predicates.to_vec()); + + let mut generics = generics.clone(); + generics.make_where_clause().predicates.extend(predicates); + generics +} + +// Puts the given bound on any generic type parameters that are used in fields +// for which filter returns true. +// +// For example, the following struct needs the bound `A: Serialize, B: +// Serialize`. +// +// struct S<'b, A, B: 'b, C> { +// a: A, +// b: Option<&'b B> +// #[serde(skip_serializing)] +// c: C, +// } +pub fn with_bound( + cont: &Container, + generics: &syn::Generics, + filter: fn(&attr::Field, Option<&attr::Variant>) -> bool, + bound: &syn::Path, +) -> syn::Generics { + struct FindTyParams<'ast> { + // Set of all generic type parameters on the current struct (A, B, C in + // the example). Initialized up front. + all_type_params: HashSet<syn::Ident>, + + // Set of generic type parameters used in fields for which filter + // returns true (A and B in the example). Filled in as the visitor sees + // them. + relevant_type_params: HashSet<syn::Ident>, + + // Fields whose type is an associated type of one of the generic type + // parameters. + associated_type_usage: Vec<&'ast syn::TypePath>, + } + impl<'ast> Visit<'ast> for FindTyParams<'ast> { + fn visit_field(&mut self, field: &'ast syn::Field) { + if let syn::Type::Path(ty) = ungroup(&field.ty) { + if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() { + if self.all_type_params.contains(&t.ident) { + self.associated_type_usage.push(ty); + } + } + } + self.visit_type(&field.ty); + } + + fn visit_path(&mut self, path: &'ast syn::Path) { + if let Some(seg) = path.segments.last() { + if seg.ident == "PhantomData" { + // Hardcoded exception, because PhantomData<T> implements + // Serialize and Deserialize whether or not T implements it. + return; + } + } + if path.leading_colon.is_none() && path.segments.len() == 1 { + let id = &path.segments[0].ident; + if self.all_type_params.contains(id) { + self.relevant_type_params.insert(id.clone()); + } + } + visit::visit_path(self, path); + } + + // Type parameter should not be considered used by a macro path. + // + // struct TypeMacro<T> { + // mac: T!(), + // marker: PhantomData<T>, + // } + fn visit_macro(&mut self, _mac: &'ast syn::Macro) {} + } + + let all_type_params = generics + .type_params() + .map(|param| param.ident.clone()) + .collect(); + + let mut visitor = FindTyParams { + all_type_params, + relevant_type_params: HashSet::new(), + associated_type_usage: Vec::new(), + }; + match &cont.data { + Data::Enum(variants) => { + for variant in variants.iter() { + let relevant_fields = variant + .fields + .iter() + .filter(|field| filter(&field.attrs, Some(&variant.attrs))); + for field in relevant_fields { + visitor.visit_field(field.original); + } + } + } + Data::Struct(_, fields) => { + for field in fields.iter().filter(|field| filter(&field.attrs, None)) { + visitor.visit_field(field.original); + } + } + } + + let relevant_type_params = visitor.relevant_type_params; + let associated_type_usage = visitor.associated_type_usage; + let new_predicates = generics + .type_params() + .map(|param| param.ident.clone()) + .filter(|id| relevant_type_params.contains(id)) + .map(|id| syn::TypePath { + qself: None, + path: id.into(), + }) + .chain(associated_type_usage.into_iter().cloned()) + .map(|bounded_ty| { + syn::WherePredicate::Type(syn::PredicateType { + lifetimes: None, + // the type parameter that is being bounded e.g. T + bounded_ty: syn::Type::Path(bounded_ty), + colon_token: <Token![:]>::default(), + // the bound e.g. Serialize + bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound { + paren_token: None, + modifier: syn::TraitBoundModifier::None, + lifetimes: None, + path: bound.clone(), + })] + .into_iter() + .collect(), + }) + }); + + let mut generics = generics.clone(); + generics + .make_where_clause() + .predicates + .extend(new_predicates); + generics +} + +pub fn with_self_bound( + cont: &Container, + generics: &syn::Generics, + bound: &syn::Path, +) -> syn::Generics { + let mut generics = generics.clone(); + generics + .make_where_clause() + .predicates + .push(syn::WherePredicate::Type(syn::PredicateType { + lifetimes: None, + // the type that is being bounded e.g. MyStruct<'a, T> + bounded_ty: type_of_item(cont), + colon_token: <Token![:]>::default(), + // the bound e.g. Default + bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound { + paren_token: None, + modifier: syn::TraitBoundModifier::None, + lifetimes: None, + path: bound.clone(), + })] + .into_iter() + .collect(), + })); + generics +} + +pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics { + let bound = syn::Lifetime::new(lifetime, Span::call_site()); + let def = syn::LifetimeDef { + attrs: Vec::new(), + lifetime: bound.clone(), + colon_token: None, + bounds: Punctuated::new(), + }; + + let params = Some(syn::GenericParam::Lifetime(def)) + .into_iter() + .chain(generics.params.iter().cloned().map(|mut param| { + match &mut param { + syn::GenericParam::Lifetime(param) => { + param.bounds.push(bound.clone()); + } + syn::GenericParam::Type(param) => { + param + .bounds + .push(syn::TypeParamBound::Lifetime(bound.clone())); + } + syn::GenericParam::Const(_) => {} + } + param + })) + .collect(); + + syn::Generics { + params, + ..generics.clone() + } +} + +fn type_of_item(cont: &Container) -> syn::Type { + syn::Type::Path(syn::TypePath { + qself: None, + path: syn::Path { + leading_colon: None, + segments: vec![syn::PathSegment { + ident: cont.ident.clone(), + arguments: syn::PathArguments::AngleBracketed( + syn::AngleBracketedGenericArguments { + colon2_token: None, + lt_token: <Token![<]>::default(), + args: cont + .generics + .params + .iter() + .map(|param| match param { + syn::GenericParam::Type(param) => { + syn::GenericArgument::Type(syn::Type::Path(syn::TypePath { + qself: None, + path: param.ident.clone().into(), + })) + } + syn::GenericParam::Lifetime(param) => { + syn::GenericArgument::Lifetime(param.lifetime.clone()) + } + syn::GenericParam::Const(_) => { + panic!("Serde does not support const generics yet"); + } + }) + .collect(), + gt_token: <Token![>]>::default(), + }, + ), + }] + .into_iter() + .collect(), + }, + }) +} diff --git a/third_party/rust/serde_derive/src/de.rs b/third_party/rust/serde_derive/src/de.rs new file mode 100644 index 0000000000..1f5733a6d5 --- /dev/null +++ b/third_party/rust/serde_derive/src/de.rs @@ -0,0 +1,3049 @@ +use proc_macro2::{Literal, Span, TokenStream}; +use quote::ToTokens; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; +use syn::{self, Ident, Index, Member}; + +use bound; +use dummy; +use fragment::{Expr, Fragment, Match, Stmts}; +use internals::ast::{Container, Data, Field, Style, Variant}; +use internals::{attr, ungroup, Ctxt, Derive}; +use pretend; + +use std::collections::BTreeSet; + +pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> { + let ctxt = Ctxt::new(); + let cont = match Container::from_ast(&ctxt, input, Derive::Deserialize) { + Some(cont) => cont, + None => return Err(ctxt.check().unwrap_err()), + }; + precondition(&ctxt, &cont); + ctxt.check()?; + + let ident = &cont.ident; + let params = Parameters::new(&cont); + let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms); + let body = Stmts(deserialize_body(&cont, ¶ms)); + let delife = params.borrowed.de_lifetime(); + let serde = cont.attrs.serde_path(); + + let impl_block = if let Some(remote) = cont.attrs.remote() { + let vis = &input.vis; + let used = pretend::pretend_used(&cont); + quote! { + impl #de_impl_generics #ident #ty_generics #where_clause { + #vis fn deserialize<__D>(__deserializer: __D) -> #serde::export::Result<#remote #ty_generics, __D::Error> + where + __D: #serde::Deserializer<#delife>, + { + #used + #body + } + } + } + } else { + let fn_deserialize_in_place = deserialize_in_place_body(&cont, ¶ms); + + quote! { + #[automatically_derived] + impl #de_impl_generics #serde::Deserialize<#delife> for #ident #ty_generics #where_clause { + fn deserialize<__D>(__deserializer: __D) -> #serde::export::Result<Self, __D::Error> + where + __D: #serde::Deserializer<#delife>, + { + #body + } + + #fn_deserialize_in_place + } + } + }; + + Ok(dummy::wrap_in_const( + cont.attrs.custom_serde_path(), + "DESERIALIZE", + ident, + impl_block, + )) +} + +fn precondition(cx: &Ctxt, cont: &Container) { + precondition_sized(cx, cont); + precondition_no_de_lifetime(cx, cont); +} + +fn precondition_sized(cx: &Ctxt, cont: &Container) { + if let Data::Struct(_, fields) = &cont.data { + if let Some(last) = fields.last() { + if let syn::Type::Slice(_) = ungroup(last.ty) { + cx.error_spanned_by( + cont.original, + "cannot deserialize a dynamically sized struct", + ); + } + } + } +} + +fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) { + if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) { + for param in cont.generics.lifetimes() { + if param.lifetime.to_string() == "'de" { + cx.error_spanned_by( + ¶m.lifetime, + "cannot deserialize when there is a lifetime parameter called 'de", + ); + return; + } + } + } +} + +struct Parameters { + /// Name of the type the `derive` is on. + local: syn::Ident, + + /// Path to the type the impl is for. Either a single `Ident` for local + /// types or `some::remote::Ident` for remote types. Does not include + /// generic parameters. + this: syn::Path, + + /// Generics including any explicit and inferred bounds for the impl. + generics: syn::Generics, + + /// Lifetimes borrowed from the deserializer. These will become bounds on + /// the `'de` lifetime of the deserializer. + borrowed: BorrowedLifetimes, + + /// At least one field has a serde(getter) attribute, implying that the + /// remote type has a private field. + has_getter: bool, +} + +impl Parameters { + fn new(cont: &Container) -> Self { + let local = cont.ident.clone(); + let this = match cont.attrs.remote() { + Some(remote) => remote.clone(), + None => cont.ident.clone().into(), + }; + let borrowed = borrowed_lifetimes(cont); + let generics = build_generics(cont, &borrowed); + let has_getter = cont.data.has_getter(); + + Parameters { + local, + this, + generics, + borrowed, + has_getter, + } + } + + /// Type name to use in error messages and `&'static str` arguments to + /// various Deserializer methods. + fn type_name(&self) -> String { + self.this.segments.last().unwrap().ident.to_string() + } +} + +// All the generics in the input, plus a bound `T: Deserialize` for each generic +// field type that will be deserialized by us, plus a bound `T: Default` for +// each generic field type that will be set to a default value. +fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics { + let generics = bound::without_defaults(cont.generics); + + let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound); + + let generics = + bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::de_bound); + + match cont.attrs.de_bound() { + Some(predicates) => bound::with_where_predicates(&generics, predicates), + None => { + let generics = match *cont.attrs.default() { + attr::Default::Default => { + bound::with_self_bound(cont, &generics, &parse_quote!(_serde::export::Default)) + } + attr::Default::None | attr::Default::Path(_) => generics, + }; + + let delife = borrowed.de_lifetime(); + let generics = bound::with_bound( + cont, + &generics, + needs_deserialize_bound, + &parse_quote!(_serde::Deserialize<#delife>), + ); + + bound::with_bound( + cont, + &generics, + requires_default, + &parse_quote!(_serde::export::Default), + ) + } + } +} + +// Fields with a `skip_deserializing` or `deserialize_with` attribute, or which +// belong to a variant with a `skip_deserializing` or `deserialize_with` +// attribute, are not deserialized by us so we do not generate a bound. Fields +// with a `bound` attribute specify their own bound so we do not generate one. +// All other fields may need a `T: Deserialize` bound where T is the type of the +// field. +fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { + !field.skip_deserializing() + && field.deserialize_with().is_none() + && field.de_bound().is_none() + && variant.map_or(true, |variant| { + !variant.skip_deserializing() + && variant.deserialize_with().is_none() + && variant.de_bound().is_none() + }) +} + +// Fields with a `default` attribute (not `default=...`), and fields with a +// `skip_deserializing` attribute that do not also have `default=...`. +fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool { + if let attr::Default::Default = *field.default() { + true + } else { + false + } +} + +enum BorrowedLifetimes { + Borrowed(BTreeSet<syn::Lifetime>), + Static, +} + +impl BorrowedLifetimes { + fn de_lifetime(&self) -> syn::Lifetime { + match *self { + BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de", Span::call_site()), + BorrowedLifetimes::Static => syn::Lifetime::new("'static", Span::call_site()), + } + } + + fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> { + match self { + BorrowedLifetimes::Borrowed(bounds) => Some(syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de", Span::call_site()), + colon_token: None, + bounds: bounds.iter().cloned().collect(), + }), + BorrowedLifetimes::Static => None, + } + } +} + +// The union of lifetimes borrowed by each field of the container. +// +// These turn into bounds on the `'de` lifetime of the Deserialize impl. If +// lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is: +// +// impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c> +// +// If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant +// and we use plain `'static` instead of `'de`. +fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes { + let mut lifetimes = BTreeSet::new(); + for field in cont.data.all_fields() { + if !field.attrs.skip_deserializing() { + lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned()); + } + } + if lifetimes.iter().any(|b| b.to_string() == "'static") { + BorrowedLifetimes::Static + } else { + BorrowedLifetimes::Borrowed(lifetimes) + } +} + +fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { + if cont.attrs.transparent() { + deserialize_transparent(cont, params) + } else if let Some(type_from) = cont.attrs.type_from() { + deserialize_from(type_from) + } else if let Some(type_try_from) = cont.attrs.type_try_from() { + deserialize_try_from(type_try_from) + } else if let attr::Identifier::No = cont.attrs.identifier() { + match &cont.data { + Data::Enum(variants) => deserialize_enum(params, variants, &cont.attrs), + Data::Struct(Style::Struct, fields) => { + deserialize_struct(None, params, fields, &cont.attrs, None, &Untagged::No) + } + Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { + deserialize_tuple(None, params, fields, &cont.attrs, None) + } + Data::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs), + } + } else { + match &cont.data { + Data::Enum(variants) => deserialize_custom_identifier(params, variants, &cont.attrs), + Data::Struct(_, _) => unreachable!("checked in serde_derive_internals"), + } + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<Stmts> { + // Only remote derives have getters, and we do not generate + // deserialize_in_place for remote derives. + assert!(!params.has_getter); + + if cont.attrs.transparent() + || cont.attrs.type_from().is_some() + || cont.attrs.type_try_from().is_some() + || cont.attrs.identifier().is_some() + || cont + .data + .all_fields() + .all(|f| f.attrs.deserialize_with().is_some()) + { + return None; + } + + let code = match &cont.data { + Data::Struct(Style::Struct, fields) => { + deserialize_struct_in_place(None, params, fields, &cont.attrs, None)? + } + Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { + deserialize_tuple_in_place(None, params, fields, &cont.attrs, None) + } + Data::Enum(_) | Data::Struct(Style::Unit, _) => { + return None; + } + }; + + let delife = params.borrowed.de_lifetime(); + let stmts = Stmts(code); + + let fn_deserialize_in_place = quote_block! { + fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::export::Result<(), __D::Error> + where + __D: _serde::Deserializer<#delife>, + { + #stmts + } + }; + + Some(Stmts(fn_deserialize_in_place)) +} + +#[cfg(not(feature = "deserialize_in_place"))] +fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option<Stmts> { + None +} + +fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment { + let fields = match &cont.data { + Data::Struct(_, fields) => fields, + Data::Enum(_) => unreachable!(), + }; + + let this = ¶ms.this; + let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap(); + + let path = match transparent_field.attrs.deserialize_with() { + Some(path) => quote!(#path), + None => { + let span = transparent_field.original.span(); + quote_spanned!(span=> _serde::Deserialize::deserialize) + } + }; + + let assign = fields.iter().map(|field| { + let member = &field.member; + if field as *const Field == transparent_field as *const Field { + quote!(#member: __transparent) + } else { + let value = match field.attrs.default() { + attr::Default::Default => quote!(_serde::export::Default::default()), + attr::Default::Path(path) => quote!(#path()), + attr::Default::None => quote!(_serde::export::PhantomData), + }; + quote!(#member: #value) + } + }); + + quote_block! { + _serde::export::Result::map( + #path(__deserializer), + |__transparent| #this { #(#assign),* }) + } +} + +fn deserialize_from(type_from: &syn::Type) -> Fragment { + quote_block! { + _serde::export::Result::map( + <#type_from as _serde::Deserialize>::deserialize(__deserializer), + _serde::export::From::from) + } +} + +fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment { + quote_block! { + _serde::export::Result::and_then( + <#type_try_from as _serde::Deserialize>::deserialize(__deserializer), + |v| _serde::export::TryFrom::try_from(v).map_err(_serde::de::Error::custom)) + } +} + +fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment { + let this = ¶ms.this; + let type_name = cattrs.name().deserialize_name(); + + let expecting = format!("unit struct {}", params.type_name()); + + quote_block! { + struct __Visitor; + + impl<'de> _serde::de::Visitor<'de> for __Visitor { + type Value = #this; + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + #[inline] + fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(#this) + } + } + + _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor) + } +} + +fn deserialize_tuple( + variant_ident: Option<&syn::Ident>, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + deserializer: Option<TokenStream>, +) -> Fragment { + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + assert!(!cattrs.has_flatten()); + + // If there are getters (implying private fields), construct the local type + // and use an `Into` conversion to get the remote type. If there are no + // getters then construct the target type directly. + let construct = if params.has_getter { + let local = ¶ms.local; + quote!(#local) + } else { + quote!(#this) + }; + + let is_enum = variant_ident.is_some(); + let type_path = match variant_ident { + Some(variant_ident) => quote!(#construct::#variant_ident), + None => construct, + }; + let expecting = match variant_ident { + Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident), + None => format!("tuple struct {}", params.type_name()), + }; + + let nfields = fields.len(); + + let visit_newtype_struct = if !is_enum && nfields == 1 { + Some(deserialize_newtype_struct(&type_path, params, &fields[0])) + } else { + None + }; + + let visit_seq = Stmts(deserialize_seq( + &type_path, params, fields, false, cattrs, &expecting, + )); + + let visitor_expr = quote! { + __Visitor { + marker: _serde::export::PhantomData::<#this #ty_generics>, + lifetime: _serde::export::PhantomData, + } + }; + let dispatch = if let Some(deserializer) = deserializer { + quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) + } else if is_enum { + quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) + } else if nfields == 1 { + let type_name = cattrs.name().deserialize_name(); + quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + } else { + let type_name = cattrs.name().deserialize_name(); + quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let visitor_var = if all_skipped { + quote!(_) + } else { + quote!(mut __seq) + }; + + quote_block! { + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + #visit_newtype_struct + + #[inline] + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + } + + #dispatch + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_tuple_in_place( + variant_ident: Option<syn::Ident>, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + deserializer: Option<TokenStream>, +) -> Fragment { + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + assert!(!cattrs.has_flatten()); + + let is_enum = variant_ident.is_some(); + let expecting = match variant_ident { + Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident), + None => format!("tuple struct {}", params.type_name()), + }; + + let nfields = fields.len(); + + let visit_newtype_struct = if !is_enum && nfields == 1 { + Some(deserialize_newtype_struct_in_place(params, &fields[0])) + } else { + None + }; + + let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting)); + + let visitor_expr = quote! { + __Visitor { + place: __place, + lifetime: _serde::export::PhantomData, + } + }; + + let dispatch = if let Some(deserializer) = deserializer { + quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) + } else if is_enum { + quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) + } else if nfields == 1 { + let type_name = cattrs.name().deserialize_name(); + quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + } else { + let type_name = cattrs.name().deserialize_name(); + quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let visitor_var = if all_skipped { + quote!(_) + } else { + quote!(mut __seq) + }; + + let in_place_impl_generics = de_impl_generics.in_place(); + let in_place_ty_generics = de_ty_generics.in_place(); + let place_life = place_lifetime(); + + quote_block! { + struct __Visitor #in_place_impl_generics #where_clause { + place: &#place_life mut #this #ty_generics, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { + type Value = (); + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + #visit_newtype_struct + + #[inline] + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + } + + #dispatch + } +} + +fn deserialize_seq( + type_path: &TokenStream, + params: &Parameters, + fields: &[Field], + is_struct: bool, + cattrs: &attr::Container, + expecting: &str, +) -> Fragment { + let vars = (0..fields.len()).map(field_i as fn(_) -> _); + + let deserialized_count = fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + let expecting = if deserialized_count == 1 { + format!("{} with 1 element", expecting) + } else { + format!("{} with {} elements", expecting, deserialized_count) + }; + + let mut index_in_seq = 0_usize; + let let_values = vars.clone().zip(fields).map(|(var, field)| { + if field.attrs.skip_deserializing() { + let default = Expr(expr_is_missing(field, cattrs)); + quote! { + let #var = #default; + } + } else { + let visit = match field.attrs.deserialize_with() { + None => { + let field_ty = field.ty; + let span = field.original.span(); + let func = + quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>); + quote!(try!(#func(&mut __seq))) + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + _serde::export::Option::map( + try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)), + |__wrap| __wrap.value) + }) + } + }; + let value_if_none = match field.attrs.default() { + attr::Default::Default => quote!(_serde::export::Default::default()), + attr::Default::Path(path) => quote!(#path()), + attr::Default::None => quote!( + return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); + ), + }; + let assign = quote! { + let #var = match #visit { + _serde::export::Some(__value) => __value, + _serde::export::None => { + #value_if_none + } + }; + }; + index_in_seq += 1; + assign + } + }); + + let mut result = if is_struct { + let names = fields.iter().map(|f| &f.member); + quote! { + #type_path { #( #names: #vars ),* } + } + } else { + quote! { + #type_path ( #(#vars),* ) + } + }; + + if params.has_getter { + let this = ¶ms.this; + result = quote! { + _serde::export::Into::<#this>::into(#result) + }; + } + + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: Self::Value = _serde::export::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: Self::Value = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #let_default + #(#let_values)* + _serde::export::Ok(#result) + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_seq_in_place( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + expecting: &str, +) -> Fragment { + let deserialized_count = fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + let expecting = if deserialized_count == 1 { + format!("{} with 1 element", expecting) + } else { + format!("{} with {} elements", expecting, deserialized_count) + }; + + let mut index_in_seq = 0usize; + let write_values = fields.iter().map(|field| { + let member = &field.member; + + if field.attrs.skip_deserializing() { + let default = Expr(expr_is_missing(field, cattrs)); + quote! { + self.place.#member = #default; + } + } else { + let value_if_none = match field.attrs.default() { + attr::Default::Default => quote!( + self.place.#member = _serde::export::Default::default(); + ), + attr::Default::Path(path) => quote!( + self.place.#member = #path(); + ), + attr::Default::None => quote!( + return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); + ), + }; + let write = match field.attrs.deserialize_with() { + None => { + quote! { + if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq, + _serde::private::de::InPlaceSeed(&mut self.place.#member))) + { + #value_if_none + } + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) { + _serde::export::Some(__wrap) => { + self.place.#member = __wrap.value; + } + _serde::export::None => { + #value_if_none + } + } + }) + } + }; + index_in_seq += 1; + write + } + }); + + let this = ¶ms.this; + let (_, ty_generics, _) = params.generics.split_for_impl(); + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: #this #ty_generics = _serde::export::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: #this #ty_generics = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #let_default + #(#write_values)* + _serde::export::Ok(()) + } +} + +fn deserialize_newtype_struct( + type_path: &TokenStream, + params: &Parameters, + field: &Field, +) -> TokenStream { + let delife = params.borrowed.de_lifetime(); + let field_ty = field.ty; + + let value = match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); + quote! { + try!(#func(__e)) + } + } + Some(path) => { + quote! { + try!(#path(__e)) + } + } + }; + + let mut result = quote!(#type_path(__field0)); + if params.has_getter { + let this = ¶ms.this; + result = quote! { + _serde::export::Into::<#this>::into(#result) + }; + } + + quote! { + #[inline] + fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error> + where + __E: _serde::Deserializer<#delife>, + { + let __field0: #field_ty = #value; + _serde::export::Ok(#result) + } + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream { + // We do not generate deserialize_in_place if every field has a + // deserialize_with. + assert!(field.attrs.deserialize_with().is_none()); + + let delife = params.borrowed.de_lifetime(); + + quote! { + #[inline] + fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error> + where + __E: _serde::Deserializer<#delife>, + { + _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0) + } + } +} + +enum Untagged { + Yes, + No, +} + +fn deserialize_struct( + variant_ident: Option<&syn::Ident>, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + deserializer: Option<TokenStream>, + untagged: &Untagged, +) -> Fragment { + let is_enum = variant_ident.is_some(); + + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + // If there are getters (implying private fields), construct the local type + // and use an `Into` conversion to get the remote type. If there are no + // getters then construct the target type directly. + let construct = if params.has_getter { + let local = ¶ms.local; + quote!(#local) + } else { + quote!(#this) + }; + + let type_path = match variant_ident { + Some(variant_ident) => quote!(#construct::#variant_ident), + None => construct, + }; + let expecting = match variant_ident { + Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident), + None => format!("struct {}", params.type_name()), + }; + + let visit_seq = Stmts(deserialize_seq( + &type_path, params, fields, true, cattrs, &expecting, + )); + + let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() { + deserialize_struct_as_map_visitor(&type_path, params, fields, cattrs) + } else { + deserialize_struct_as_struct_visitor(&type_path, params, fields, cattrs) + }; + let field_visitor = Stmts(field_visitor); + let fields_stmt = fields_stmt.map(Stmts); + let visit_map = Stmts(visit_map); + + let visitor_expr = quote! { + __Visitor { + marker: _serde::export::PhantomData::<#this #ty_generics>, + lifetime: _serde::export::PhantomData, + } + }; + let dispatch = if let Some(deserializer) = deserializer { + quote! { + _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) + } + } else if is_enum && cattrs.has_flatten() { + quote! { + _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr) + } + } else if is_enum { + quote! { + _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) + } + } else if cattrs.has_flatten() { + quote! { + _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr) + } + } else { + let type_name = cattrs.name().deserialize_name(); + quote! { + _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) + } + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let visitor_var = if all_skipped { + quote!(_) + } else { + quote!(mut __seq) + }; + + // untagged struct variants do not get a visit_seq method. The same applies to + // structs that only have a map representation. + let visit_seq = match *untagged { + Untagged::No if !cattrs.has_flatten() => Some(quote! { + #[inline] + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + }), + _ => None, + }; + + let visitor_seed = if is_enum && cattrs.has_flatten() { + Some(quote! { + impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error> + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_map(__deserializer, self) + } + } + }) + } else { + None + }; + + quote_block! { + #field_visitor + + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + #visit_seq + + #[inline] + fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::MapAccess<#delife>, + { + #visit_map + } + } + + #visitor_seed + + #fields_stmt + + #dispatch + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_struct_in_place( + variant_ident: Option<syn::Ident>, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + deserializer: Option<TokenStream>, +) -> Option<Fragment> { + let is_enum = variant_ident.is_some(); + + // for now we do not support in_place deserialization for structs that + // are represented as map. + if cattrs.has_flatten() { + return None; + } + + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let expecting = match variant_ident { + Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident), + None => format!("struct {}", params.type_name()), + }; + + let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting)); + + let (field_visitor, fields_stmt, visit_map) = + deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs); + + let field_visitor = Stmts(field_visitor); + let fields_stmt = Stmts(fields_stmt); + let visit_map = Stmts(visit_map); + + let visitor_expr = quote! { + __Visitor { + place: __place, + lifetime: _serde::export::PhantomData, + } + }; + let dispatch = if let Some(deserializer) = deserializer { + quote! { + _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) + } + } else if is_enum { + quote! { + _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) + } + } else { + let type_name = cattrs.name().deserialize_name(); + quote! { + _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) + } + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let visitor_var = if all_skipped { + quote!(_) + } else { + quote!(mut __seq) + }; + + let visit_seq = quote! { + #[inline] + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + }; + + let in_place_impl_generics = de_impl_generics.in_place(); + let in_place_ty_generics = de_ty_generics.in_place(); + let place_life = place_lifetime(); + + Some(quote_block! { + #field_visitor + + struct __Visitor #in_place_impl_generics #where_clause { + place: &#place_life mut #this #ty_generics, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { + type Value = (); + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + #visit_seq + + #[inline] + fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::MapAccess<#delife>, + { + #visit_map + } + } + + #fields_stmt + + #dispatch + }) +} + +fn deserialize_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + match cattrs.tag() { + attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs), + attr::TagType::Internal { tag } => { + deserialize_internally_tagged_enum(params, variants, cattrs, tag) + } + attr::TagType::Adjacent { tag, content } => { + deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content) + } + attr::TagType::None => deserialize_untagged_enum(params, variants, cattrs), + } +} + +fn prepare_enum_variant_enum( + variants: &[Variant], + cattrs: &attr::Container, +) -> (TokenStream, Stmts) { + let mut deserialized_variants = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()); + + let variant_names_idents: Vec<_> = deserialized_variants + .clone() + .map(|(i, variant)| { + ( + variant.attrs.name().deserialize_name(), + field_i(i), + variant.attrs.aliases(), + ) + }) + .collect(); + + let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other()); + + let variants_stmt = { + let variant_names = variant_names_idents.iter().map(|(name, _, _)| name); + quote! { + const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; + } + }; + + let variant_visitor = Stmts(deserialize_generated_identifier( + &variant_names_idents, + cattrs, + true, + other_idx, + )); + + (variants_stmt, variant_visitor) +} + +fn deserialize_externally_tagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let type_name = cattrs.name().deserialize_name(); + let expecting = format!("enum {}", params.type_name()); + + let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs); + + // Match arms to extract a variant from a string + let variant_arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_name = field_i(i); + + let block = Match(deserialize_externally_tagged_variant( + params, variant, cattrs, + )); + + quote! { + (__Field::#variant_name, __variant) => #block + } + }); + + let all_skipped = variants + .iter() + .all(|variant| variant.attrs.skip_deserializing()); + let match_variant = if all_skipped { + // This is an empty enum like `enum Impossible {}` or an enum in which + // all variants have `#[serde(skip_deserializing)]`. + quote! { + // FIXME: Once we drop support for Rust 1.15: + // let _serde::export::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data); + // _serde::export::Err(__err) + _serde::export::Result::map( + _serde::de::EnumAccess::variant::<__Field>(__data), + |(__impossible, _)| match __impossible {}) + } + } else { + quote! { + match try!(_serde::de::EnumAccess::variant(__data)) { + #(#variant_arms)* + } + } + }; + + quote_block! { + #variant_visitor + + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::EnumAccess<#delife>, + { + #match_variant + } + } + + #variants_stmt + + _serde::Deserializer::deserialize_enum( + __deserializer, + #type_name, + VARIANTS, + __Visitor { + marker: _serde::export::PhantomData::<#this #ty_generics>, + lifetime: _serde::export::PhantomData, + }, + ) + } +} + +fn deserialize_internally_tagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, + tag: &str, +) -> Fragment { + let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs); + + // Match arms to extract a variant from a string + let variant_arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_name = field_i(i); + + let block = Match(deserialize_internally_tagged_variant( + params, + variant, + cattrs, + quote! { + _serde::private::de::ContentDeserializer::<__D::Error>::new(__tagged.content) + }, + )); + + quote! { + __Field::#variant_name => #block + } + }); + + quote_block! { + #variant_visitor + + #variants_stmt + + let __tagged = try!(_serde::Deserializer::deserialize_any( + __deserializer, + _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag))); + + match __tagged.tag { + #(#variant_arms)* + } + } +} + +fn deserialize_adjacently_tagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, + tag: &str, + content: &str, +) -> Fragment { + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs); + + let variant_arms: &Vec<_> = &variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_index = field_i(i); + + let block = Match(deserialize_untagged_variant( + params, + variant, + cattrs, + quote!(__deserializer), + )); + + quote! { + __Field::#variant_index => #block + } + }) + .collect(); + + let expecting = format!("adjacently tagged enum {}", params.type_name()); + let type_name = cattrs.name().deserialize_name(); + let deny_unknown_fields = cattrs.deny_unknown_fields(); + + // If unknown fields are allowed, we pick the visitor that can step over + // those. Otherwise we pick the visitor that fails on unknown keys. + let field_visitor_ty = if deny_unknown_fields { + quote! { _serde::private::de::TagOrContentFieldVisitor } + } else { + quote! { _serde::private::de::TagContentOtherFieldVisitor } + }; + + let tag_or_content = quote! { + #field_visitor_ty { + tag: #tag, + content: #content, + } + }; + + let mut missing_content = quote! { + _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#content)) + }; + let mut missing_content_fallthrough = quote!(); + let missing_content_arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .filter_map(|(i, variant)| { + let variant_index = field_i(i); + let variant_ident = &variant.ident; + + let arm = match variant.style { + Style::Unit => quote! { + _serde::export::Ok(#this::#variant_ident) + }, + Style::Newtype if variant.attrs.deserialize_with().is_none() => { + let span = variant.original.span(); + let func = quote_spanned!(span=> _serde::private::de::missing_field); + quote! { + #func(#content).map(#this::#variant_ident) + } + } + _ => { + missing_content_fallthrough = quote!(_ => #missing_content); + return None; + } + }; + Some(quote! { + __Field::#variant_index => #arm, + }) + }) + .collect::<Vec<_>>(); + if !missing_content_arms.is_empty() { + missing_content = quote! { + match __field { + #(#missing_content_arms)* + #missing_content_fallthrough + } + }; + } + + // Advance the map by one key, returning early in case of error. + let next_key = quote! { + try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) + }; + + // When allowing unknown fields, we want to transparently step through keys + // we don't care about until we find `tag`, `content`, or run out of keys. + let next_relevant_key = if deny_unknown_fields { + next_key + } else { + quote!({ + let mut __rk : _serde::export::Option<_serde::private::de::TagOrContentField> = _serde::export::None; + while let _serde::export::Some(__k) = #next_key { + match __k { + _serde::private::de::TagContentOtherField::Other => { + try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); + continue; + }, + _serde::private::de::TagContentOtherField::Tag => { + __rk = _serde::export::Some(_serde::private::de::TagOrContentField::Tag); + break; + } + _serde::private::de::TagContentOtherField::Content => { + __rk = _serde::export::Some(_serde::private::de::TagOrContentField::Content); + break; + } + } + } + + __rk + }) + }; + + // Step through remaining keys, looking for duplicates of previously-seen + // keys. When unknown fields are denied, any key that isn't a duplicate will + // at this point immediately produce an error. + let visit_remaining_keys = quote! { + match #next_relevant_key { + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) + } + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) + } + _serde::export::None => _serde::export::Ok(__ret), + } + }; + + let finish_content_then_tag = if variant_arms.is_empty() { + quote! { + match try!(_serde::de::MapAccess::next_value::<__Field>(&mut __map)) {} + } + } else { + quote! { + let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) { + // Deserialize the buffered content now that we know the variant. + #(#variant_arms)* + }); + // Visit remaining keys, looking for duplicates. + #visit_remaining_keys + } + }; + + quote_block! { + #variant_visitor + + #variants_stmt + + struct __Seed #de_impl_generics #where_clause { + field: __Field, + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error> + where + __D: _serde::Deserializer<#delife>, + { + match self.field { + #(#variant_arms)* + } + } + } + + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::MapAccess<#delife>, + { + // Visit the first relevant key. + match #next_relevant_key { + // First key is the tag. + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { + // Parse the tag. + let __field = try!(_serde::de::MapAccess::next_value(&mut __map)); + // Visit the second key. + match #next_relevant_key { + // Second key is a duplicate of the tag. + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) + } + // Second key is the content. + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { + let __ret = try!(_serde::de::MapAccess::next_value_seed(&mut __map, + __Seed { + field: __field, + marker: _serde::export::PhantomData, + lifetime: _serde::export::PhantomData, + })); + // Visit remaining keys, looking for duplicates. + #visit_remaining_keys + } + // There is no second key; might be okay if the we have a unit variant. + _serde::export::None => #missing_content + } + } + // First key is the content. + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { + // Buffer up the content. + let __content = try!(_serde::de::MapAccess::next_value::<_serde::private::de::Content>(&mut __map)); + // Visit the second key. + match #next_relevant_key { + // Second key is the tag. + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { + let __deserializer = _serde::private::de::ContentDeserializer::<__A::Error>::new(__content); + #finish_content_then_tag + } + // Second key is a duplicate of the content. + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) + } + // There is no second key. + _serde::export::None => { + _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) + } + } + } + // There is no first key. + _serde::export::None => { + _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) + } + } + } + + fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error> + where + __A: _serde::de::SeqAccess<#delife>, + { + // Visit the first element - the tag. + match try!(_serde::de::SeqAccess::next_element(&mut __seq)) { + _serde::export::Some(__field) => { + // Visit the second element - the content. + match try!(_serde::de::SeqAccess::next_element_seed( + &mut __seq, + __Seed { + field: __field, + marker: _serde::export::PhantomData, + lifetime: _serde::export::PhantomData, + }, + )) { + _serde::export::Some(__ret) => _serde::export::Ok(__ret), + // There is no second element. + _serde::export::None => { + _serde::export::Err(_serde::de::Error::invalid_length(1, &self)) + } + } + } + // There is no first element. + _serde::export::None => { + _serde::export::Err(_serde::de::Error::invalid_length(0, &self)) + } + } + } + } + + const FIELDS: &'static [&'static str] = &[#tag, #content]; + _serde::Deserializer::deserialize_struct( + __deserializer, + #type_name, + FIELDS, + __Visitor { + marker: _serde::export::PhantomData::<#this #ty_generics>, + lifetime: _serde::export::PhantomData, + }, + ) + } +} + +fn deserialize_untagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let attempts = variants + .iter() + .filter(|variant| !variant.attrs.skip_deserializing()) + .map(|variant| { + Expr(deserialize_untagged_variant( + params, + variant, + cattrs, + quote!(_serde::private::de::ContentRefDeserializer::<__D::Error>::new(&__content)), + )) + }); + + // TODO this message could be better by saving the errors from the failed + // attempts. The heuristic used by TOML was to count the number of fields + // processed before an error, and use the error that happened after the + // largest number of fields. I'm not sure I like that. Maybe it would be + // better to save all the errors and combine them into one message that + // explains why none of the variants matched. + let fallthrough_msg = format!( + "data did not match any variant of untagged enum {}", + params.type_name() + ); + + quote_block! { + let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); + + #( + if let _serde::export::Ok(__ok) = #attempts { + return _serde::export::Ok(__ok); + } + )* + + _serde::export::Err(_serde::de::Error::custom(#fallthrough_msg)) + } +} + +fn deserialize_externally_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, +) -> Fragment { + if let Some(path) = variant.attrs.deserialize_with() { + let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path); + return quote_block! { + #wrapper + _serde::export::Result::map( + _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn) + }; + } + + let variant_ident = &variant.ident; + + match variant.style { + Style::Unit => { + let this = ¶ms.this; + quote_block! { + try!(_serde::de::VariantAccess::unit_variant(__variant)); + _serde::export::Ok(#this::#variant_ident) + } + } + Style::Newtype => deserialize_externally_tagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + cattrs, + ), + Style::Tuple => { + deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None) + } + Style::Struct => deserialize_struct( + Some(variant_ident), + params, + &variant.fields, + cattrs, + None, + &Untagged::No, + ), + } +} + +fn deserialize_internally_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + deserializer: TokenStream, +) -> Fragment { + if variant.attrs.deserialize_with().is_some() { + return deserialize_untagged_variant(params, variant, cattrs, deserializer); + } + + let variant_ident = &variant.ident; + + match effective_style(variant) { + Style::Unit => { + let this = ¶ms.this; + let type_name = params.type_name(); + let variant_name = variant.ident.to_string(); + let default = variant.fields.get(0).map(|field| { + let default = Expr(expr_is_missing(field, cattrs)); + quote!((#default)) + }); + quote_block! { + try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); + _serde::export::Ok(#this::#variant_ident #default) + } + } + Style::Newtype => deserialize_untagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + &deserializer, + ), + Style::Struct => deserialize_struct( + Some(variant_ident), + params, + &variant.fields, + cattrs, + Some(deserializer), + &Untagged::No, + ), + Style::Tuple => unreachable!("checked in serde_derive_internals"), + } +} + +fn deserialize_untagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + deserializer: TokenStream, +) -> Fragment { + if let Some(path) = variant.attrs.deserialize_with() { + let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path); + return quote_block! { + #wrapper + _serde::export::Result::map( + <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn) + }; + } + + let variant_ident = &variant.ident; + + match effective_style(variant) { + Style::Unit => { + let this = ¶ms.this; + let type_name = params.type_name(); + let variant_name = variant.ident.to_string(); + let default = variant.fields.get(0).map(|field| { + let default = Expr(expr_is_missing(field, cattrs)); + quote!((#default)) + }); + quote_expr! { + match _serde::Deserializer::deserialize_any( + #deserializer, + _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) + ) { + _serde::export::Ok(()) => _serde::export::Ok(#this::#variant_ident #default), + _serde::export::Err(__err) => _serde::export::Err(__err), + } + } + } + Style::Newtype => deserialize_untagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + &deserializer, + ), + Style::Tuple => deserialize_tuple( + Some(variant_ident), + params, + &variant.fields, + cattrs, + Some(deserializer), + ), + Style::Struct => deserialize_struct( + Some(variant_ident), + params, + &variant.fields, + cattrs, + Some(deserializer), + &Untagged::Yes, + ), + } +} + +fn deserialize_externally_tagged_newtype_variant( + variant_ident: &syn::Ident, + params: &Parameters, + field: &Field, + cattrs: &attr::Container, +) -> Fragment { + let this = ¶ms.this; + + if field.attrs.skip_deserializing() { + let this = ¶ms.this; + let default = Expr(expr_is_missing(field, cattrs)); + return quote_block! { + try!(_serde::de::VariantAccess::unit_variant(__variant)); + _serde::export::Ok(#this::#variant_ident(#default)) + }; + } + + match field.attrs.deserialize_with() { + None => { + let field_ty = field.ty; + let span = field.original.span(); + let func = + quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>); + quote_expr! { + _serde::export::Result::map(#func(__variant), #this::#variant_ident) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote_block! { + #wrapper + _serde::export::Result::map( + _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), + |__wrapper| #this::#variant_ident(__wrapper.value)) + } + } + } +} + +fn deserialize_untagged_newtype_variant( + variant_ident: &syn::Ident, + params: &Parameters, + field: &Field, + deserializer: &TokenStream, +) -> Fragment { + let this = ¶ms.this; + let field_ty = field.ty; + match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); + quote_expr! { + _serde::export::Result::map(#func(#deserializer), #this::#variant_ident) + } + } + Some(path) => { + quote_block! { + let __value: _serde::export::Result<#field_ty, _> = #path(#deserializer); + _serde::export::Result::map(__value, #this::#variant_ident) + } + } + } +} + +fn deserialize_generated_identifier( + fields: &[(String, Ident, Vec<String>)], + cattrs: &attr::Container, + is_variant: bool, + other_idx: Option<usize>, +) -> Fragment { + let this = quote!(__Field); + let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect(); + + let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() { + let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),); + let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value))); + (Some(ignore_variant), Some(fallthrough)) + } else if let Some(other_idx) = other_idx { + let ignore_variant = fields[other_idx].1.clone(); + let fallthrough = quote!(_serde::export::Ok(__Field::#ignore_variant)); + (None, Some(fallthrough)) + } else if is_variant || cattrs.deny_unknown_fields() { + (None, None) + } else { + let ignore_variant = quote!(__ignore,); + let fallthrough = quote!(_serde::export::Ok(__Field::__ignore)); + (Some(ignore_variant), Some(fallthrough)) + }; + + let visitor_impl = Stmts(deserialize_identifier( + &this, + fields, + is_variant, + fallthrough, + !is_variant && cattrs.has_flatten(), + )); + + let lifetime = if !is_variant && cattrs.has_flatten() { + Some(quote!(<'de>)) + } else { + None + }; + + quote_block! { + #[allow(non_camel_case_types)] + enum __Field #lifetime { + #(#field_idents,)* + #ignore_variant + } + + struct __FieldVisitor; + + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field #lifetime; + + #visitor_impl + } + + impl<'de> _serde::Deserialize<'de> for __Field #lifetime { + #[inline] + fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error> + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) + } + } + } +} + +fn deserialize_custom_identifier( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let is_variant = match cattrs.identifier() { + attr::Identifier::Variant => true, + attr::Identifier::Field => false, + attr::Identifier::No => unreachable!(), + }; + + let this = ¶ms.this; + let this = quote!(#this); + + let (ordinary, fallthrough) = if let Some(last) = variants.last() { + let last_ident = &last.ident; + if last.attrs.other() { + let ordinary = &variants[..variants.len() - 1]; + let fallthrough = quote!(_serde::export::Ok(#this::#last_ident)); + (ordinary, Some(fallthrough)) + } else if let Style::Newtype = last.style { + let ordinary = &variants[..variants.len() - 1]; + let deserializer = quote!(_serde::private::de::IdentifierDeserializer::from(__value)); + let fallthrough = quote! { + _serde::export::Result::map( + _serde::Deserialize::deserialize(#deserializer), + #this::#last_ident) + }; + (ordinary, Some(fallthrough)) + } else { + (variants, None) + } + } else { + (variants, None) + }; + + let names_idents: Vec<_> = ordinary + .iter() + .map(|variant| { + ( + variant.attrs.name().deserialize_name(), + variant.ident.clone(), + variant.attrs.aliases(), + ) + }) + .collect(); + + let names = names_idents.iter().map(|(name, _, _)| name); + + let names_const = if fallthrough.is_some() { + None + } else if is_variant { + let variants = quote! { + const VARIANTS: &'static [&'static str] = &[ #(#names),* ]; + }; + Some(variants) + } else { + let fields = quote! { + const FIELDS: &'static [&'static str] = &[ #(#names),* ]; + }; + Some(fields) + }; + + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + let visitor_impl = Stmts(deserialize_identifier( + &this, + &names_idents, + is_variant, + fallthrough, + false, + )); + + quote_block! { + #names_const + + struct __FieldVisitor #de_impl_generics #where_clause { + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + #visitor_impl + } + + let __visitor = __FieldVisitor { + marker: _serde::export::PhantomData::<#this #ty_generics>, + lifetime: _serde::export::PhantomData, + }; + _serde::Deserializer::deserialize_identifier(__deserializer, __visitor) + } +} + +fn deserialize_identifier( + this: &TokenStream, + fields: &[(String, Ident, Vec<String>)], + is_variant: bool, + fallthrough: Option<TokenStream>, + collect_other_fields: bool, +) -> Fragment { + let mut flat_fields = Vec::new(); + for (_, ident, aliases) in fields { + flat_fields.extend(aliases.iter().map(|alias| (alias, ident))) + } + + let field_strs = flat_fields.iter().map(|(name, _)| name); + let field_borrowed_strs = flat_fields.iter().map(|(name, _)| name); + let field_bytes = flat_fields + .iter() + .map(|(name, _)| Literal::byte_string(name.as_bytes())); + let field_borrowed_bytes = flat_fields + .iter() + .map(|(name, _)| Literal::byte_string(name.as_bytes())); + + let constructors: &Vec<_> = &flat_fields + .iter() + .map(|(_, ident)| quote!(#this::#ident)) + .collect(); + let main_constructors: &Vec<_> = &fields + .iter() + .map(|(_, ident, _)| quote!(#this::#ident)) + .collect(); + + let expecting = if is_variant { + "variant identifier" + } else { + "field identifier" + }; + + let index_expecting = if is_variant { "variant" } else { "field" }; + + let bytes_to_str = if fallthrough.is_some() || collect_other_fields { + None + } else { + Some(quote! { + let __value = &_serde::export::from_utf8_lossy(__value); + }) + }; + + let ( + value_as_str_content, + value_as_borrowed_str_content, + value_as_bytes_content, + value_as_borrowed_bytes_content, + ) = if collect_other_fields { + ( + Some(quote! { + let __value = _serde::private::de::Content::String(_serde::export::ToString::to_string(__value)); + }), + Some(quote! { + let __value = _serde::private::de::Content::Str(__value); + }), + Some(quote! { + let __value = _serde::private::de::Content::ByteBuf(__value.to_vec()); + }), + Some(quote! { + let __value = _serde::private::de::Content::Bytes(__value); + }), + ) + } else { + (None, None, None, None) + }; + + let fallthrough_arm = if let Some(fallthrough) = fallthrough { + fallthrough + } else if is_variant { + quote! { + _serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS)) + } + } else { + quote! { + _serde::export::Err(_serde::de::Error::unknown_field(__value, FIELDS)) + } + }; + + let variant_indices = 0_u64..; + let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); + let visit_other = if collect_other_fields { + quote! { + fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value))) + } + + fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value))) + } + + fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value))) + } + + fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value))) + } + + fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value))) + } + + fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value))) + } + + fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value))) + } + + fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value))) + } + + fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value))) + } + + fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value))) + } + + fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value))) + } + + fn visit_char<__E>(self, __value: char) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value))) + } + + fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + _serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit)) + } + + fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + match __value { + #( + #field_borrowed_strs => _serde::export::Ok(#constructors), + )* + _ => { + #value_as_borrowed_str_content + #fallthrough_arm + } + } + } + + fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + match __value { + #( + #field_borrowed_bytes => _serde::export::Ok(#constructors), + )* + _ => { + #bytes_to_str + #value_as_borrowed_bytes_content + #fallthrough_arm + } + } + } + } + } else { + quote! { + fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + match __value { + #( + #variant_indices => _serde::export::Ok(#main_constructors), + )* + _ => _serde::export::Err(_serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &#fallthrough_msg, + )) + } + } + } + }; + + quote_block! { + fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(__formatter, #expecting) + } + + #visit_other + + fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + match __value { + #( + #field_strs => _serde::export::Ok(#constructors), + )* + _ => { + #value_as_str_content + #fallthrough_arm + } + } + } + + fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<Self::Value, __E> + where + __E: _serde::de::Error, + { + match __value { + #( + #field_bytes => _serde::export::Ok(#constructors), + )* + _ => { + #bytes_to_str + #value_as_bytes_content + #fallthrough_arm + } + } + } + } +} + +fn deserialize_struct_as_struct_visitor( + struct_path: &TokenStream, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> (Fragment, Option<Fragment>, Fragment) { + assert!(!cattrs.has_flatten()); + + let field_names_idents: Vec<_> = fields + .iter() + .enumerate() + .filter(|&(_, field)| !field.attrs.skip_deserializing()) + .map(|(i, field)| { + ( + field.attrs.name().deserialize_name(), + field_i(i), + field.attrs.aliases(), + ) + }) + .collect(); + + let fields_stmt = { + let field_names = field_names_idents.iter().map(|(name, _, _)| name); + quote_block! { + const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; + } + }; + + let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); + + let visit_map = deserialize_map(struct_path, params, fields, cattrs); + + (field_visitor, Some(fields_stmt), visit_map) +} + +fn deserialize_struct_as_map_visitor( + struct_path: &TokenStream, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> (Fragment, Option<Fragment>, Fragment) { + let field_names_idents: Vec<_> = fields + .iter() + .enumerate() + .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(i, field)| { + ( + field.attrs.name().deserialize_name(), + field_i(i), + field.attrs.aliases(), + ) + }) + .collect(); + + let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); + + let visit_map = deserialize_map(struct_path, params, fields, cattrs); + + (field_visitor, None, visit_map) +} + +fn deserialize_map( + struct_path: &TokenStream, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + // Create the field names for the fields. + let fields_names: Vec<_> = fields + .iter() + .enumerate() + .map(|(i, field)| (field, field_i(i))) + .collect(); + + // Declare each field that will be deserialized. + let let_values = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(field, name)| { + let field_ty = field.ty; + quote! { + let mut #name: _serde::export::Option<#field_ty> = _serde::export::None; + } + }); + + // Collect contents for flatten fields into a buffer + let let_collect = if cattrs.has_flatten() { + Some(quote! { + let mut __collect = _serde::export::Vec::<_serde::export::Option<( + _serde::private::de::Content, + _serde::private::de::Content + )>>::new(); + }) + } else { + None + }; + + // Match arms to extract a value for a field. + let value_arms = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(field, name)| { + let deser_name = field.attrs.name().deserialize_name(); + + let visit = match field.attrs.deserialize_with() { + None => { + let field_ty = field.ty; + let span = field.original.span(); + let func = + quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>); + quote! { + try!(#func(&mut __map)) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { + _serde::export::Ok(__wrapper) => __wrapper.value, + _serde::export::Err(__err) => { + return _serde::export::Err(__err); + } + } + }) + } + }; + quote! { + __Field::#name => { + if _serde::export::Option::is_some(&#name) { + return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); + } + #name = _serde::export::Some(#visit); + } + } + }); + + // Visit ignored values to consume them + let ignored_arm = if cattrs.has_flatten() { + Some(quote! { + __Field::__other(__name) => { + __collect.push(_serde::export::Some(( + __name, + try!(_serde::de::MapAccess::next_value(&mut __map))))); + } + }) + } else if cattrs.deny_unknown_fields() { + None + } else { + Some(quote! { + _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } + }) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let match_keys = if cattrs.deny_unknown_fields() && all_skipped { + quote! { + // FIXME: Once we drop support for Rust 1.15: + // let _serde::export::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); + _serde::export::Option::map( + try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), + |__impossible| match __impossible {}); + } + } else { + quote! { + while let _serde::export::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { + match __key { + #(#value_arms)* + #ignored_arm + } + } + } + }; + + let extract_values = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(field, name)| { + let missing_expr = Match(expr_is_missing(field, cattrs)); + + quote! { + let #name = match #name { + _serde::export::Some(#name) => #name, + _serde::export::None => #missing_expr + }; + } + }); + + let extract_collected = fields_names + .iter() + .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing()) + .map(|(field, name)| { + let field_ty = field.ty; + let func = match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + quote_spanned!(span=> _serde::de::Deserialize::deserialize) + } + Some(path) => quote!(#path), + }; + quote! { + let #name: #field_ty = try!(#func( + _serde::private::de::FlatMapDeserializer( + &mut __collect, + _serde::export::PhantomData))); + } + }); + + let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() { + Some(quote! { + if let _serde::export::Some(_serde::export::Some((__key, _))) = + __collect.into_iter().filter(_serde::export::Option::is_some).next() + { + if let _serde::export::Some(__key) = __key.as_str() { + return _serde::export::Err( + _serde::de::Error::custom(format_args!("unknown field `{}`", &__key))); + } else { + return _serde::export::Err( + _serde::de::Error::custom(format_args!("unexpected map key"))); + } + } + }) + } else { + None + }; + + let result = fields_names.iter().map(|(field, name)| { + let member = &field.member; + if field.attrs.skip_deserializing() { + let value = Expr(expr_is_missing(field, cattrs)); + quote!(#member: #value) + } else { + quote!(#member: #name) + } + }); + + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: Self::Value = _serde::export::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: Self::Value = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + let mut result = quote!(#struct_path { #(#result),* }); + if params.has_getter { + let this = ¶ms.this; + result = quote! { + _serde::export::Into::<#this>::into(#result) + }; + } + + quote_block! { + #(#let_values)* + + #let_collect + + #match_keys + + #let_default + + #(#extract_values)* + + #(#extract_collected)* + + #collected_deny_unknown_fields + + _serde::export::Ok(#result) + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_struct_as_struct_in_place_visitor( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> (Fragment, Fragment, Fragment) { + assert!(!cattrs.has_flatten()); + + let field_names_idents: Vec<_> = fields + .iter() + .enumerate() + .filter(|&(_, field)| !field.attrs.skip_deserializing()) + .map(|(i, field)| { + ( + field.attrs.name().deserialize_name(), + field_i(i), + field.attrs.aliases(), + ) + }) + .collect(); + + let fields_stmt = { + let field_names = field_names_idents.iter().map(|(name, _, _)| name); + quote_block! { + const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; + } + }; + + let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); + + let visit_map = deserialize_map_in_place(params, fields, cattrs); + + (field_visitor, fields_stmt, visit_map) +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_map_in_place( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + assert!(!cattrs.has_flatten()); + + // Create the field names for the fields. + let fields_names: Vec<_> = fields + .iter() + .enumerate() + .map(|(i, field)| (field, field_i(i))) + .collect(); + + // For deserialize_in_place, declare booleans for each field that will be + // deserialized. + let let_flags = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|(_, name)| { + quote! { + let mut #name: bool = false; + } + }); + + // Match arms to extract a value for a field. + let value_arms_from = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|(field, name)| { + let deser_name = field.attrs.name().deserialize_name(); + let member = &field.member; + + let visit = match field.attrs.deserialize_with() { + None => { + quote! { + try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::InPlaceSeed(&mut self.place.#member))) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { + _serde::export::Ok(__wrapper) => __wrapper.value, + _serde::export::Err(__err) => { + return _serde::export::Err(__err); + } + }; + }) + } + }; + quote! { + __Field::#name => { + if #name { + return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); + } + #visit; + #name = true; + } + } + }); + + // Visit ignored values to consume them + let ignored_arm = if cattrs.deny_unknown_fields() { + None + } else { + Some(quote! { + _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } + }) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + + let match_keys = if cattrs.deny_unknown_fields() && all_skipped { + quote! { + // FIXME: Once we drop support for Rust 1.15: + // let _serde::export::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); + _serde::export::Option::map( + try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), + |__impossible| match __impossible {}); + } + } else { + quote! { + while let _serde::export::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { + match __key { + #(#value_arms_from)* + #ignored_arm + } + } + } + }; + + let check_flags = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|(field, name)| { + let missing_expr = expr_is_missing(field, cattrs); + // If missing_expr unconditionally returns an error, don't try + // to assign its value to self.place. + if field.attrs.default().is_none() + && cattrs.default().is_none() + && field.attrs.deserialize_with().is_some() + { + let missing_expr = Stmts(missing_expr); + quote! { + if !#name { + #missing_expr; + } + } + } else { + let member = &field.member; + let missing_expr = Expr(missing_expr); + quote! { + if !#name { + self.place.#member = #missing_expr; + }; + } + } + }); + + let this = ¶ms.this; + let (_, _, ty_generics, _) = split_with_de_lifetime(params); + + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: #this #ty_generics = _serde::export::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: #this #ty_generics = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #(#let_flags)* + + #match_keys + + #let_default + + #(#check_flags)* + + _serde::export::Ok(()) + } +} + +fn field_i(i: usize) -> Ident { + Ident::new(&format!("__field{}", i), Span::call_site()) +} + +/// This function wraps the expression in `#[serde(deserialize_with = "...")]` +/// in a trait to prevent it from accessing the internal `Deserialize` state. +fn wrap_deserialize_with( + params: &Parameters, + value_ty: &TokenStream, + deserialize_with: &syn::ExprPath, +) -> (TokenStream, TokenStream) { + let this = ¶ms.this; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let wrapper = quote! { + struct __DeserializeWith #de_impl_generics #where_clause { + value: #value_ty, + phantom: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause { + fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error> + where + __D: _serde::Deserializer<#delife>, + { + _serde::export::Ok(__DeserializeWith { + value: try!(#deserialize_with(__deserializer)), + phantom: _serde::export::PhantomData, + lifetime: _serde::export::PhantomData, + }) + } + } + }; + + let wrapper_ty = quote!(__DeserializeWith #de_ty_generics); + + (wrapper, wrapper_ty) +} + +fn wrap_deserialize_field_with( + params: &Parameters, + field_ty: &syn::Type, + deserialize_with: &syn::ExprPath, +) -> (TokenStream, TokenStream) { + wrap_deserialize_with(params, "e!(#field_ty), deserialize_with) +} + +fn wrap_deserialize_variant_with( + params: &Parameters, + variant: &Variant, + deserialize_with: &syn::ExprPath, +) -> (TokenStream, TokenStream, TokenStream) { + let this = ¶ms.this; + let variant_ident = &variant.ident; + + let field_tys = variant.fields.iter().map(|field| field.ty); + let (wrapper, wrapper_ty) = + wrap_deserialize_with(params, "e!((#(#field_tys),*)), deserialize_with); + + let field_access = (0..variant.fields.len()).map(|n| { + Member::Unnamed(Index { + index: n as u32, + span: Span::call_site(), + }) + }); + let unwrap_fn = match variant.style { + Style::Struct if variant.fields.len() == 1 => { + let member = &variant.fields[0].member; + quote! { + |__wrap| #this::#variant_ident { #member: __wrap.value } + } + } + Style::Struct => { + let members = variant.fields.iter().map(|field| &field.member); + quote! { + |__wrap| #this::#variant_ident { #(#members: __wrap.value.#field_access),* } + } + } + Style::Tuple => quote! { + |__wrap| #this::#variant_ident(#(__wrap.value.#field_access),*) + }, + Style::Newtype => quote! { + |__wrap| #this::#variant_ident(__wrap.value) + }, + Style::Unit => quote! { + |__wrap| #this::#variant_ident + }, + }; + + (wrapper, wrapper_ty, unwrap_fn) +} + +fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { + match field.attrs.default() { + attr::Default::Default => { + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::export::Default::default); + return quote_expr!(#func()); + } + attr::Default::Path(path) => { + return quote_expr!(#path()); + } + attr::Default::None => { /* below */ } + } + + match *cattrs.default() { + attr::Default::Default | attr::Default::Path(_) => { + let member = &field.member; + return quote_expr!(__default.#member); + } + attr::Default::None => { /* below */ } + } + + let name = field.attrs.name().deserialize_name(); + match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::private::de::missing_field); + quote_expr! { + try!(#func(#name)) + } + } + Some(_) => { + quote_expr! { + return _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#name)) + } + } + } +} + +fn effective_style(variant: &Variant) -> Style { + match variant.style { + Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit, + other => other, + } +} + +struct DeImplGenerics<'a>(&'a Parameters); +#[cfg(feature = "deserialize_in_place")] +struct InPlaceImplGenerics<'a>(&'a Parameters); + +impl<'a> ToTokens for DeImplGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut generics = self.0.generics.clone(); + if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() { + generics.params = Some(syn::GenericParam::Lifetime(de_lifetime)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (impl_generics, _, _) = generics.split_for_impl(); + impl_generics.to_tokens(tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> ToTokens for InPlaceImplGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let place_lifetime = place_lifetime(); + let mut generics = self.0.generics.clone(); + + // Add lifetime for `&'place mut Self, and `'a: 'place` + for param in &mut generics.params { + match param { + syn::GenericParam::Lifetime(param) => { + param.bounds.push(place_lifetime.lifetime.clone()); + } + syn::GenericParam::Type(param) => { + param.bounds.push(syn::TypeParamBound::Lifetime( + place_lifetime.lifetime.clone(), + )); + } + syn::GenericParam::Const(_) => {} + } + } + generics.params = Some(syn::GenericParam::Lifetime(place_lifetime)) + .into_iter() + .chain(generics.params) + .collect(); + if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() { + generics.params = Some(syn::GenericParam::Lifetime(de_lifetime)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (impl_generics, _, _) = generics.split_for_impl(); + impl_generics.to_tokens(tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> DeImplGenerics<'a> { + fn in_place(self) -> InPlaceImplGenerics<'a> { + InPlaceImplGenerics(self.0) + } +} + +struct DeTypeGenerics<'a>(&'a Parameters); +#[cfg(feature = "deserialize_in_place")] +struct InPlaceTypeGenerics<'a>(&'a Parameters); + +impl<'a> ToTokens for DeTypeGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut generics = self.0.generics.clone(); + if self.0.borrowed.de_lifetime_def().is_some() { + let def = syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de", Span::call_site()), + colon_token: None, + bounds: Punctuated::new(), + }; + generics.params = Some(syn::GenericParam::Lifetime(def)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (_, ty_generics, _) = generics.split_for_impl(); + ty_generics.to_tokens(tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> ToTokens for InPlaceTypeGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut generics = self.0.generics.clone(); + generics.params = Some(syn::GenericParam::Lifetime(place_lifetime())) + .into_iter() + .chain(generics.params) + .collect(); + + if self.0.borrowed.de_lifetime_def().is_some() { + let def = syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de", Span::call_site()), + colon_token: None, + bounds: Punctuated::new(), + }; + generics.params = Some(syn::GenericParam::Lifetime(def)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (_, ty_generics, _) = generics.split_for_impl(); + ty_generics.to_tokens(tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> DeTypeGenerics<'a> { + fn in_place(self) -> InPlaceTypeGenerics<'a> { + InPlaceTypeGenerics(self.0) + } +} + +#[cfg(feature = "deserialize_in_place")] +fn place_lifetime() -> syn::LifetimeDef { + syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'place", Span::call_site()), + colon_token: None, + bounds: Punctuated::new(), + } +} + +fn split_with_de_lifetime( + params: &Parameters, +) -> ( + DeImplGenerics, + DeTypeGenerics, + syn::TypeGenerics, + Option<&syn::WhereClause>, +) { + let de_impl_generics = DeImplGenerics(params); + let de_ty_generics = DeTypeGenerics(params); + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + (de_impl_generics, de_ty_generics, ty_generics, where_clause) +} diff --git a/third_party/rust/serde_derive/src/dummy.rs b/third_party/rust/serde_derive/src/dummy.rs new file mode 100644 index 0000000000..9a4e5f085f --- /dev/null +++ b/third_party/rust/serde_derive/src/dummy.rs @@ -0,0 +1,48 @@ +use proc_macro2::{Ident, TokenStream}; +use quote::format_ident; + +use syn; +use try; + +pub fn wrap_in_const( + serde_path: Option<&syn::Path>, + trait_: &str, + ty: &Ident, + code: TokenStream, +) -> TokenStream { + let try_replacement = try::replacement(); + + let dummy_const = if cfg!(underscore_consts) { + format_ident!("_") + } else { + format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty)) + }; + + let use_serde = match serde_path { + Some(path) => quote! { + use #path as _serde; + }, + None => quote! { + #[allow(rust_2018_idioms, clippy::useless_attribute)] + extern crate serde as _serde; + }, + }; + + quote! { + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + #use_serde + #try_replacement + #code + }; + } +} + +#[allow(deprecated)] +fn unraw(ident: &Ident) -> String { + // str::trim_start_matches was added in 1.30, trim_left_matches deprecated + // in 1.33. We currently support rustc back to 1.15 so we need to continue + // to use the deprecated one. + ident.to_string().trim_left_matches("r#").to_owned() +} diff --git a/third_party/rust/serde_derive/src/fragment.rs b/third_party/rust/serde_derive/src/fragment.rs new file mode 100644 index 0000000000..324504aa46 --- /dev/null +++ b/third_party/rust/serde_derive/src/fragment.rs @@ -0,0 +1,74 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::token; + +pub enum Fragment { + /// Tokens that can be used as an expression. + Expr(TokenStream), + /// Tokens that can be used inside a block. The surrounding curly braces are + /// not part of these tokens. + Block(TokenStream), +} + +macro_rules! quote_expr { + ($($tt:tt)*) => { + $crate::fragment::Fragment::Expr(quote!($($tt)*)) + } +} + +macro_rules! quote_block { + ($($tt:tt)*) => { + $crate::fragment::Fragment::Block(quote!($($tt)*)) + } +} + +/// Interpolate a fragment in place of an expression. This involves surrounding +/// Block fragments in curly braces. +pub struct Expr(pub Fragment); +impl ToTokens for Expr { + fn to_tokens(&self, out: &mut TokenStream) { + match &self.0 { + Fragment::Expr(expr) => expr.to_tokens(out), + Fragment::Block(block) => { + token::Brace::default().surround(out, |out| block.to_tokens(out)); + } + } + } +} + +/// Interpolate a fragment as the statements of a block. +pub struct Stmts(pub Fragment); +impl ToTokens for Stmts { + fn to_tokens(&self, out: &mut TokenStream) { + match &self.0 { + Fragment::Expr(expr) => expr.to_tokens(out), + Fragment::Block(block) => block.to_tokens(out), + } + } +} + +/// Interpolate a fragment as the value part of a `match` expression. This +/// involves putting a comma after expressions and curly braces around blocks. +pub struct Match(pub Fragment); +impl ToTokens for Match { + fn to_tokens(&self, out: &mut TokenStream) { + match &self.0 { + Fragment::Expr(expr) => { + expr.to_tokens(out); + <Token![,]>::default().to_tokens(out); + } + Fragment::Block(block) => { + token::Brace::default().surround(out, |out| block.to_tokens(out)); + } + } + } +} + +impl AsRef<TokenStream> for Fragment { + fn as_ref(&self) -> &TokenStream { + match self { + Fragment::Expr(expr) => expr, + Fragment::Block(block) => block, + } + } +} diff --git a/third_party/rust/serde_derive/src/internals/ast.rs b/third_party/rust/serde_derive/src/internals/ast.rs new file mode 100644 index 0000000000..1afdaee540 --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/ast.rs @@ -0,0 +1,202 @@ +//! A Serde ast, parsed from the Syn ast and ready to generate Rust code. + +use internals::attr; +use internals::check; +use internals::{Ctxt, Derive}; +use syn; +use syn::punctuated::Punctuated; + +/// A source data structure annotated with `#[derive(Serialize)]` and/or `#[derive(Deserialize)]`, +/// parsed into an internal representation. +pub struct Container<'a> { + /// The struct or enum name (without generics). + pub ident: syn::Ident, + /// Attributes on the structure, parsed for Serde. + pub attrs: attr::Container, + /// The contents of the struct or enum. + pub data: Data<'a>, + /// Any generics on the struct or enum. + pub generics: &'a syn::Generics, + /// Original input. + pub original: &'a syn::DeriveInput, +} + +/// The fields of a struct or enum. +/// +/// Analagous to `syn::Data`. +pub enum Data<'a> { + Enum(Vec<Variant<'a>>), + Struct(Style, Vec<Field<'a>>), +} + +/// A variant of an enum. +pub struct Variant<'a> { + pub ident: syn::Ident, + pub attrs: attr::Variant, + pub style: Style, + pub fields: Vec<Field<'a>>, + pub original: &'a syn::Variant, +} + +/// A field of a struct. +pub struct Field<'a> { + pub member: syn::Member, + pub attrs: attr::Field, + pub ty: &'a syn::Type, + pub original: &'a syn::Field, +} + +#[derive(Copy, Clone)] +pub enum Style { + /// Named fields. + Struct, + /// Many unnamed fields. + Tuple, + /// One unnamed field. + Newtype, + /// No fields. + Unit, +} + +impl<'a> Container<'a> { + /// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`. + pub fn from_ast( + cx: &Ctxt, + item: &'a syn::DeriveInput, + derive: Derive, + ) -> Option<Container<'a>> { + let mut attrs = attr::Container::from_ast(cx, item); + + let mut data = match &item.data { + syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())), + syn::Data::Struct(data) => { + let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default()); + Data::Struct(style, fields) + } + syn::Data::Union(_) => { + cx.error_spanned_by(item, "Serde does not support derive for unions"); + return None; + } + }; + + let mut has_flatten = false; + match &mut data { + Data::Enum(variants) => { + for variant in variants { + variant.attrs.rename_by_rules(attrs.rename_all_rules()); + for field in &mut variant.fields { + if field.attrs.flatten() { + has_flatten = true; + } + field + .attrs + .rename_by_rules(variant.attrs.rename_all_rules()); + } + } + } + Data::Struct(_, fields) => { + for field in fields { + if field.attrs.flatten() { + has_flatten = true; + } + field.attrs.rename_by_rules(attrs.rename_all_rules()); + } + } + } + + if has_flatten { + attrs.mark_has_flatten(); + } + + let mut item = Container { + ident: item.ident.clone(), + attrs, + data, + generics: &item.generics, + original: item, + }; + check::check(cx, &mut item, derive); + Some(item) + } +} + +impl<'a> Data<'a> { + pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> { + match self { + Data::Enum(variants) => { + Box::new(variants.iter().flat_map(|variant| variant.fields.iter())) + } + Data::Struct(_, fields) => Box::new(fields.iter()), + } + } + + pub fn has_getter(&self) -> bool { + self.all_fields().any(|f| f.attrs.getter().is_some()) + } +} + +fn enum_from_ast<'a>( + cx: &Ctxt, + variants: &'a Punctuated<syn::Variant, Token![,]>, + container_default: &attr::Default, +) -> Vec<Variant<'a>> { + variants + .iter() + .map(|variant| { + let attrs = attr::Variant::from_ast(cx, variant); + let (style, fields) = + struct_from_ast(cx, &variant.fields, Some(&attrs), container_default); + Variant { + ident: variant.ident.clone(), + attrs, + style, + fields, + original: variant, + } + }) + .collect() +} + +fn struct_from_ast<'a>( + cx: &Ctxt, + fields: &'a syn::Fields, + attrs: Option<&attr::Variant>, + container_default: &attr::Default, +) -> (Style, Vec<Field<'a>>) { + match fields { + syn::Fields::Named(fields) => ( + Style::Struct, + fields_from_ast(cx, &fields.named, attrs, container_default), + ), + syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => ( + Style::Newtype, + fields_from_ast(cx, &fields.unnamed, attrs, container_default), + ), + syn::Fields::Unnamed(fields) => ( + Style::Tuple, + fields_from_ast(cx, &fields.unnamed, attrs, container_default), + ), + syn::Fields::Unit => (Style::Unit, Vec::new()), + } +} + +fn fields_from_ast<'a>( + cx: &Ctxt, + fields: &'a Punctuated<syn::Field, Token![,]>, + attrs: Option<&attr::Variant>, + container_default: &attr::Default, +) -> Vec<Field<'a>> { + fields + .iter() + .enumerate() + .map(|(i, field)| Field { + member: match &field.ident { + Some(ident) => syn::Member::Named(ident.clone()), + None => syn::Member::Unnamed(i.into()), + }, + attrs: attr::Field::from_ast(cx, i, field, attrs, container_default), + ty: &field.ty, + original: field, + }) + .collect() +} diff --git a/third_party/rust/serde_derive/src/internals/attr.rs b/third_party/rust/serde_derive/src/internals/attr.rs new file mode 100644 index 0000000000..e6f72dfe7f --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/attr.rs @@ -0,0 +1,1961 @@ +use internals::symbol::*; +use internals::{ungroup, Ctxt}; +use proc_macro2::{Group, Span, TokenStream, TokenTree}; +use quote::ToTokens; +use std::borrow::Cow; +use std::collections::BTreeSet; +use std::str::FromStr; +use syn; +use syn::parse::{self, Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::Ident; +use syn::Meta::{List, NameValue, Path}; +use syn::NestedMeta::{Lit, Meta}; + +// This module handles parsing of `#[serde(...)]` attributes. The entrypoints +// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and +// `attr::Field::from_ast`. Each returns an instance of the corresponding +// struct. Note that none of them return a Result. Unrecognized, malformed, or +// duplicated attributes result in a span_err but otherwise are ignored. The +// user will see errors simultaneously for all bad attributes in the crate +// rather than just the first. + +pub use internals::case::RenameRule; + +struct Attr<'c, T> { + cx: &'c Ctxt, + name: Symbol, + tokens: TokenStream, + value: Option<T>, +} + +impl<'c, T> Attr<'c, T> { + fn none(cx: &'c Ctxt, name: Symbol) -> Self { + Attr { + cx, + name, + tokens: TokenStream::new(), + value: None, + } + } + + fn set<A: ToTokens>(&mut self, obj: A, value: T) { + let tokens = obj.into_token_stream(); + + if self.value.is_some() { + self.cx + .error_spanned_by(tokens, format!("duplicate serde attribute `{}`", self.name)); + } else { + self.tokens = tokens; + self.value = Some(value); + } + } + + fn set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>) { + if let Some(value) = value { + self.set(obj, value); + } + } + + fn set_if_none(&mut self, value: T) { + if self.value.is_none() { + self.value = Some(value); + } + } + + fn get(self) -> Option<T> { + self.value + } + + fn get_with_tokens(self) -> Option<(TokenStream, T)> { + match self.value { + Some(v) => Some((self.tokens, v)), + None => None, + } + } +} + +struct BoolAttr<'c>(Attr<'c, ()>); + +impl<'c> BoolAttr<'c> { + fn none(cx: &'c Ctxt, name: Symbol) -> Self { + BoolAttr(Attr::none(cx, name)) + } + + fn set_true<A: ToTokens>(&mut self, obj: A) { + self.0.set(obj, ()); + } + + fn get(&self) -> bool { + self.0.value.is_some() + } +} + +struct VecAttr<'c, T> { + cx: &'c Ctxt, + name: Symbol, + first_dup_tokens: TokenStream, + values: Vec<T>, +} + +impl<'c, T> VecAttr<'c, T> { + fn none(cx: &'c Ctxt, name: Symbol) -> Self { + VecAttr { + cx, + name, + first_dup_tokens: TokenStream::new(), + values: Vec::new(), + } + } + + fn insert<A: ToTokens>(&mut self, obj: A, value: T) { + if self.values.len() == 1 { + self.first_dup_tokens = obj.into_token_stream(); + } + self.values.push(value); + } + + fn at_most_one(mut self) -> Result<Option<T>, ()> { + if self.values.len() > 1 { + let dup_token = self.first_dup_tokens; + self.cx.error_spanned_by( + dup_token, + format!("duplicate serde attribute `{}`", self.name), + ); + Err(()) + } else { + Ok(self.values.pop()) + } + } + + fn get(self) -> Vec<T> { + self.values + } +} + +pub struct Name { + serialize: String, + serialize_renamed: bool, + deserialize: String, + deserialize_renamed: bool, + deserialize_aliases: Vec<String>, +} + +#[allow(deprecated)] +fn unraw(ident: &Ident) -> String { + // str::trim_start_matches was added in 1.30, trim_left_matches deprecated + // in 1.33. We currently support rustc back to 1.15 so we need to continue + // to use the deprecated one. + ident.to_string().trim_left_matches("r#").to_owned() +} + +impl Name { + fn from_attrs( + source_name: String, + ser_name: Attr<String>, + de_name: Attr<String>, + de_aliases: Option<VecAttr<String>>, + ) -> Name { + let deserialize_aliases = match de_aliases { + Some(de_aliases) => { + let mut alias_list = BTreeSet::new(); + for alias_name in de_aliases.get() { + alias_list.insert(alias_name); + } + alias_list.into_iter().collect() + } + None => Vec::new(), + }; + + let ser_name = ser_name.get(); + let ser_renamed = ser_name.is_some(); + let de_name = de_name.get(); + let de_renamed = de_name.is_some(); + Name { + serialize: ser_name.unwrap_or_else(|| source_name.clone()), + serialize_renamed: ser_renamed, + deserialize: de_name.unwrap_or(source_name), + deserialize_renamed: de_renamed, + deserialize_aliases, + } + } + + /// Return the container name for the container when serializing. + pub fn serialize_name(&self) -> String { + self.serialize.clone() + } + + /// Return the container name for the container when deserializing. + pub fn deserialize_name(&self) -> String { + self.deserialize.clone() + } + + fn deserialize_aliases(&self) -> Vec<String> { + let mut aliases = self.deserialize_aliases.clone(); + let main_name = self.deserialize_name(); + if !aliases.contains(&main_name) { + aliases.push(main_name); + } + aliases + } +} + +pub struct RenameAllRules { + serialize: RenameRule, + deserialize: RenameRule, +} + +/// Represents struct or enum attribute information. +pub struct Container { + name: Name, + transparent: bool, + deny_unknown_fields: bool, + default: Default, + rename_all_rules: RenameAllRules, + ser_bound: Option<Vec<syn::WherePredicate>>, + de_bound: Option<Vec<syn::WherePredicate>>, + tag: TagType, + type_from: Option<syn::Type>, + type_try_from: Option<syn::Type>, + type_into: Option<syn::Type>, + remote: Option<syn::Path>, + identifier: Identifier, + has_flatten: bool, + serde_path: Option<syn::Path>, + is_packed: bool, +} + +/// Styles of representing an enum. +pub enum TagType { + /// The default. + /// + /// ```json + /// {"variant1": {"key1": "value1", "key2": "value2"}} + /// ``` + External, + + /// `#[serde(tag = "type")]` + /// + /// ```json + /// {"type": "variant1", "key1": "value1", "key2": "value2"} + /// ``` + Internal { tag: String }, + + /// `#[serde(tag = "t", content = "c")]` + /// + /// ```json + /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}} + /// ``` + Adjacent { tag: String, content: String }, + + /// `#[serde(untagged)]` + /// + /// ```json + /// {"key1": "value1", "key2": "value2"} + /// ``` + None, +} + +/// Whether this enum represents the fields of a struct or the variants of an +/// enum. +#[derive(Copy, Clone)] +pub enum Identifier { + /// It does not. + No, + + /// This enum represents the fields of a struct. All of the variants must be + /// unit variants, except possibly one which is annotated with + /// `#[serde(other)]` and is a newtype variant. + Field, + + /// This enum represents the variants of an enum. All of the variants must + /// be unit variants. + Variant, +} + +impl Identifier { + #[cfg(feature = "deserialize_in_place")] + pub fn is_some(self) -> bool { + match self { + Identifier::No => false, + Identifier::Field | Identifier::Variant => true, + } + } +} + +impl Container { + /// Extract out the `#[serde(...)]` attributes from an item. + pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self { + let mut ser_name = Attr::none(cx, RENAME); + let mut de_name = Attr::none(cx, RENAME); + let mut transparent = BoolAttr::none(cx, TRANSPARENT); + let mut deny_unknown_fields = BoolAttr::none(cx, DENY_UNKNOWN_FIELDS); + let mut default = Attr::none(cx, DEFAULT); + let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL); + let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL); + let mut ser_bound = Attr::none(cx, BOUND); + let mut de_bound = Attr::none(cx, BOUND); + let mut untagged = BoolAttr::none(cx, UNTAGGED); + let mut internal_tag = Attr::none(cx, TAG); + let mut content = Attr::none(cx, CONTENT); + let mut type_from = Attr::none(cx, FROM); + let mut type_try_from = Attr::none(cx, TRY_FROM); + let mut type_into = Attr::none(cx, INTO); + let mut remote = Attr::none(cx, REMOTE); + let mut field_identifier = BoolAttr::none(cx, FIELD_IDENTIFIER); + let mut variant_identifier = BoolAttr::none(cx, VARIANT_IDENTIFIER); + let mut serde_path = Attr::none(cx, CRATE); + + for meta_item in item + .attrs + .iter() + .flat_map(|attr| get_serde_meta_items(cx, attr)) + .flatten() + { + match &meta_item { + // Parse `#[serde(rename = "foo")]` + Meta(NameValue(m)) if m.path == RENAME => { + if let Ok(s) = get_lit_str(cx, RENAME, &m.lit) { + ser_name.set(&m.path, s.value()); + de_name.set(&m.path, s.value()); + } + } + + // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]` + Meta(List(m)) if m.path == RENAME => { + if let Ok((ser, de)) = get_renames(cx, &m.nested) { + ser_name.set_opt(&m.path, ser.map(syn::LitStr::value)); + de_name.set_opt(&m.path, de.map(syn::LitStr::value)); + } + } + + // Parse `#[serde(rename_all = "foo")]` + Meta(NameValue(m)) if m.path == RENAME_ALL => { + if let Ok(s) = get_lit_str(cx, RENAME_ALL, &m.lit) { + match RenameRule::from_str(&s.value()) { + Ok(rename_rule) => { + rename_all_ser_rule.set(&m.path, rename_rule); + rename_all_de_rule.set(&m.path, rename_rule); + } + Err(()) => cx.error_spanned_by( + s, + format!( + "unknown rename rule for #[serde(rename_all = {:?})]", + s.value(), + ), + ), + } + } + } + + // Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]` + Meta(List(m)) if m.path == RENAME_ALL => { + if let Ok((ser, de)) = get_renames(cx, &m.nested) { + if let Some(ser) = ser { + match RenameRule::from_str(&ser.value()) { + Ok(rename_rule) => rename_all_ser_rule.set(&m.path, rename_rule), + Err(()) => cx.error_spanned_by( + ser, + format!( + "unknown rename rule for #[serde(rename_all = {:?})]", + ser.value(), + ), + ), + } + } + if let Some(de) = de { + match RenameRule::from_str(&de.value()) { + Ok(rename_rule) => rename_all_de_rule.set(&m.path, rename_rule), + Err(()) => cx.error_spanned_by( + de, + format!( + "unknown rename rule for #[serde(rename_all = {:?})]", + de.value(), + ), + ), + } + } + } + } + + // Parse `#[serde(transparent)]` + Meta(Path(word)) if word == TRANSPARENT => { + transparent.set_true(word); + } + + // Parse `#[serde(deny_unknown_fields)]` + Meta(Path(word)) if word == DENY_UNKNOWN_FIELDS => { + deny_unknown_fields.set_true(word); + } + + // Parse `#[serde(default)]` + Meta(Path(word)) if word == DEFAULT => match &item.data { + syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { + syn::Fields::Named(_) => { + default.set(word, Default::Default); + } + syn::Fields::Unnamed(_) | syn::Fields::Unit => cx.error_spanned_by( + fields, + "#[serde(default)] can only be used on structs with named fields", + ), + }, + syn::Data::Enum(syn::DataEnum { enum_token, .. }) => cx.error_spanned_by( + enum_token, + "#[serde(default)] can only be used on structs with named fields", + ), + syn::Data::Union(syn::DataUnion { union_token, .. }) => cx.error_spanned_by( + union_token, + "#[serde(default)] can only be used on structs with named fields", + ), + }, + + // Parse `#[serde(default = "...")]` + Meta(NameValue(m)) if m.path == DEFAULT => { + if let Ok(path) = parse_lit_into_expr_path(cx, DEFAULT, &m.lit) { + match &item.data { + syn::Data::Struct(syn::DataStruct { fields, .. }) => { + match fields { + syn::Fields::Named(_) => { + default.set(&m.path, Default::Path(path)); + } + syn::Fields::Unnamed(_) | syn::Fields::Unit => cx + .error_spanned_by( + fields, + "#[serde(default = \"...\")] can only be used on structs with named fields", + ), + } + } + syn::Data::Enum(syn::DataEnum { enum_token, .. }) => cx + .error_spanned_by( + enum_token, + "#[serde(default = \"...\")] can only be used on structs with named fields", + ), + syn::Data::Union(syn::DataUnion { + union_token, .. + }) => cx.error_spanned_by( + union_token, + "#[serde(default = \"...\")] can only be used on structs with named fields", + ), + } + } + } + + // Parse `#[serde(bound = "T: SomeBound")]` + Meta(NameValue(m)) if m.path == BOUND => { + if let Ok(where_predicates) = parse_lit_into_where(cx, BOUND, BOUND, &m.lit) { + ser_bound.set(&m.path, where_predicates.clone()); + de_bound.set(&m.path, where_predicates); + } + } + + // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]` + Meta(List(m)) if m.path == BOUND => { + if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) { + ser_bound.set_opt(&m.path, ser); + de_bound.set_opt(&m.path, de); + } + } + + // Parse `#[serde(untagged)]` + Meta(Path(word)) if word == UNTAGGED => match item.data { + syn::Data::Enum(_) => { + untagged.set_true(word); + } + syn::Data::Struct(syn::DataStruct { struct_token, .. }) => { + cx.error_spanned_by( + struct_token, + "#[serde(untagged)] can only be used on enums", + ); + } + syn::Data::Union(syn::DataUnion { union_token, .. }) => { + cx.error_spanned_by( + union_token, + "#[serde(untagged)] can only be used on enums", + ); + } + }, + + // Parse `#[serde(tag = "type")]` + Meta(NameValue(m)) if m.path == TAG => { + if let Ok(s) = get_lit_str(cx, TAG, &m.lit) { + match &item.data { + syn::Data::Enum(_) => { + internal_tag.set(&m.path, s.value()); + } + syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { + syn::Fields::Named(_) => { + internal_tag.set(&m.path, s.value()); + } + syn::Fields::Unnamed(_) | syn::Fields::Unit => { + cx.error_spanned_by( + fields, + "#[serde(tag = \"...\")] can only be used on enums and structs with named fields", + ); + } + }, + syn::Data::Union(syn::DataUnion { union_token, .. }) => { + cx.error_spanned_by( + union_token, + "#[serde(tag = \"...\")] can only be used on enums and structs with named fields", + ); + } + } + } + } + + // Parse `#[serde(content = "c")]` + Meta(NameValue(m)) if m.path == CONTENT => { + if let Ok(s) = get_lit_str(cx, CONTENT, &m.lit) { + match &item.data { + syn::Data::Enum(_) => { + content.set(&m.path, s.value()); + } + syn::Data::Struct(syn::DataStruct { struct_token, .. }) => { + cx.error_spanned_by( + struct_token, + "#[serde(content = \"...\")] can only be used on enums", + ); + } + syn::Data::Union(syn::DataUnion { union_token, .. }) => { + cx.error_spanned_by( + union_token, + "#[serde(content = \"...\")] can only be used on enums", + ); + } + } + } + } + + // Parse `#[serde(from = "Type")] + Meta(NameValue(m)) if m.path == FROM => { + if let Ok(from_ty) = parse_lit_into_ty(cx, FROM, &m.lit) { + type_from.set_opt(&m.path, Some(from_ty)); + } + } + + // Parse `#[serde(try_from = "Type")] + Meta(NameValue(m)) if m.path == TRY_FROM => { + if let Ok(try_from_ty) = parse_lit_into_ty(cx, TRY_FROM, &m.lit) { + type_try_from.set_opt(&m.path, Some(try_from_ty)); + } + } + + // Parse `#[serde(into = "Type")] + Meta(NameValue(m)) if m.path == INTO => { + if let Ok(into_ty) = parse_lit_into_ty(cx, INTO, &m.lit) { + type_into.set_opt(&m.path, Some(into_ty)); + } + } + + // Parse `#[serde(remote = "...")]` + Meta(NameValue(m)) if m.path == REMOTE => { + if let Ok(path) = parse_lit_into_path(cx, REMOTE, &m.lit) { + if is_primitive_path(&path, "Self") { + remote.set(&m.path, item.ident.clone().into()); + } else { + remote.set(&m.path, path); + } + } + } + + // Parse `#[serde(field_identifier)]` + Meta(Path(word)) if word == FIELD_IDENTIFIER => { + field_identifier.set_true(word); + } + + // Parse `#[serde(variant_identifier)]` + Meta(Path(word)) if word == VARIANT_IDENTIFIER => { + variant_identifier.set_true(word); + } + + // Parse `#[serde(crate = "foo")]` + Meta(NameValue(m)) if m.path == CRATE => { + if let Ok(path) = parse_lit_into_path(cx, CRATE, &m.lit) { + serde_path.set(&m.path, path) + } + } + + Meta(meta_item) => { + let path = meta_item + .path() + .into_token_stream() + .to_string() + .replace(' ', ""); + cx.error_spanned_by( + meta_item.path(), + format!("unknown serde container attribute `{}`", path), + ); + } + + Lit(lit) => { + cx.error_spanned_by(lit, "unexpected literal in serde container attribute"); + } + } + } + + let mut is_packed = false; + for attr in &item.attrs { + if attr.path.is_ident("repr") { + let _ = attr.parse_args_with(|input: ParseStream| { + while let Some(token) = input.parse()? { + if let TokenTree::Ident(ident) = token { + is_packed |= ident == "packed"; + } + } + Ok(()) + }); + } + } + + Container { + name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None), + transparent: transparent.get(), + deny_unknown_fields: deny_unknown_fields.get(), + default: default.get().unwrap_or(Default::None), + rename_all_rules: RenameAllRules { + serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None), + deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None), + }, + ser_bound: ser_bound.get(), + de_bound: de_bound.get(), + tag: decide_tag(cx, item, untagged, internal_tag, content), + type_from: type_from.get(), + type_try_from: type_try_from.get(), + type_into: type_into.get(), + remote: remote.get(), + identifier: decide_identifier(cx, item, field_identifier, variant_identifier), + has_flatten: false, + serde_path: serde_path.get(), + is_packed, + } + } + + pub fn name(&self) -> &Name { + &self.name + } + + pub fn rename_all_rules(&self) -> &RenameAllRules { + &self.rename_all_rules + } + + pub fn transparent(&self) -> bool { + self.transparent + } + + pub fn deny_unknown_fields(&self) -> bool { + self.deny_unknown_fields + } + + pub fn default(&self) -> &Default { + &self.default + } + + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { + self.ser_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { + self.de_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn tag(&self) -> &TagType { + &self.tag + } + + pub fn type_from(&self) -> Option<&syn::Type> { + self.type_from.as_ref() + } + + pub fn type_try_from(&self) -> Option<&syn::Type> { + self.type_try_from.as_ref() + } + + pub fn type_into(&self) -> Option<&syn::Type> { + self.type_into.as_ref() + } + + pub fn remote(&self) -> Option<&syn::Path> { + self.remote.as_ref() + } + + pub fn is_packed(&self) -> bool { + self.is_packed + } + + pub fn identifier(&self) -> Identifier { + self.identifier + } + + pub fn has_flatten(&self) -> bool { + self.has_flatten + } + + pub fn mark_has_flatten(&mut self) { + self.has_flatten = true; + } + + pub fn custom_serde_path(&self) -> Option<&syn::Path> { + self.serde_path.as_ref() + } + + pub fn serde_path(&self) -> Cow<syn::Path> { + self.custom_serde_path() + .map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed) + } +} + +fn decide_tag( + cx: &Ctxt, + item: &syn::DeriveInput, + untagged: BoolAttr, + internal_tag: Attr<String>, + content: Attr<String>, +) -> TagType { + match ( + untagged.0.get_with_tokens(), + internal_tag.get_with_tokens(), + content.get_with_tokens(), + ) { + (None, None, None) => TagType::External, + (Some(_), None, None) => TagType::None, + (None, Some((_, tag)), None) => { + // Check that there are no tuple variants. + if let syn::Data::Enum(data) = &item.data { + for variant in &data.variants { + match &variant.fields { + syn::Fields::Named(_) | syn::Fields::Unit => {} + syn::Fields::Unnamed(fields) => { + if fields.unnamed.len() != 1 { + cx.error_spanned_by( + variant, + "#[serde(tag = \"...\")] cannot be used with tuple variants", + ); + break; + } + } + } + } + } + TagType::Internal { tag } + } + (Some((untagged_tokens, _)), Some((tag_tokens, _)), None) => { + cx.error_spanned_by( + untagged_tokens, + "enum cannot be both untagged and internally tagged", + ); + cx.error_spanned_by( + tag_tokens, + "enum cannot be both untagged and internally tagged", + ); + TagType::External // doesn't matter, will error + } + (None, None, Some((content_tokens, _))) => { + cx.error_spanned_by( + content_tokens, + "#[serde(tag = \"...\", content = \"...\")] must be used together", + ); + TagType::External + } + (Some((untagged_tokens, _)), None, Some((content_tokens, _))) => { + cx.error_spanned_by( + untagged_tokens, + "untagged enum cannot have #[serde(content = \"...\")]", + ); + cx.error_spanned_by( + content_tokens, + "untagged enum cannot have #[serde(content = \"...\")]", + ); + TagType::External + } + (None, Some((_, tag)), Some((_, content))) => TagType::Adjacent { tag, content }, + (Some((untagged_tokens, _)), Some((tag_tokens, _)), Some((content_tokens, _))) => { + cx.error_spanned_by( + untagged_tokens, + "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]", + ); + cx.error_spanned_by( + tag_tokens, + "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]", + ); + cx.error_spanned_by( + content_tokens, + "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]", + ); + TagType::External + } + } +} + +fn decide_identifier( + cx: &Ctxt, + item: &syn::DeriveInput, + field_identifier: BoolAttr, + variant_identifier: BoolAttr, +) -> Identifier { + match ( + &item.data, + field_identifier.0.get_with_tokens(), + variant_identifier.0.get_with_tokens(), + ) { + (_, None, None) => Identifier::No, + (_, Some((field_identifier_tokens, _)), Some((variant_identifier_tokens, _))) => { + cx.error_spanned_by( + field_identifier_tokens, + "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set", + ); + cx.error_spanned_by( + variant_identifier_tokens, + "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set", + ); + Identifier::No + } + (syn::Data::Enum(_), Some(_), None) => Identifier::Field, + (syn::Data::Enum(_), None, Some(_)) => Identifier::Variant, + (syn::Data::Struct(syn::DataStruct { struct_token, .. }), Some(_), None) => { + cx.error_spanned_by( + struct_token, + "#[serde(field_identifier)] can only be used on an enum", + ); + Identifier::No + } + (syn::Data::Union(syn::DataUnion { union_token, .. }), Some(_), None) => { + cx.error_spanned_by( + union_token, + "#[serde(field_identifier)] can only be used on an enum", + ); + Identifier::No + } + (syn::Data::Struct(syn::DataStruct { struct_token, .. }), None, Some(_)) => { + cx.error_spanned_by( + struct_token, + "#[serde(variant_identifier)] can only be used on an enum", + ); + Identifier::No + } + (syn::Data::Union(syn::DataUnion { union_token, .. }), None, Some(_)) => { + cx.error_spanned_by( + union_token, + "#[serde(variant_identifier)] can only be used on an enum", + ); + Identifier::No + } + } +} + +/// Represents variant attribute information +pub struct Variant { + name: Name, + rename_all_rules: RenameAllRules, + ser_bound: Option<Vec<syn::WherePredicate>>, + de_bound: Option<Vec<syn::WherePredicate>>, + skip_deserializing: bool, + skip_serializing: bool, + other: bool, + serialize_with: Option<syn::ExprPath>, + deserialize_with: Option<syn::ExprPath>, + borrow: Option<syn::Meta>, +} + +impl Variant { + pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self { + let mut ser_name = Attr::none(cx, RENAME); + let mut de_name = Attr::none(cx, RENAME); + let mut de_aliases = VecAttr::none(cx, RENAME); + let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING); + let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING); + let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL); + let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL); + let mut ser_bound = Attr::none(cx, BOUND); + let mut de_bound = Attr::none(cx, BOUND); + let mut other = BoolAttr::none(cx, OTHER); + let mut serialize_with = Attr::none(cx, SERIALIZE_WITH); + let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH); + let mut borrow = Attr::none(cx, BORROW); + + for meta_item in variant + .attrs + .iter() + .flat_map(|attr| get_serde_meta_items(cx, attr)) + .flatten() + { + match &meta_item { + // Parse `#[serde(rename = "foo")]` + Meta(NameValue(m)) if m.path == RENAME => { + if let Ok(s) = get_lit_str(cx, RENAME, &m.lit) { + ser_name.set(&m.path, s.value()); + de_name.set_if_none(s.value()); + de_aliases.insert(&m.path, s.value()); + } + } + + // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]` + Meta(List(m)) if m.path == RENAME => { + if let Ok((ser, de)) = get_multiple_renames(cx, &m.nested) { + ser_name.set_opt(&m.path, ser.map(syn::LitStr::value)); + for de_value in de { + de_name.set_if_none(de_value.value()); + de_aliases.insert(&m.path, de_value.value()); + } + } + } + + // Parse `#[serde(alias = "foo")]` + Meta(NameValue(m)) if m.path == ALIAS => { + if let Ok(s) = get_lit_str(cx, ALIAS, &m.lit) { + de_aliases.insert(&m.path, s.value()); + } + } + + // Parse `#[serde(rename_all = "foo")]` + Meta(NameValue(m)) if m.path == RENAME_ALL => { + if let Ok(s) = get_lit_str(cx, RENAME_ALL, &m.lit) { + match RenameRule::from_str(&s.value()) { + Ok(rename_rule) => { + rename_all_ser_rule.set(&m.path, rename_rule); + rename_all_de_rule.set(&m.path, rename_rule); + } + Err(()) => cx.error_spanned_by( + s, + format!( + "unknown rename rule for #[serde(rename_all = {:?})]", + s.value() + ), + ), + } + } + } + + // Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]` + Meta(List(m)) if m.path == RENAME_ALL => { + if let Ok((ser, de)) = get_renames(cx, &m.nested) { + if let Some(ser) = ser { + match RenameRule::from_str(&ser.value()) { + Ok(rename_rule) => rename_all_ser_rule.set(&m.path, rename_rule), + Err(()) => cx.error_spanned_by( + ser, + format!( + "unknown rename rule for #[serde(rename_all = {:?})]", + ser.value(), + ), + ), + } + } + if let Some(de) = de { + match RenameRule::from_str(&de.value()) { + Ok(rename_rule) => rename_all_de_rule.set(&m.path, rename_rule), + Err(()) => cx.error_spanned_by( + de, + format!( + "unknown rename rule for #[serde(rename_all = {:?})]", + de.value(), + ), + ), + } + } + } + } + + // Parse `#[serde(skip)]` + Meta(Path(word)) if word == SKIP => { + skip_serializing.set_true(word); + skip_deserializing.set_true(word); + } + + // Parse `#[serde(skip_deserializing)]` + Meta(Path(word)) if word == SKIP_DESERIALIZING => { + skip_deserializing.set_true(word); + } + + // Parse `#[serde(skip_serializing)]` + Meta(Path(word)) if word == SKIP_SERIALIZING => { + skip_serializing.set_true(word); + } + + // Parse `#[serde(other)]` + Meta(Path(word)) if word == OTHER => { + other.set_true(word); + } + + // Parse `#[serde(bound = "T: SomeBound")]` + Meta(NameValue(m)) if m.path == BOUND => { + if let Ok(where_predicates) = parse_lit_into_where(cx, BOUND, BOUND, &m.lit) { + ser_bound.set(&m.path, where_predicates.clone()); + de_bound.set(&m.path, where_predicates); + } + } + + // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]` + Meta(List(m)) if m.path == BOUND => { + if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) { + ser_bound.set_opt(&m.path, ser); + de_bound.set_opt(&m.path, de); + } + } + + // Parse `#[serde(with = "...")]` + Meta(NameValue(m)) if m.path == WITH => { + if let Ok(path) = parse_lit_into_expr_path(cx, WITH, &m.lit) { + let mut ser_path = path.clone(); + ser_path + .path + .segments + .push(Ident::new("serialize", Span::call_site()).into()); + serialize_with.set(&m.path, ser_path); + let mut de_path = path; + de_path + .path + .segments + .push(Ident::new("deserialize", Span::call_site()).into()); + deserialize_with.set(&m.path, de_path); + } + } + + // Parse `#[serde(serialize_with = "...")]` + Meta(NameValue(m)) if m.path == SERIALIZE_WITH => { + if let Ok(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &m.lit) { + serialize_with.set(&m.path, path); + } + } + + // Parse `#[serde(deserialize_with = "...")]` + Meta(NameValue(m)) if m.path == DESERIALIZE_WITH => { + if let Ok(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &m.lit) { + deserialize_with.set(&m.path, path); + } + } + + // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]` + Meta(m) if m.path() == BORROW => match &variant.fields { + syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => { + borrow.set(m.path(), m.clone()); + } + _ => { + cx.error_spanned_by( + variant, + "#[serde(borrow)] may only be used on newtype variants", + ); + } + }, + + Meta(meta_item) => { + let path = meta_item + .path() + .into_token_stream() + .to_string() + .replace(' ', ""); + cx.error_spanned_by( + meta_item.path(), + format!("unknown serde variant attribute `{}`", path), + ); + } + + Lit(lit) => { + cx.error_spanned_by(lit, "unexpected literal in serde variant attribute"); + } + } + } + + Variant { + name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)), + rename_all_rules: RenameAllRules { + serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None), + deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None), + }, + ser_bound: ser_bound.get(), + de_bound: de_bound.get(), + skip_deserializing: skip_deserializing.get(), + skip_serializing: skip_serializing.get(), + other: other.get(), + serialize_with: serialize_with.get(), + deserialize_with: deserialize_with.get(), + borrow: borrow.get(), + } + } + + pub fn name(&self) -> &Name { + &self.name + } + + pub fn aliases(&self) -> Vec<String> { + self.name.deserialize_aliases() + } + + pub fn rename_by_rules(&mut self, rules: &RenameAllRules) { + if !self.name.serialize_renamed { + self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize); + } + if !self.name.deserialize_renamed { + self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize); + } + } + + pub fn rename_all_rules(&self) -> &RenameAllRules { + &self.rename_all_rules + } + + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { + self.ser_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { + self.de_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn skip_deserializing(&self) -> bool { + self.skip_deserializing + } + + pub fn skip_serializing(&self) -> bool { + self.skip_serializing + } + + pub fn other(&self) -> bool { + self.other + } + + pub fn serialize_with(&self) -> Option<&syn::ExprPath> { + self.serialize_with.as_ref() + } + + pub fn deserialize_with(&self) -> Option<&syn::ExprPath> { + self.deserialize_with.as_ref() + } +} + +/// Represents field attribute information +pub struct Field { + name: Name, + skip_serializing: bool, + skip_deserializing: bool, + skip_serializing_if: Option<syn::ExprPath>, + default: Default, + serialize_with: Option<syn::ExprPath>, + deserialize_with: Option<syn::ExprPath>, + ser_bound: Option<Vec<syn::WherePredicate>>, + de_bound: Option<Vec<syn::WherePredicate>>, + borrowed_lifetimes: BTreeSet<syn::Lifetime>, + getter: Option<syn::ExprPath>, + flatten: bool, + transparent: bool, +} + +/// Represents the default to use for a field when deserializing. +pub enum Default { + /// Field must always be specified because it does not have a default. + None, + /// The default is given by `std::default::Default::default()`. + Default, + /// The default is given by this function. + Path(syn::ExprPath), +} + +impl Default { + pub fn is_none(&self) -> bool { + match self { + Default::None => true, + Default::Default | Default::Path(_) => false, + } + } +} + +impl Field { + /// Extract out the `#[serde(...)]` attributes from a struct field. + pub fn from_ast( + cx: &Ctxt, + index: usize, + field: &syn::Field, + attrs: Option<&Variant>, + container_default: &Default, + ) -> Self { + let mut ser_name = Attr::none(cx, RENAME); + let mut de_name = Attr::none(cx, RENAME); + let mut de_aliases = VecAttr::none(cx, RENAME); + let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING); + let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING); + let mut skip_serializing_if = Attr::none(cx, SKIP_SERIALIZING_IF); + let mut default = Attr::none(cx, DEFAULT); + let mut serialize_with = Attr::none(cx, SERIALIZE_WITH); + let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH); + let mut ser_bound = Attr::none(cx, BOUND); + let mut de_bound = Attr::none(cx, BOUND); + let mut borrowed_lifetimes = Attr::none(cx, BORROW); + let mut getter = Attr::none(cx, GETTER); + let mut flatten = BoolAttr::none(cx, FLATTEN); + + let ident = match &field.ident { + Some(ident) => unraw(ident), + None => index.to_string(), + }; + + let variant_borrow = attrs + .and_then(|variant| variant.borrow.as_ref()) + .map(|borrow| Meta(borrow.clone())); + + for meta_item in field + .attrs + .iter() + .flat_map(|attr| get_serde_meta_items(cx, attr)) + .flatten() + .chain(variant_borrow) + { + match &meta_item { + // Parse `#[serde(rename = "foo")]` + Meta(NameValue(m)) if m.path == RENAME => { + if let Ok(s) = get_lit_str(cx, RENAME, &m.lit) { + ser_name.set(&m.path, s.value()); + de_name.set_if_none(s.value()); + de_aliases.insert(&m.path, s.value()); + } + } + + // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]` + Meta(List(m)) if m.path == RENAME => { + if let Ok((ser, de)) = get_multiple_renames(cx, &m.nested) { + ser_name.set_opt(&m.path, ser.map(syn::LitStr::value)); + for de_value in de { + de_name.set_if_none(de_value.value()); + de_aliases.insert(&m.path, de_value.value()); + } + } + } + + // Parse `#[serde(alias = "foo")]` + Meta(NameValue(m)) if m.path == ALIAS => { + if let Ok(s) = get_lit_str(cx, ALIAS, &m.lit) { + de_aliases.insert(&m.path, s.value()); + } + } + + // Parse `#[serde(default)]` + Meta(Path(word)) if word == DEFAULT => { + default.set(word, Default::Default); + } + + // Parse `#[serde(default = "...")]` + Meta(NameValue(m)) if m.path == DEFAULT => { + if let Ok(path) = parse_lit_into_expr_path(cx, DEFAULT, &m.lit) { + default.set(&m.path, Default::Path(path)); + } + } + + // Parse `#[serde(skip_serializing)]` + Meta(Path(word)) if word == SKIP_SERIALIZING => { + skip_serializing.set_true(word); + } + + // Parse `#[serde(skip_deserializing)]` + Meta(Path(word)) if word == SKIP_DESERIALIZING => { + skip_deserializing.set_true(word); + } + + // Parse `#[serde(skip)]` + Meta(Path(word)) if word == SKIP => { + skip_serializing.set_true(word); + skip_deserializing.set_true(word); + } + + // Parse `#[serde(skip_serializing_if = "...")]` + Meta(NameValue(m)) if m.path == SKIP_SERIALIZING_IF => { + if let Ok(path) = parse_lit_into_expr_path(cx, SKIP_SERIALIZING_IF, &m.lit) { + skip_serializing_if.set(&m.path, path); + } + } + + // Parse `#[serde(serialize_with = "...")]` + Meta(NameValue(m)) if m.path == SERIALIZE_WITH => { + if let Ok(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &m.lit) { + serialize_with.set(&m.path, path); + } + } + + // Parse `#[serde(deserialize_with = "...")]` + Meta(NameValue(m)) if m.path == DESERIALIZE_WITH => { + if let Ok(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &m.lit) { + deserialize_with.set(&m.path, path); + } + } + + // Parse `#[serde(with = "...")]` + Meta(NameValue(m)) if m.path == WITH => { + if let Ok(path) = parse_lit_into_expr_path(cx, WITH, &m.lit) { + let mut ser_path = path.clone(); + ser_path + .path + .segments + .push(Ident::new("serialize", Span::call_site()).into()); + serialize_with.set(&m.path, ser_path); + let mut de_path = path; + de_path + .path + .segments + .push(Ident::new("deserialize", Span::call_site()).into()); + deserialize_with.set(&m.path, de_path); + } + } + + // Parse `#[serde(bound = "T: SomeBound")]` + Meta(NameValue(m)) if m.path == BOUND => { + if let Ok(where_predicates) = parse_lit_into_where(cx, BOUND, BOUND, &m.lit) { + ser_bound.set(&m.path, where_predicates.clone()); + de_bound.set(&m.path, where_predicates); + } + } + + // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]` + Meta(List(m)) if m.path == BOUND => { + if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) { + ser_bound.set_opt(&m.path, ser); + de_bound.set_opt(&m.path, de); + } + } + + // Parse `#[serde(borrow)]` + Meta(Path(word)) if word == BORROW => { + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) { + borrowed_lifetimes.set(word, borrowable); + } + } + + // Parse `#[serde(borrow = "'a + 'b")]` + Meta(NameValue(m)) if m.path == BORROW => { + if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, BORROW, &m.lit) { + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) { + for lifetime in &lifetimes { + if !borrowable.contains(lifetime) { + cx.error_spanned_by( + field, + format!( + "field `{}` does not have lifetime {}", + ident, lifetime + ), + ); + } + } + borrowed_lifetimes.set(&m.path, lifetimes); + } + } + } + + // Parse `#[serde(getter = "...")]` + Meta(NameValue(m)) if m.path == GETTER => { + if let Ok(path) = parse_lit_into_expr_path(cx, GETTER, &m.lit) { + getter.set(&m.path, path); + } + } + + // Parse `#[serde(flatten)]` + Meta(Path(word)) if word == FLATTEN => { + flatten.set_true(word); + } + + Meta(meta_item) => { + let path = meta_item + .path() + .into_token_stream() + .to_string() + .replace(' ', ""); + cx.error_spanned_by( + meta_item.path(), + format!("unknown serde field attribute `{}`", path), + ); + } + + Lit(lit) => { + cx.error_spanned_by(lit, "unexpected literal in serde field attribute"); + } + } + } + + // Is skip_deserializing, initialize the field to Default::default() unless a + // different default is specified by `#[serde(default = "...")]` on + // ourselves or our container (e.g. the struct we are in). + if let Default::None = *container_default { + if skip_deserializing.0.value.is_some() { + default.set_if_none(Default::Default); + } + } + + let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default(); + if !borrowed_lifetimes.is_empty() { + // Cow<str> and Cow<[u8]> never borrow by default: + // + // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> + // + // A #[serde(borrow)] attribute enables borrowing that corresponds + // roughly to these impls: + // + // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str> + // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> + if is_cow(&field.ty, is_str) { + let mut path = syn::Path { + leading_colon: None, + segments: Punctuated::new(), + }; + let span = Span::call_site(); + path.segments.push(Ident::new("_serde", span).into()); + path.segments.push(Ident::new("private", span).into()); + path.segments.push(Ident::new("de", span).into()); + path.segments + .push(Ident::new("borrow_cow_str", span).into()); + let expr = syn::ExprPath { + attrs: Vec::new(), + qself: None, + path, + }; + deserialize_with.set_if_none(expr); + } else if is_cow(&field.ty, is_slice_u8) { + let mut path = syn::Path { + leading_colon: None, + segments: Punctuated::new(), + }; + let span = Span::call_site(); + path.segments.push(Ident::new("_serde", span).into()); + path.segments.push(Ident::new("private", span).into()); + path.segments.push(Ident::new("de", span).into()); + path.segments + .push(Ident::new("borrow_cow_bytes", span).into()); + let expr = syn::ExprPath { + attrs: Vec::new(), + qself: None, + path, + }; + deserialize_with.set_if_none(expr); + } + } else if is_implicitly_borrowed(&field.ty) { + // Types &str and &[u8] are always implicitly borrowed. No need for + // a #[serde(borrow)]. + collect_lifetimes(&field.ty, &mut borrowed_lifetimes); + } + + Field { + name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)), + skip_serializing: skip_serializing.get(), + skip_deserializing: skip_deserializing.get(), + skip_serializing_if: skip_serializing_if.get(), + default: default.get().unwrap_or(Default::None), + serialize_with: serialize_with.get(), + deserialize_with: deserialize_with.get(), + ser_bound: ser_bound.get(), + de_bound: de_bound.get(), + borrowed_lifetimes, + getter: getter.get(), + flatten: flatten.get(), + transparent: false, + } + } + + pub fn name(&self) -> &Name { + &self.name + } + + pub fn aliases(&self) -> Vec<String> { + self.name.deserialize_aliases() + } + + pub fn rename_by_rules(&mut self, rules: &RenameAllRules) { + if !self.name.serialize_renamed { + self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize); + } + if !self.name.deserialize_renamed { + self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize); + } + } + + pub fn skip_serializing(&self) -> bool { + self.skip_serializing + } + + pub fn skip_deserializing(&self) -> bool { + self.skip_deserializing + } + + pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> { + self.skip_serializing_if.as_ref() + } + + pub fn default(&self) -> &Default { + &self.default + } + + pub fn serialize_with(&self) -> Option<&syn::ExprPath> { + self.serialize_with.as_ref() + } + + pub fn deserialize_with(&self) -> Option<&syn::ExprPath> { + self.deserialize_with.as_ref() + } + + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { + self.ser_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { + self.de_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> { + &self.borrowed_lifetimes + } + + pub fn getter(&self) -> Option<&syn::ExprPath> { + self.getter.as_ref() + } + + pub fn flatten(&self) -> bool { + self.flatten + } + + pub fn transparent(&self) -> bool { + self.transparent + } + + pub fn mark_transparent(&mut self) { + self.transparent = true; + } +} + +type SerAndDe<T> = (Option<T>, Option<T>); + +fn get_ser_and_de<'a, 'b, T, F>( + cx: &'b Ctxt, + attr_name: Symbol, + metas: &'a Punctuated<syn::NestedMeta, Token![,]>, + f: F, +) -> Result<(VecAttr<'b, T>, VecAttr<'b, T>), ()> +where + T: 'a, + F: Fn(&Ctxt, Symbol, Symbol, &'a syn::Lit) -> Result<T, ()>, +{ + let mut ser_meta = VecAttr::none(cx, attr_name); + let mut de_meta = VecAttr::none(cx, attr_name); + + for meta in metas { + match meta { + Meta(NameValue(meta)) if meta.path == SERIALIZE => { + if let Ok(v) = f(cx, attr_name, SERIALIZE, &meta.lit) { + ser_meta.insert(&meta.path, v); + } + } + + Meta(NameValue(meta)) if meta.path == DESERIALIZE => { + if let Ok(v) = f(cx, attr_name, DESERIALIZE, &meta.lit) { + de_meta.insert(&meta.path, v); + } + } + + _ => { + cx.error_spanned_by( + meta, + format!( + "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`", + attr_name + ), + ); + return Err(()); + } + } + } + + Ok((ser_meta, de_meta)) +} + +fn get_renames<'a>( + cx: &Ctxt, + items: &'a Punctuated<syn::NestedMeta, Token![,]>, +) -> Result<SerAndDe<&'a syn::LitStr>, ()> { + let (ser, de) = get_ser_and_de(cx, RENAME, items, get_lit_str2)?; + Ok((ser.at_most_one()?, de.at_most_one()?)) +} + +fn get_multiple_renames<'a>( + cx: &Ctxt, + items: &'a Punctuated<syn::NestedMeta, Token![,]>, +) -> Result<(Option<&'a syn::LitStr>, Vec<&'a syn::LitStr>), ()> { + let (ser, de) = get_ser_and_de(cx, RENAME, items, get_lit_str2)?; + Ok((ser.at_most_one()?, de.get())) +} + +fn get_where_predicates( + cx: &Ctxt, + items: &Punctuated<syn::NestedMeta, Token![,]>, +) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> { + let (ser, de) = get_ser_and_de(cx, BOUND, items, parse_lit_into_where)?; + Ok((ser.at_most_one()?, de.at_most_one()?)) +} + +pub fn get_serde_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::NestedMeta>, ()> { + if attr.path != SERDE { + return Ok(Vec::new()); + } + + match attr.parse_meta() { + Ok(List(meta)) => Ok(meta.nested.into_iter().collect()), + Ok(other) => { + cx.error_spanned_by(other, "expected #[serde(...)]"); + Err(()) + } + Err(err) => { + cx.syn_error(err); + Err(()) + } + } +} + +fn get_lit_str<'a>(cx: &Ctxt, attr_name: Symbol, lit: &'a syn::Lit) -> Result<&'a syn::LitStr, ()> { + get_lit_str2(cx, attr_name, attr_name, lit) +} + +fn get_lit_str2<'a>( + cx: &Ctxt, + attr_name: Symbol, + meta_item_name: Symbol, + lit: &'a syn::Lit, +) -> Result<&'a syn::LitStr, ()> { + if let syn::Lit::Str(lit) = lit { + Ok(lit) + } else { + cx.error_spanned_by( + lit, + format!( + "expected serde {} attribute to be a string: `{} = \"...\"`", + attr_name, meta_item_name + ), + ); + Err(()) + } +} + +fn parse_lit_into_path(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::Path, ()> { + let string = get_lit_str(cx, attr_name, lit)?; + parse_lit_str(string).map_err(|_| { + cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value())) + }) +} + +fn parse_lit_into_expr_path( + cx: &Ctxt, + attr_name: Symbol, + lit: &syn::Lit, +) -> Result<syn::ExprPath, ()> { + let string = get_lit_str(cx, attr_name, lit)?; + parse_lit_str(string).map_err(|_| { + cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value())) + }) +} + +fn parse_lit_into_where( + cx: &Ctxt, + attr_name: Symbol, + meta_item_name: Symbol, + lit: &syn::Lit, +) -> Result<Vec<syn::WherePredicate>, ()> { + let string = get_lit_str2(cx, attr_name, meta_item_name, lit)?; + if string.value().is_empty() { + return Ok(Vec::new()); + } + + let where_string = syn::LitStr::new(&format!("where {}", string.value()), string.span()); + + parse_lit_str::<syn::WhereClause>(&where_string) + .map(|wh| wh.predicates.into_iter().collect()) + .map_err(|err| cx.error_spanned_by(lit, err)) +} + +fn parse_lit_into_ty(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::Type, ()> { + let string = get_lit_str(cx, attr_name, lit)?; + + parse_lit_str(string).map_err(|_| { + cx.error_spanned_by( + lit, + format!("failed to parse type: {} = {:?}", attr_name, string.value()), + ) + }) +} + +// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of +// lifetimes separated by `+`. +fn parse_lit_into_lifetimes( + cx: &Ctxt, + attr_name: Symbol, + lit: &syn::Lit, +) -> Result<BTreeSet<syn::Lifetime>, ()> { + let string = get_lit_str(cx, attr_name, lit)?; + if string.value().is_empty() { + cx.error_spanned_by(lit, "at least one lifetime must be borrowed"); + return Err(()); + } + + struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>); + + impl Parse for BorrowedLifetimes { + fn parse(input: ParseStream) -> parse::Result<Self> { + Punctuated::parse_separated_nonempty(input).map(BorrowedLifetimes) + } + } + + if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) { + let mut set = BTreeSet::new(); + for lifetime in lifetimes { + if !set.insert(lifetime.clone()) { + cx.error_spanned_by(lit, format!("duplicate borrowed lifetime `{}`", lifetime)); + } + } + return Ok(set); + } + + cx.error_spanned_by( + lit, + format!("failed to parse borrowed lifetimes: {:?}", string.value()), + ); + Err(()) +} + +fn is_implicitly_borrowed(ty: &syn::Type) -> bool { + is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference) +} + +fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool { + is_reference(ty, is_str) || is_reference(ty, is_slice_u8) +} + +// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T". +// This can have false negatives and false positives. +// +// False negative: +// +// use std::borrow::Cow as Pig; +// +// #[derive(Deserialize)] +// struct S<'a> { +// #[serde(borrow)] +// pig: Pig<'a, str>, +// } +// +// False positive: +// +// type str = [i16]; +// +// #[derive(Deserialize)] +// struct S<'a> { +// #[serde(borrow)] +// cow: Cow<'a, str>, +// } +fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool { + let path = match ungroup(ty) { + syn::Type::Path(ty) => &ty.path, + _ => { + return false; + } + }; + let seg = match path.segments.last() { + Some(seg) => seg, + None => { + return false; + } + }; + let args = match &seg.arguments { + syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args, + _ => { + return false; + } + }; + seg.ident == "Cow" + && args.len() == 2 + && match (&args[0], &args[1]) { + (syn::GenericArgument::Lifetime(_), syn::GenericArgument::Type(arg)) => elem(arg), + _ => false, + } +} + +fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool { + let path = match ungroup(ty) { + syn::Type::Path(ty) => &ty.path, + _ => { + return false; + } + }; + let seg = match path.segments.last() { + Some(seg) => seg, + None => { + return false; + } + }; + let args = match &seg.arguments { + syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args, + _ => { + return false; + } + }; + seg.ident == "Option" + && args.len() == 1 + && match &args[0] { + syn::GenericArgument::Type(arg) => elem(arg), + _ => false, + } +} + +// Whether the type looks like it might be `&T` where elem="T". This can have +// false negatives and false positives. +// +// False negative: +// +// type Yarn = str; +// +// #[derive(Deserialize)] +// struct S<'a> { +// r: &'a Yarn, +// } +// +// False positive: +// +// type str = [i16]; +// +// #[derive(Deserialize)] +// struct S<'a> { +// r: &'a str, +// } +fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool { + match ungroup(ty) { + syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem), + _ => false, + } +} + +fn is_str(ty: &syn::Type) -> bool { + is_primitive_type(ty, "str") +} + +fn is_slice_u8(ty: &syn::Type) -> bool { + match ungroup(ty) { + syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"), + _ => false, + } +} + +fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool { + match ungroup(ty) { + syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive), + _ => false, + } +} + +fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool { + path.leading_colon.is_none() + && path.segments.len() == 1 + && path.segments[0].ident == primitive + && path.segments[0].arguments.is_empty() +} + +// All lifetimes that this type could borrow from a Deserializer. +// +// For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand +// a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer. +// +// This is used when there is an explicit or implicit `#[serde(borrow)]` +// attribute on the field so there must be at least one borrowable lifetime. +fn borrowable_lifetimes( + cx: &Ctxt, + name: &str, + field: &syn::Field, +) -> Result<BTreeSet<syn::Lifetime>, ()> { + let mut lifetimes = BTreeSet::new(); + collect_lifetimes(&field.ty, &mut lifetimes); + if lifetimes.is_empty() { + cx.error_spanned_by( + field, + format!("field `{}` has no lifetimes to borrow", name), + ); + Err(()) + } else { + Ok(lifetimes) + } +} + +fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) { + match ty { + syn::Type::Slice(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Array(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Ptr(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Reference(ty) => { + out.extend(ty.lifetime.iter().cloned()); + collect_lifetimes(&ty.elem, out); + } + syn::Type::Tuple(ty) => { + for elem in &ty.elems { + collect_lifetimes(elem, out); + } + } + syn::Type::Path(ty) => { + if let Some(qself) = &ty.qself { + collect_lifetimes(&qself.ty, out); + } + for seg in &ty.path.segments { + if let syn::PathArguments::AngleBracketed(bracketed) = &seg.arguments { + for arg in &bracketed.args { + match arg { + syn::GenericArgument::Lifetime(lifetime) => { + out.insert(lifetime.clone()); + } + syn::GenericArgument::Type(ty) => { + collect_lifetimes(ty, out); + } + syn::GenericArgument::Binding(binding) => { + collect_lifetimes(&binding.ty, out); + } + syn::GenericArgument::Constraint(_) + | syn::GenericArgument::Const(_) => {} + } + } + } + } + } + syn::Type::Paren(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Group(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::BareFn(_) + | syn::Type::Never(_) + | syn::Type::TraitObject(_) + | syn::Type::ImplTrait(_) + | syn::Type::Infer(_) + | syn::Type::Macro(_) + | syn::Type::Verbatim(_) + | _ => {} + } +} + +fn parse_lit_str<T>(s: &syn::LitStr) -> parse::Result<T> +where + T: Parse, +{ + let tokens = spanned_tokens(s)?; + syn::parse2(tokens) +} + +fn spanned_tokens(s: &syn::LitStr) -> parse::Result<TokenStream> { + let stream = syn::parse_str(&s.value())?; + Ok(respan_token_stream(stream, s.span())) +} + +fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream { + stream + .into_iter() + .map(|token| respan_token_tree(token, span)) + .collect() +} + +fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree { + if let TokenTree::Group(g) = &mut token { + *g = Group::new(g.delimiter(), respan_token_stream(g.stream(), span)); + } + token.set_span(span); + token +} diff --git a/third_party/rust/serde_derive/src/internals/case.rs b/third_party/rust/serde_derive/src/internals/case.rs new file mode 100644 index 0000000000..3fcbb32dbd --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/case.rs @@ -0,0 +1,174 @@ +//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the +//! case of the source (e.g. `my-field`, `MY_FIELD`). + +// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726 +#[allow(deprecated, unused_imports)] +use std::ascii::AsciiExt; + +use std::str::FromStr; + +use self::RenameRule::*; + +/// The different possible ways to change case of fields in a struct, or variants in an enum. +#[derive(Copy, Clone, PartialEq)] +pub enum RenameRule { + /// Don't apply a default rename rule. + None, + /// Rename direct children to "lowercase" style. + LowerCase, + /// Rename direct children to "UPPERCASE" style. + UPPERCASE, + /// Rename direct children to "PascalCase" style, as typically used for + /// enum variants. + PascalCase, + /// Rename direct children to "camelCase" style. + CamelCase, + /// Rename direct children to "snake_case" style, as commonly used for + /// fields. + SnakeCase, + /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly + /// used for constants. + ScreamingSnakeCase, + /// Rename direct children to "kebab-case" style. + KebabCase, + /// Rename direct children to "SCREAMING-KEBAB-CASE" style. + ScreamingKebabCase, +} + +impl RenameRule { + /// Apply a renaming rule to an enum variant, returning the version expected in the source. + pub fn apply_to_variant(&self, variant: &str) -> String { + match *self { + None | PascalCase => variant.to_owned(), + LowerCase => variant.to_ascii_lowercase(), + UPPERCASE => variant.to_ascii_uppercase(), + CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..], + SnakeCase => { + let mut snake = String::new(); + for (i, ch) in variant.char_indices() { + if i > 0 && ch.is_uppercase() { + snake.push('_'); + } + snake.push(ch.to_ascii_lowercase()); + } + snake + } + ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(), + KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"), + ScreamingKebabCase => ScreamingSnakeCase + .apply_to_variant(variant) + .replace('_', "-"), + } + } + + /// Apply a renaming rule to a struct field, returning the version expected in the source. + pub fn apply_to_field(&self, field: &str) -> String { + match *self { + None | LowerCase | SnakeCase => field.to_owned(), + UPPERCASE => field.to_ascii_uppercase(), + PascalCase => { + let mut pascal = String::new(); + let mut capitalize = true; + for ch in field.chars() { + if ch == '_' { + capitalize = true; + } else if capitalize { + pascal.push(ch.to_ascii_uppercase()); + capitalize = false; + } else { + pascal.push(ch); + } + } + pascal + } + CamelCase => { + let pascal = PascalCase.apply_to_field(field); + pascal[..1].to_ascii_lowercase() + &pascal[1..] + } + ScreamingSnakeCase => field.to_ascii_uppercase(), + KebabCase => field.replace('_', "-"), + ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"), + } + } +} + +impl FromStr for RenameRule { + type Err = (); + + fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> { + match rename_all_str { + "lowercase" => Ok(LowerCase), + "UPPERCASE" => Ok(UPPERCASE), + "PascalCase" => Ok(PascalCase), + "camelCase" => Ok(CamelCase), + "snake_case" => Ok(SnakeCase), + "SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase), + "kebab-case" => Ok(KebabCase), + "SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase), + _ => Err(()), + } + } +} + +#[test] +fn rename_variants() { + for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[ + ( + "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME", + ), + ( + "VeryTasty", + "verytasty", + "VERYTASTY", + "veryTasty", + "very_tasty", + "VERY_TASTY", + "very-tasty", + "VERY-TASTY", + ), + ("A", "a", "A", "a", "a", "A", "a", "A"), + ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"), + ] { + assert_eq!(None.apply_to_variant(original), original); + assert_eq!(LowerCase.apply_to_variant(original), lower); + assert_eq!(UPPERCASE.apply_to_variant(original), upper); + assert_eq!(PascalCase.apply_to_variant(original), original); + assert_eq!(CamelCase.apply_to_variant(original), camel); + assert_eq!(SnakeCase.apply_to_variant(original), snake); + assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming); + assert_eq!(KebabCase.apply_to_variant(original), kebab); + assert_eq!( + ScreamingKebabCase.apply_to_variant(original), + screaming_kebab + ); + } +} + +#[test] +fn rename_fields() { + for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[ + ( + "outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME", + ), + ( + "very_tasty", + "VERY_TASTY", + "VeryTasty", + "veryTasty", + "VERY_TASTY", + "very-tasty", + "VERY-TASTY", + ), + ("a", "A", "A", "a", "A", "a", "A"), + ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"), + ] { + assert_eq!(None.apply_to_field(original), original); + assert_eq!(UPPERCASE.apply_to_field(original), upper); + assert_eq!(PascalCase.apply_to_field(original), pascal); + assert_eq!(CamelCase.apply_to_field(original), camel); + assert_eq!(SnakeCase.apply_to_field(original), original); + assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming); + assert_eq!(KebabCase.apply_to_field(original), kebab); + assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab); + } +} diff --git a/third_party/rust/serde_derive/src/internals/check.rs b/third_party/rust/serde_derive/src/internals/check.rs new file mode 100644 index 0000000000..30ede1ce58 --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/check.rs @@ -0,0 +1,420 @@ +use internals::ast::{Container, Data, Field, Style}; +use internals::attr::{Identifier, TagType}; +use internals::{ungroup, Ctxt, Derive}; +use syn::{Member, Type}; + +/// Cross-cutting checks that require looking at more than a single attrs +/// object. Simpler checks should happen when parsing and building the attrs. +pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) { + check_getter(cx, cont); + check_flatten(cx, cont); + check_identifier(cx, cont); + check_variant_skip_attrs(cx, cont); + check_internal_tag_field_name_conflict(cx, cont); + check_adjacent_tag_conflict(cx, cont); + check_transparent(cx, cont, derive); + check_from_and_try_from(cx, cont); +} + +/// Getters are only allowed inside structs (not enums) with the `remote` +/// attribute. +fn check_getter(cx: &Ctxt, cont: &Container) { + match cont.data { + Data::Enum(_) => { + if cont.data.has_getter() { + cx.error_spanned_by( + cont.original, + "#[serde(getter = \"...\")] is not allowed in an enum", + ); + } + } + Data::Struct(_, _) => { + if cont.data.has_getter() && cont.attrs.remote().is_none() { + cx.error_spanned_by( + cont.original, + "#[serde(getter = \"...\")] can only be used in structs that have #[serde(remote = \"...\")]", + ); + } + } + } +} + +/// Flattening has some restrictions we can test. +fn check_flatten(cx: &Ctxt, cont: &Container) { + match &cont.data { + Data::Enum(variants) => { + for variant in variants { + for field in &variant.fields { + check_flatten_field(cx, variant.style, field); + } + } + } + Data::Struct(style, fields) => { + for field in fields { + check_flatten_field(cx, *style, field); + } + } + } +} + +fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) { + if !field.attrs.flatten() { + return; + } + match style { + Style::Tuple => { + cx.error_spanned_by( + field.original, + "#[serde(flatten)] cannot be used on tuple structs", + ); + } + Style::Newtype => { + cx.error_spanned_by( + field.original, + "#[serde(flatten)] cannot be used on newtype structs", + ); + } + _ => {} + } +} + +/// The `other` attribute must be used at most once and it must be the last +/// variant of an enum. +/// +/// Inside a `variant_identifier` all variants must be unit variants. Inside a +/// `field_identifier` all but possibly one variant must be unit variants. The +/// last variant may be a newtype variant which is an implicit "other" case. +fn check_identifier(cx: &Ctxt, cont: &Container) { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => { + return; + } + }; + + for (i, variant) in variants.iter().enumerate() { + match ( + variant.style, + cont.attrs.identifier(), + variant.attrs.other(), + cont.attrs.tag(), + ) { + // The `other` attribute may not be used in a variant_identifier. + (_, Identifier::Variant, true, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(other)] may not be used on a variant identifier", + ); + } + + // Variant with `other` attribute cannot appear in untagged enum + (_, Identifier::No, true, &TagType::None) => { + cx.error_spanned_by( + variant.original, + "#[serde(other)] cannot appear on untagged enum", + ); + } + + // Variant with `other` attribute must be the last one. + (Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => { + if i < variants.len() - 1 { + cx.error_spanned_by( + variant.original, + "#[serde(other)] must be on the last variant", + ); + } + } + + // Variant with `other` attribute must be a unit variant. + (_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(other)] must be on a unit variant", + ); + } + + // Any sort of variant is allowed if this is not an identifier. + (_, Identifier::No, false, _) => {} + + // Unit variant without `other` attribute is always fine. + (Style::Unit, _, false, _) => {} + + // The last field is allowed to be a newtype catch-all. + (Style::Newtype, Identifier::Field, false, _) => { + if i < variants.len() - 1 { + cx.error_spanned_by( + variant.original, + format!("`{}` must be the last variant", variant.ident), + ); + } + } + + (_, Identifier::Field, false, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(field_identifier)] may only contain unit variants", + ); + } + + (_, Identifier::Variant, false, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(variant_identifier)] may only contain unit variants", + ); + } + } + } +} + +/// Skip-(de)serializing attributes are not allowed on variants marked +/// (de)serialize_with. +fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => { + return; + } + }; + + for variant in variants.iter() { + if variant.attrs.serialize_with().is_some() { + if variant.attrs.skip_serializing() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(serialize_with)] and #[serde(skip_serializing)]", + variant.ident + ), + ); + } + + for field in &variant.fields { + let member = member_message(&field.member); + + if field.attrs.skip_serializing() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing)]", + variant.ident, member + ), + ); + } + + if field.attrs.skip_serializing_if().is_some() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing_if)]", + variant.ident, member + ), + ); + } + } + } + + if variant.attrs.deserialize_with().is_some() { + if variant.attrs.skip_deserializing() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(deserialize_with)] and #[serde(skip_deserializing)]", + variant.ident + ), + ); + } + + for field in &variant.fields { + if field.attrs.skip_deserializing() { + let member = member_message(&field.member); + + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(deserialize_with)] and a field {} marked with #[serde(skip_deserializing)]", + variant.ident, member + ), + ); + } + } + } + } +} + +/// The tag of an internally-tagged struct variant must not be +/// the same as either one of its fields, as this would result in +/// duplicate keys in the serialized output and/or ambiguity in +/// the to-be-deserialized input. +fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => return, + }; + + let tag = match cont.attrs.tag() { + TagType::Internal { tag } => tag.as_str(), + TagType::External | TagType::Adjacent { .. } | TagType::None => return, + }; + + let diagnose_conflict = || { + cx.error_spanned_by( + cont.original, + format!("variant field name `{}` conflicts with internal tag", tag), + ) + }; + + for variant in variants { + match variant.style { + Style::Struct => { + for field in &variant.fields { + let check_ser = !field.attrs.skip_serializing(); + let check_de = !field.attrs.skip_deserializing(); + let name = field.attrs.name(); + let ser_name = name.serialize_name(); + + if check_ser && ser_name == tag { + diagnose_conflict(); + return; + } + + for de_name in field.attrs.aliases() { + if check_de && de_name == tag { + diagnose_conflict(); + return; + } + } + } + } + Style::Unit | Style::Newtype | Style::Tuple => {} + } + } +} + +/// In the case of adjacently-tagged enums, the type and the +/// contents tag must differ, for the same reason. +fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) { + let (type_tag, content_tag) = match cont.attrs.tag() { + TagType::Adjacent { tag, content } => (tag, content), + TagType::Internal { .. } | TagType::External | TagType::None => return, + }; + + if type_tag == content_tag { + cx.error_spanned_by( + cont.original, + format!( + "enum tags `{}` for type and content conflict with each other", + type_tag + ), + ); + } +} + +/// Enums and unit structs cannot be transparent. +fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) { + if !cont.attrs.transparent() { + return; + } + + if cont.attrs.type_from().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed with #[serde(from = \"...\")]", + ); + } + + if cont.attrs.type_try_from().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed with #[serde(try_from = \"...\")]", + ); + } + + if cont.attrs.type_into().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed with #[serde(into = \"...\")]", + ); + } + + let fields = match &mut cont.data { + Data::Enum(_) => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed on an enum", + ); + return; + } + Data::Struct(Style::Unit, _) => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed on a unit struct", + ); + return; + } + Data::Struct(_, fields) => fields, + }; + + let mut transparent_field = None; + + for field in fields { + if allow_transparent(field, derive) { + if transparent_field.is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] requires struct to have at most one transparent field", + ); + return; + } + transparent_field = Some(field); + } + } + + match transparent_field { + Some(transparent_field) => transparent_field.attrs.mark_transparent(), + None => match derive { + Derive::Serialize => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] requires at least one field that is not skipped", + ); + } + Derive::Deserialize => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] requires at least one field that is neither skipped nor has a default", + ); + } + }, + } +} + +fn member_message(member: &Member) -> String { + match member { + Member::Named(ident) => format!("`{}`", ident), + Member::Unnamed(i) => format!("#{}", i.index), + } +} + +fn allow_transparent(field: &Field, derive: Derive) -> bool { + if let Type::Path(ty) = ungroup(&field.ty) { + if let Some(seg) = ty.path.segments.last() { + if seg.ident == "PhantomData" { + return false; + } + } + } + + match derive { + Derive::Serialize => !field.attrs.skip_serializing(), + Derive::Deserialize => !field.attrs.skip_deserializing() && field.attrs.default().is_none(), + } +} + +fn check_from_and_try_from(cx: &Ctxt, cont: &mut Container) { + if cont.attrs.type_from().is_some() && cont.attrs.type_try_from().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(from = \"...\")] and #[serde(try_from = \"...\")] conflict with each other", + ); + } +} diff --git a/third_party/rust/serde_derive/src/internals/ctxt.rs b/third_party/rust/serde_derive/src/internals/ctxt.rs new file mode 100644 index 0000000000..d692c2a449 --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/ctxt.rs @@ -0,0 +1,62 @@ +use quote::ToTokens; +use std::cell::RefCell; +use std::fmt::Display; +use std::thread; +use syn; + +/// A type to collect errors together and format them. +/// +/// Dropping this object will cause a panic. It must be consumed using `check`. +/// +/// References can be shared since this type uses run-time exclusive mut checking. +#[derive(Default)] +pub struct Ctxt { + // The contents will be set to `None` during checking. This is so that checking can be + // enforced. + errors: RefCell<Option<Vec<syn::Error>>>, +} + +impl Ctxt { + /// Create a new context object. + /// + /// This object contains no errors, but will still trigger a panic if it is not `check`ed. + pub fn new() -> Self { + Ctxt { + errors: RefCell::new(Some(Vec::new())), + } + } + + /// Add an error to the context object with a tokenenizable object. + /// + /// The object is used for spanning in error messages. + pub fn error_spanned_by<A: ToTokens, T: Display>(&self, obj: A, msg: T) { + self.errors + .borrow_mut() + .as_mut() + .unwrap() + // Curb monomorphization from generating too many identical methods. + .push(syn::Error::new_spanned(obj.into_token_stream(), msg)); + } + + /// Add one of Syn's parse errors. + pub fn syn_error(&self, err: syn::Error) { + self.errors.borrow_mut().as_mut().unwrap().push(err); + } + + /// Consume this object, producing a formatted error string if there are errors. + pub fn check(self) -> Result<(), Vec<syn::Error>> { + let errors = self.errors.borrow_mut().take().unwrap(); + match errors.len() { + 0 => Ok(()), + _ => Err(errors), + } + } +} + +impl Drop for Ctxt { + fn drop(&mut self) { + if !thread::panicking() && self.errors.borrow().is_some() { + panic!("forgot to check for errors"); + } + } +} diff --git a/third_party/rust/serde_derive/src/internals/mod.rs b/third_party/rust/serde_derive/src/internals/mod.rs new file mode 100644 index 0000000000..d36b6e45c4 --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/mod.rs @@ -0,0 +1,24 @@ +pub mod ast; +pub mod attr; + +mod ctxt; +pub use self::ctxt::Ctxt; + +mod case; +mod check; +mod symbol; + +use syn::Type; + +#[derive(Copy, Clone)] +pub enum Derive { + Serialize, + Deserialize, +} + +pub fn ungroup(mut ty: &Type) -> &Type { + while let Type::Group(group) = ty { + ty = &group.elem; + } + ty +} diff --git a/third_party/rust/serde_derive/src/internals/symbol.rs b/third_party/rust/serde_derive/src/internals/symbol.rs new file mode 100644 index 0000000000..318b81bbbd --- /dev/null +++ b/third_party/rust/serde_derive/src/internals/symbol.rs @@ -0,0 +1,67 @@ +use std::fmt::{self, Display}; +use syn::{Ident, Path}; + +#[derive(Copy, Clone)] +pub struct Symbol(&'static str); + +pub const ALIAS: Symbol = Symbol("alias"); +pub const BORROW: Symbol = Symbol("borrow"); +pub const BOUND: Symbol = Symbol("bound"); +pub const CONTENT: Symbol = Symbol("content"); +pub const CRATE: Symbol = Symbol("crate"); +pub const DEFAULT: Symbol = Symbol("default"); +pub const DENY_UNKNOWN_FIELDS: Symbol = Symbol("deny_unknown_fields"); +pub const DESERIALIZE: Symbol = Symbol("deserialize"); +pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with"); +pub const FIELD_IDENTIFIER: Symbol = Symbol("field_identifier"); +pub const FLATTEN: Symbol = Symbol("flatten"); +pub const FROM: Symbol = Symbol("from"); +pub const GETTER: Symbol = Symbol("getter"); +pub const INTO: Symbol = Symbol("into"); +pub const OTHER: Symbol = Symbol("other"); +pub const REMOTE: Symbol = Symbol("remote"); +pub const RENAME: Symbol = Symbol("rename"); +pub const RENAME_ALL: Symbol = Symbol("rename_all"); +pub const SERDE: Symbol = Symbol("serde"); +pub const SERIALIZE: Symbol = Symbol("serialize"); +pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with"); +pub const SKIP: Symbol = Symbol("skip"); +pub const SKIP_DESERIALIZING: Symbol = Symbol("skip_deserializing"); +pub const SKIP_SERIALIZING: Symbol = Symbol("skip_serializing"); +pub const SKIP_SERIALIZING_IF: Symbol = Symbol("skip_serializing_if"); +pub const TAG: Symbol = Symbol("tag"); +pub const TRANSPARENT: Symbol = Symbol("transparent"); +pub const TRY_FROM: Symbol = Symbol("try_from"); +pub const UNTAGGED: Symbol = Symbol("untagged"); +pub const VARIANT_IDENTIFIER: Symbol = Symbol("variant_identifier"); +pub const WITH: Symbol = Symbol("with"); + +impl PartialEq<Symbol> for Ident { + fn eq(&self, word: &Symbol) -> bool { + self == word.0 + } +} + +impl<'a> PartialEq<Symbol> for &'a Ident { + fn eq(&self, word: &Symbol) -> bool { + *self == word.0 + } +} + +impl PartialEq<Symbol> for Path { + fn eq(&self, word: &Symbol) -> bool { + self.is_ident(word.0) + } +} + +impl<'a> PartialEq<Symbol> for &'a Path { + fn eq(&self, word: &Symbol) -> bool { + self.is_ident(word.0) + } +} + +impl Display for Symbol { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.0) + } +} diff --git a/third_party/rust/serde_derive/src/lib.rs b/third_party/rust/serde_derive/src/lib.rs new file mode 100644 index 0000000000..9307ae8147 --- /dev/null +++ b/third_party/rust/serde_derive/src/lib.rs @@ -0,0 +1,97 @@ +//! This crate provides Serde's two derive macros. +//! +//! ```edition2018 +//! # use serde_derive::{Serialize, Deserialize}; +//! # +//! #[derive(Serialize, Deserialize)] +//! # struct S; +//! # +//! # fn main() {} +//! ``` +//! +//! Please refer to [https://serde.rs/derive.html] for how to set this up. +//! +//! [https://serde.rs/derive.html]: https://serde.rs/derive.html + +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.116")] +#![allow(unknown_lints, bare_trait_objects)] +#![deny(clippy::all, clippy::pedantic)] +// Ignored clippy lints +#![allow( + clippy::cognitive_complexity, + clippy::enum_variant_names, + clippy::match_like_matches_macro, + clippy::needless_pass_by_value, + clippy::too_many_arguments, + clippy::trivially_copy_pass_by_ref, + clippy::used_underscore_binding, + clippy::wildcard_in_or_patterns, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 + clippy::unnested_or_patterns, +)] +// Ignored clippy_pedantic lints +#![allow( + clippy::cast_possible_truncation, + clippy::checked_conversions, + clippy::doc_markdown, + clippy::enum_glob_use, + clippy::filter_map, + clippy::indexing_slicing, + clippy::items_after_statements, + clippy::match_same_arms, + clippy::module_name_repetitions, + clippy::must_use_candidate, + clippy::option_if_let_else, + clippy::similar_names, + clippy::single_match_else, + clippy::struct_excessive_bools, + clippy::too_many_lines, + clippy::unseparated_literal_suffix, + clippy::use_self, + clippy::wildcard_imports +)] + +#[macro_use] +extern crate quote; +#[macro_use] +extern crate syn; + +extern crate proc_macro; +extern crate proc_macro2; + +mod internals; + +use proc_macro::TokenStream; +use syn::DeriveInput; + +#[macro_use] +mod bound; +#[macro_use] +mod fragment; + +mod de; +mod dummy; +mod pretend; +mod ser; +mod try; + +#[proc_macro_derive(Serialize, attributes(serde))] +pub fn derive_serialize(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + ser::expand_derive_serialize(&input) + .unwrap_or_else(to_compile_errors) + .into() +} + +#[proc_macro_derive(Deserialize, attributes(serde))] +pub fn derive_deserialize(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + de::expand_derive_deserialize(&input) + .unwrap_or_else(to_compile_errors) + .into() +} + +fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream { + let compile_errors = errors.iter().map(syn::Error::to_compile_error); + quote!(#(#compile_errors)*) +} diff --git a/third_party/rust/serde_derive/src/pretend.rs b/third_party/rust/serde_derive/src/pretend.rs new file mode 100644 index 0000000000..7233c236a1 --- /dev/null +++ b/third_party/rust/serde_derive/src/pretend.rs @@ -0,0 +1,140 @@ +use proc_macro2::{Span, TokenStream}; +use syn::Ident; + +use internals::ast::{Container, Data, Field, Style}; + +// Suppress dead_code warnings that would otherwise appear when using a remote +// derive. Other than this pretend code, a struct annotated with remote derive +// never has its fields referenced and an enum annotated with remote derive +// never has its variants constructed. +// +// warning: field is never used: `i` +// --> src/main.rs:4:20 +// | +// 4 | struct StructDef { i: i32 } +// | ^^^^^^ +// +// warning: variant is never constructed: `V` +// --> src/main.rs:8:16 +// | +// 8 | enum EnumDef { V } +// | ^ +// +pub fn pretend_used(cont: &Container) -> TokenStream { + let pretend_fields = pretend_fields_used(cont); + let pretend_variants = pretend_variants_used(cont); + + quote! { + #pretend_fields + #pretend_variants + } +} + +// For structs with named fields, expands to: +// +// match None::<T> { +// Some(T { a: ref __v0, b: ref __v1 }) => {} +// _ => {} +// } +// +// For enums, expands to the following but only including struct variants: +// +// match None::<T> { +// Some(T::A { a: ref __v0 }) => {} +// Some(T::B { b: ref __v0 }) => {} +// _ => {} +// } +// +// The `ref` is important in case the user has written a Drop impl on their +// type. Rust does not allow destructuring a struct or enum that has a Drop +// impl. +fn pretend_fields_used(cont: &Container) -> TokenStream { + let type_ident = &cont.ident; + let (_, ty_generics, _) = cont.generics.split_for_impl(); + + let patterns = match &cont.data { + Data::Enum(variants) => variants + .iter() + .filter_map(|variant| match variant.style { + Style::Struct => { + let variant_ident = &variant.ident; + let pat = struct_pattern(&variant.fields); + Some(quote!(#type_ident::#variant_ident #pat)) + } + _ => None, + }) + .collect::<Vec<_>>(), + Data::Struct(Style::Struct, fields) => { + let pat = struct_pattern(fields); + vec![quote!(#type_ident #pat)] + } + Data::Struct(_, _) => { + return quote!(); + } + }; + + quote! { + match _serde::export::None::<#type_ident #ty_generics> { + #( + _serde::export::Some(#patterns) => {} + )* + _ => {} + } + } +} + +// Expands to one of these per enum variant: +// +// match None { +// Some((__v0, __v1,)) => { +// let _ = E::V { a: __v0, b: __v1 }; +// } +// _ => {} +// } +// +fn pretend_variants_used(cont: &Container) -> TokenStream { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => { + return quote!(); + } + }; + + let type_ident = &cont.ident; + let (_, ty_generics, _) = cont.generics.split_for_impl(); + let turbofish = ty_generics.as_turbofish(); + + let cases = variants.iter().map(|variant| { + let variant_ident = &variant.ident; + let placeholders = &(0..variant.fields.len()) + .map(|i| Ident::new(&format!("__v{}", i), Span::call_site())) + .collect::<Vec<_>>(); + + let pat = match variant.style { + Style::Struct => { + let members = variant.fields.iter().map(|field| &field.member); + quote!({ #(#members: #placeholders),* }) + } + Style::Tuple | Style::Newtype => quote!(( #(#placeholders),* )), + Style::Unit => quote!(), + }; + + quote! { + match _serde::export::None { + _serde::export::Some((#(#placeholders,)*)) => { + let _ = #type_ident::#variant_ident #turbofish #pat; + } + _ => {} + } + } + }); + + quote!(#(#cases)*) +} + +fn struct_pattern(fields: &[Field]) -> TokenStream { + let members = fields.iter().map(|field| &field.member); + let placeholders = + (0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site())); + quote!({ #(#members: ref #placeholders),* }) +} diff --git a/third_party/rust/serde_derive/src/ser.rs b/third_party/rust/serde_derive/src/ser.rs new file mode 100644 index 0000000000..f29d73809c --- /dev/null +++ b/third_party/rust/serde_derive/src/ser.rs @@ -0,0 +1,1334 @@ +use proc_macro2::{Span, TokenStream}; +use syn::spanned::Spanned; +use syn::{self, Ident, Index, Member}; + +use bound; +use dummy; +use fragment::{Fragment, Match, Stmts}; +use internals::ast::{Container, Data, Field, Style, Variant}; +use internals::{attr, Ctxt, Derive}; +use pretend; + +pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> { + let ctxt = Ctxt::new(); + let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) { + Some(cont) => cont, + None => return Err(ctxt.check().unwrap_err()), + }; + precondition(&ctxt, &cont); + ctxt.check()?; + + let ident = &cont.ident; + let params = Parameters::new(&cont); + let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); + let body = Stmts(serialize_body(&cont, ¶ms)); + let serde = cont.attrs.serde_path(); + + let impl_block = if let Some(remote) = cont.attrs.remote() { + let vis = &input.vis; + let used = pretend::pretend_used(&cont); + quote! { + impl #impl_generics #ident #ty_generics #where_clause { + #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error> + where + __S: #serde::Serializer, + { + #used + #body + } + } + } + } else { + quote! { + #[automatically_derived] + impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error> + where + __S: #serde::Serializer, + { + #body + } + } + } + }; + + Ok(dummy::wrap_in_const( + cont.attrs.custom_serde_path(), + "SERIALIZE", + ident, + impl_block, + )) +} + +fn precondition(cx: &Ctxt, cont: &Container) { + match cont.attrs.identifier() { + attr::Identifier::No => {} + attr::Identifier::Field => { + cx.error_spanned_by(cont.original, "field identifiers cannot be serialized"); + } + attr::Identifier::Variant => { + cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized"); + } + } +} + +struct Parameters { + /// Variable holding the value being serialized. Either `self` for local + /// types or `__self` for remote types. + self_var: Ident, + + /// Path to the type the impl is for. Either a single `Ident` for local + /// types or `some::remote::Ident` for remote types. Does not include + /// generic parameters. + this: syn::Path, + + /// Generics including any explicit and inferred bounds for the impl. + generics: syn::Generics, + + /// Type has a `serde(remote = "...")` attribute. + is_remote: bool, + + /// Type has a repr(packed) attribute. + is_packed: bool, +} + +impl Parameters { + fn new(cont: &Container) -> Self { + let is_remote = cont.attrs.remote().is_some(); + let self_var = if is_remote { + Ident::new("__self", Span::call_site()) + } else { + Ident::new("self", Span::call_site()) + }; + + let this = match cont.attrs.remote() { + Some(remote) => remote.clone(), + None => cont.ident.clone().into(), + }; + + let is_packed = cont.attrs.is_packed(); + + let generics = build_generics(cont); + + Parameters { + self_var, + this, + generics, + is_remote, + is_packed, + } + } + + /// Type name to use in error messages and `&'static str` arguments to + /// various Serializer methods. + fn type_name(&self) -> String { + self.this.segments.last().unwrap().ident.to_string() + } +} + +// All the generics in the input, plus a bound `T: Serialize` for each generic +// field type that will be serialized by us. +fn build_generics(cont: &Container) -> syn::Generics { + let generics = bound::without_defaults(cont.generics); + + let generics = + bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound); + + let generics = + bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::ser_bound); + + match cont.attrs.ser_bound() { + Some(predicates) => bound::with_where_predicates(&generics, predicates), + None => bound::with_bound( + cont, + &generics, + needs_serialize_bound, + &parse_quote!(_serde::Serialize), + ), + } +} + +// Fields with a `skip_serializing` or `serialize_with` attribute, or which +// belong to a variant with a 'skip_serializing` or `serialize_with` attribute, +// are not serialized by us so we do not generate a bound. Fields with a `bound` +// attribute specify their own bound so we do not generate one. All other fields +// may need a `T: Serialize` bound where T is the type of the field. +fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { + !field.skip_serializing() + && field.serialize_with().is_none() + && field.ser_bound().is_none() + && variant.map_or(true, |variant| { + !variant.skip_serializing() + && variant.serialize_with().is_none() + && variant.ser_bound().is_none() + }) +} + +fn serialize_body(cont: &Container, params: &Parameters) -> Fragment { + if cont.attrs.transparent() { + serialize_transparent(cont, params) + } else if let Some(type_into) = cont.attrs.type_into() { + serialize_into(params, type_into) + } else { + match &cont.data { + Data::Enum(variants) => serialize_enum(params, variants, &cont.attrs), + Data::Struct(Style::Struct, fields) => serialize_struct(params, fields, &cont.attrs), + Data::Struct(Style::Tuple, fields) => { + serialize_tuple_struct(params, fields, &cont.attrs) + } + Data::Struct(Style::Newtype, fields) => { + serialize_newtype_struct(params, &fields[0], &cont.attrs) + } + Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs), + } + } +} + +fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment { + let fields = match &cont.data { + Data::Struct(_, fields) => fields, + Data::Enum(_) => unreachable!(), + }; + + let self_var = ¶ms.self_var; + let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap(); + let member = &transparent_field.member; + + let path = match transparent_field.attrs.serialize_with() { + Some(path) => quote!(#path), + None => { + let span = transparent_field.original.span(); + quote_spanned!(span=> _serde::Serialize::serialize) + } + }; + + quote_block! { + #path(&#self_var.#member, __serializer) + } +} + +fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment { + let self_var = ¶ms.self_var; + quote_block! { + _serde::Serialize::serialize( + &_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)), + __serializer) + } +} + +fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment { + let type_name = cattrs.name().serialize_name(); + + quote_expr! { + _serde::Serializer::serialize_unit_struct(__serializer, #type_name) + } +} + +fn serialize_newtype_struct( + params: &Parameters, + field: &Field, + cattrs: &attr::Container, +) -> Fragment { + let type_name = cattrs.name().serialize_name(); + + let mut field_expr = get_member( + params, + field, + &Member::Unnamed(Index { + index: 0, + span: Span::call_site(), + }), + ); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_struct); + quote_expr! { + #func(__serializer, #type_name, #field_expr) + } +} + +fn serialize_tuple_struct( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + let serialize_stmts = + serialize_tuple_struct_visitor(fields, params, false, &TupleTrait::SerializeTupleStruct); + + let type_name = cattrs.name().serialize_name(); + + let mut serialized_fields = fields + .iter() + .enumerate() + .filter(|(_, field)| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields + .map(|(i, field)| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let index = syn::Index { + index: i as u32, + span: Span::call_site(), + }; + let field_expr = get_member(params, field, &Member::Unnamed(index)); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len)); + #(#serialize_stmts)* + _serde::ser::SerializeTupleStruct::end(__serde_state) + } +} + +fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment { + assert!(fields.len() as u64 <= u64::from(u32::max_value())); + + if cattrs.has_flatten() { + serialize_struct_as_map(params, fields, cattrs) + } else { + serialize_struct_as_struct(params, fields, cattrs) + } +} + +fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream { + match cattrs.tag() { + attr::TagType::Internal { tag } => { + let type_name = cattrs.name().serialize_name(); + let func = struct_trait.serialize_field(Span::call_site()); + quote! { + try!(#func(&mut __serde_state, #tag, #type_name)); + } + } + _ => quote! {}, + } +} + +fn serialize_struct_as_struct( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + let serialize_fields = + serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct); + + let type_name = cattrs.name().serialize_name(); + + let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct); + let tag_field_exists = !tag_field.is_empty(); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists); + + let len = serialized_fields + .map(|field| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let field_expr = get_member(params, field, &field.member); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold( + quote!(#tag_field_exists as usize), + |sum, expr| quote!(#sum + #expr), + ); + + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len)); + #tag_field + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } +} + +fn serialize_struct_as_map( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + let serialize_fields = + serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap); + + let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap); + let tag_field_exists = !tag_field.is_empty(); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists); + + let len = if cattrs.has_flatten() { + quote!(_serde::export::None) + } else { + let len = serialized_fields + .map(|field| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let field_expr = get_member(params, field, &field.member); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold( + quote!(#tag_field_exists as usize), + |sum, expr| quote!(#sum + #expr), + ); + quote!(_serde::export::Some(#len)) + }; + + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len)); + #tag_field + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } +} + +fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment { + assert!(variants.len() as u64 <= u64::from(u32::max_value())); + + let self_var = ¶ms.self_var; + + let arms: Vec<_> = variants + .iter() + .enumerate() + .map(|(variant_index, variant)| { + serialize_variant(params, variant, variant_index as u32, cattrs) + }) + .collect(); + + quote_expr! { + match *#self_var { + #(#arms)* + } + } +} + +fn serialize_variant( + params: &Parameters, + variant: &Variant, + variant_index: u32, + cattrs: &attr::Container, +) -> TokenStream { + let this = ¶ms.this; + let variant_ident = &variant.ident; + + if variant.attrs.skip_serializing() { + let skipped_msg = format!( + "the enum variant {}::{} cannot be serialized", + params.type_name(), + variant_ident + ); + let skipped_err = quote! { + _serde::export::Err(_serde::ser::Error::custom(#skipped_msg)) + }; + let fields_pat = match variant.style { + Style::Unit => quote!(), + Style::Newtype | Style::Tuple => quote!((..)), + Style::Struct => quote!({ .. }), + }; + quote! { + #this::#variant_ident #fields_pat => #skipped_err, + } + } else { + // variant wasn't skipped + let case = match variant.style { + Style::Unit => { + quote! { + #this::#variant_ident + } + } + Style::Newtype => { + quote! { + #this::#variant_ident(ref __field0) + } + } + Style::Tuple => { + let field_names = (0..variant.fields.len()) + .map(|i| Ident::new(&format!("__field{}", i), Span::call_site())); + quote! { + #this::#variant_ident(#(ref #field_names),*) + } + } + Style::Struct => { + let members = variant.fields.iter().map(|f| &f.member); + quote! { + #this::#variant_ident { #(ref #members),* } + } + } + }; + + let body = Match(match cattrs.tag() { + attr::TagType::External => { + serialize_externally_tagged_variant(params, variant, variant_index, cattrs) + } + attr::TagType::Internal { tag } => { + serialize_internally_tagged_variant(params, variant, cattrs, tag) + } + attr::TagType::Adjacent { tag, content } => { + serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content) + } + attr::TagType::None => serialize_untagged_variant(params, variant, cattrs), + }); + + quote! { + #case => #body + } + } +} + +fn serialize_externally_tagged_variant( + params: &Parameters, + variant: &Variant, + variant_index: u32, + cattrs: &attr::Container, +) -> Fragment { + let type_name = cattrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + return quote_expr! { + _serde::Serializer::serialize_newtype_variant( + __serializer, + #type_name, + #variant_index, + #variant_name, + #ser, + ) + }; + } + + match effective_style(variant) { + Style::Unit => { + quote_expr! { + _serde::Serializer::serialize_unit_variant( + __serializer, + #type_name, + #variant_index, + #variant_name, + ) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant); + quote_expr! { + #func( + __serializer, + #type_name, + #variant_index, + #variant_name, + #field_expr, + ) + } + } + Style::Tuple => serialize_tuple_variant( + TupleVariant::ExternallyTagged { + type_name, + variant_index, + variant_name, + }, + params, + &variant.fields, + ), + Style::Struct => serialize_struct_variant( + StructVariant::ExternallyTagged { + variant_index, + variant_name, + }, + params, + &variant.fields, + &type_name, + ), + } +} + +fn serialize_internally_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + tag: &str, +) -> Fragment { + let type_name = cattrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + let enum_ident_str = params.type_name(); + let variant_ident_str = variant.ident.to_string(); + + if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + return quote_expr! { + _serde::private::ser::serialize_tagged_newtype( + __serializer, + #enum_ident_str, + #variant_ident_str, + #tag, + #variant_name, + #ser, + ) + }; + } + + match effective_style(variant) { + Style::Unit => { + quote_block! { + let mut __struct = try!(_serde::Serializer::serialize_struct( + __serializer, #type_name, 1)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + _serde::ser::SerializeStruct::end(__struct) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::private::ser::serialize_tagged_newtype); + quote_expr! { + #func( + __serializer, + #enum_ident_str, + #variant_ident_str, + #tag, + #variant_name, + #field_expr, + ) + } + } + Style::Struct => serialize_struct_variant( + StructVariant::InternallyTagged { tag, variant_name }, + params, + &variant.fields, + &type_name, + ), + Style::Tuple => unreachable!("checked in serde_derive_internals"), + } +} + +fn serialize_adjacently_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + tag: &str, + content: &str, +) -> Fragment { + let this = ¶ms.this; + let type_name = cattrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + quote_expr! { + _serde::Serialize::serialize(#ser, __serializer) + } + } else { + match effective_style(variant) { + Style::Unit => { + return quote_block! { + let mut __struct = try!(_serde::Serializer::serialize_struct( + __serializer, #type_name, 1)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + _serde::ser::SerializeStruct::end(__struct) + }; + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field); + return quote_block! { + let mut __struct = try!(_serde::Serializer::serialize_struct( + __serializer, #type_name, 2)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + try!(#func( + &mut __struct, #content, #field_expr)); + _serde::ser::SerializeStruct::end(__struct) + }; + } + Style::Tuple => { + serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields) + } + Style::Struct => serialize_struct_variant( + StructVariant::Untagged, + params, + &variant.fields, + &variant_name, + ), + } + }); + + let fields_ty = variant.fields.iter().map(|f| &f.ty); + let fields_ident: &Vec<_> = &match variant.style { + Style::Unit => { + if variant.attrs.serialize_with().is_some() { + vec![] + } else { + unreachable!() + } + } + Style::Newtype => vec![Member::Named(Ident::new("__field0", Span::call_site()))], + Style::Tuple => (0..variant.fields.len()) + .map(|i| Member::Named(Ident::new(&format!("__field{}", i), Span::call_site()))) + .collect(), + Style::Struct => variant.fields.iter().map(|f| f.member.clone()).collect(), + }; + + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + + let wrapper_generics = if fields_ident.is_empty() { + params.generics.clone() + } else { + bound::with_lifetime_bound(¶ms.generics, "'__a") + }; + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + quote_block! { + struct __AdjacentlyTagged #wrapper_generics #where_clause { + data: (#(&'__a #fields_ty,)*), + phantom: _serde::export::PhantomData<#this #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + // Elements that have skip_serializing will be unused. + #[allow(unused_variables)] + let (#(#fields_ident,)*) = self.data; + #inner + } + } + + let mut __struct = try!(_serde::Serializer::serialize_struct( + __serializer, #type_name, 2)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #content, &__AdjacentlyTagged { + data: (#(#fields_ident,)*), + phantom: _serde::export::PhantomData::<#this #ty_generics>, + })); + _serde::ser::SerializeStruct::end(__struct) + } +} + +fn serialize_untagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, +) -> Fragment { + if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + return quote_expr! { + _serde::Serialize::serialize(#ser, __serializer) + }; + } + + match effective_style(variant) { + Style::Unit => { + quote_expr! { + _serde::Serializer::serialize_unit(__serializer) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::Serialize::serialize); + quote_expr! { + #func(#field_expr, __serializer) + } + } + Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), + Style::Struct => { + let type_name = cattrs.name().serialize_name(); + serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name) + } + } +} + +enum TupleVariant { + ExternallyTagged { + type_name: String, + variant_index: u32, + variant_name: String, + }, + Untagged, +} + +fn serialize_tuple_variant( + context: TupleVariant, + params: &Parameters, + fields: &[Field], +) -> Fragment { + let tuple_trait = match context { + TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant, + TupleVariant::Untagged => TupleTrait::SerializeTuple, + }; + + let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait); + + let mut serialized_fields = fields + .iter() + .enumerate() + .filter(|(_, field)| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields + .map(|(i, field)| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let field_expr = Ident::new(&format!("__field{}", i), Span::call_site()); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + match context { + TupleVariant::ExternallyTagged { + type_name, + variant_index, + variant_name, + } => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant( + __serializer, + #type_name, + #variant_index, + #variant_name, + #len)); + #(#serialize_stmts)* + _serde::ser::SerializeTupleVariant::end(__serde_state) + } + } + TupleVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple( + __serializer, + #len)); + #(#serialize_stmts)* + _serde::ser::SerializeTuple::end(__serde_state) + } + } + } +} + +enum StructVariant<'a> { + ExternallyTagged { + variant_index: u32, + variant_name: String, + }, + InternallyTagged { + tag: &'a str, + variant_name: String, + }, + Untagged, +} + +fn serialize_struct_variant<'a>( + context: StructVariant<'a>, + params: &Parameters, + fields: &[Field], + name: &str, +) -> Fragment { + if fields.iter().any(|field| field.attrs.flatten()) { + return serialize_struct_variant_with_flatten(context, params, fields, name); + } + + let struct_trait = match context { + StructVariant::ExternallyTagged { .. } => StructTrait::SerializeStructVariant, + StructVariant::InternallyTagged { .. } | StructVariant::Untagged => { + StructTrait::SerializeStruct + } + }; + + let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields + .map(|field| { + let member = &field.member; + + match field.attrs.skip_serializing_if() { + Some(path) => quote!(if #path(#member) { 0 } else { 1 }), + None => quote!(1), + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + match context { + StructVariant::ExternallyTagged { + variant_index, + variant_name, + } => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant( + __serializer, + #name, + #variant_index, + #variant_name, + #len, + )); + #(#serialize_fields)* + _serde::ser::SerializeStructVariant::end(__serde_state) + } + } + StructVariant::InternallyTagged { tag, variant_name } => { + quote_block! { + let mut __serde_state = try!(_serde::Serializer::serialize_struct( + __serializer, + #name, + #len + 1, + )); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + #tag, + #variant_name, + )); + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } + } + StructVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct( + __serializer, + #name, + #len, + )); + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } + } + } +} + +fn serialize_struct_variant_with_flatten<'a>( + context: StructVariant<'a>, + params: &Parameters, + fields: &[Field], + name: &str, +) -> Fragment { + let struct_trait = StructTrait::SerializeMap; + let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + match context { + StructVariant::ExternallyTagged { + variant_index, + variant_name, + } => { + let this = ¶ms.this; + let fields_ty = fields.iter().map(|f| &f.ty); + let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>(); + + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a"); + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + quote_block! { + struct __EnumFlatten #wrapper_generics #where_clause { + data: (#(&'__a #fields_ty,)*), + phantom: _serde::export::PhantomData<#this #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let (#(#members,)*) = self.data; + let #let_mut __serde_state = try!(_serde::Serializer::serialize_map( + __serializer, + _serde::export::None)); + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } + } + + _serde::Serializer::serialize_newtype_variant( + __serializer, + #name, + #variant_index, + #variant_name, + &__EnumFlatten { + data: (#(#members,)*), + phantom: _serde::export::PhantomData::<#this #ty_generics>, + }) + } + } + StructVariant::InternallyTagged { tag, variant_name } => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_map( + __serializer, + _serde::export::None)); + try!(_serde::ser::SerializeMap::serialize_entry( + &mut __serde_state, + #tag, + #variant_name, + )); + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } + } + StructVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_map( + __serializer, + _serde::export::None)); + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } + } + } +} + +fn serialize_tuple_struct_visitor( + fields: &[Field], + params: &Parameters, + is_enum: bool, + tuple_trait: &TupleTrait, +) -> Vec<TokenStream> { + fields + .iter() + .enumerate() + .filter(|(_, field)| !field.attrs.skip_serializing()) + .map(|(i, field)| { + let mut field_expr = if is_enum { + let id = Ident::new(&format!("__field{}", i), Span::call_site()); + quote!(#id) + } else { + get_member( + params, + field, + &Member::Unnamed(Index { + index: i as u32, + span: Span::call_site(), + }), + ) + }; + + let skip = field + .attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); + + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = tuple_trait.serialize_element(span); + let ser = quote! { + try!(#func(&mut __serde_state, #field_expr)); + }; + + match skip { + None => ser, + Some(skip) => quote!(if !#skip { #ser }), + } + }) + .collect() +} + +fn serialize_struct_visitor( + fields: &[Field], + params: &Parameters, + is_enum: bool, + struct_trait: &StructTrait, +) -> Vec<TokenStream> { + fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .map(|field| { + let member = &field.member; + + let mut field_expr = if is_enum { + quote!(#member) + } else { + get_member(params, field, &member) + }; + + let key_expr = field.attrs.name().serialize_name(); + + let skip = field + .attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); + + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let ser = if field.attrs.flatten() { + let func = quote_spanned!(span=> _serde::Serialize::serialize); + quote! { + try!(#func(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state))); + } + } else { + let func = struct_trait.serialize_field(span); + quote! { + try!(#func(&mut __serde_state, #key_expr, #field_expr)); + } + }; + + match skip { + None => ser, + Some(skip) => { + if let Some(skip_func) = struct_trait.skip_field(span) { + quote! { + if !#skip { + #ser + } else { + try!(#skip_func(&mut __serde_state, #key_expr)); + } + } + } else { + quote! { + if !#skip { + #ser + } + } + } + } + } + }) + .collect() +} + +fn wrap_serialize_field_with( + params: &Parameters, + field_ty: &syn::Type, + serialize_with: &syn::ExprPath, + field_expr: &TokenStream, +) -> TokenStream { + wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)]) +} + +fn wrap_serialize_variant_with( + params: &Parameters, + serialize_with: &syn::ExprPath, + variant: &Variant, +) -> TokenStream { + let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect(); + let field_exprs: Vec<_> = variant + .fields + .iter() + .map(|field| { + let id = match &field.member { + Member::Named(ident) => ident.clone(), + Member::Unnamed(member) => { + Ident::new(&format!("__field{}", member.index), Span::call_site()) + } + }; + quote!(#id) + }) + .collect(); + wrap_serialize_with( + params, + serialize_with, + field_tys.as_slice(), + field_exprs.as_slice(), + ) +} + +fn wrap_serialize_with( + params: &Parameters, + serialize_with: &syn::ExprPath, + field_tys: &[&syn::Type], + field_exprs: &[TokenStream], +) -> TokenStream { + let this = ¶ms.this; + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + + let wrapper_generics = if field_exprs.is_empty() { + params.generics.clone() + } else { + bound::with_lifetime_bound(¶ms.generics, "'__a") + }; + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + let field_access = (0..field_exprs.len()).map(|n| { + Member::Unnamed(Index { + index: n as u32, + span: Span::call_site(), + }) + }); + + quote!({ + struct __SerializeWith #wrapper_impl_generics #where_clause { + values: (#(&'__a #field_tys, )*), + phantom: _serde::export::PhantomData<#this #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + #serialize_with(#(self.values.#field_access, )* __s) + } + } + + &__SerializeWith { + values: (#(#field_exprs, )*), + phantom: _serde::export::PhantomData::<#this #ty_generics>, + } + }) +} + +// Serialization of an empty struct results in code like: +// +// let mut __serde_state = try!(serializer.serialize_struct("S", 0)); +// _serde::ser::SerializeStruct::end(__serde_state) +// +// where we want to omit the `mut` to avoid a warning. +fn mut_if(is_mut: bool) -> Option<TokenStream> { + if is_mut { + Some(quote!(mut)) + } else { + None + } +} + +fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStream { + let self_var = ¶ms.self_var; + match (params.is_remote, field.attrs.getter()) { + (false, None) => { + if params.is_packed { + quote!(&{#self_var.#member}) + } else { + quote!(&#self_var.#member) + } + } + (true, None) => { + let inner = if params.is_packed { + quote!(&{#self_var.#member}) + } else { + quote!(&#self_var.#member) + }; + let ty = field.ty; + quote!(_serde::private::ser::constrain::<#ty>(#inner)) + } + (true, Some(getter)) => { + let ty = field.ty; + quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var))) + } + (false, Some(_)) => { + unreachable!("getter is only allowed for remote impls"); + } + } +} + +fn effective_style(variant: &Variant) -> Style { + match variant.style { + Style::Newtype if variant.fields[0].attrs.skip_serializing() => Style::Unit, + other => other, + } +} + +enum StructTrait { + SerializeMap, + SerializeStruct, + SerializeStructVariant, +} + +impl StructTrait { + fn serialize_field(&self, span: Span) -> TokenStream { + match *self { + StructTrait::SerializeMap => { + quote_spanned!(span=> _serde::ser::SerializeMap::serialize_entry) + } + StructTrait::SerializeStruct => { + quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field) + } + StructTrait::SerializeStructVariant => { + quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field) + } + } + } + + fn skip_field(&self, span: Span) -> Option<TokenStream> { + match *self { + StructTrait::SerializeMap => None, + StructTrait::SerializeStruct => { + Some(quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field)) + } + StructTrait::SerializeStructVariant => { + Some(quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field)) + } + } + } +} + +enum TupleTrait { + SerializeTuple, + SerializeTupleStruct, + SerializeTupleVariant, +} + +impl TupleTrait { + fn serialize_element(&self, span: Span) -> TokenStream { + match *self { + TupleTrait::SerializeTuple => { + quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element) + } + TupleTrait::SerializeTupleStruct => { + quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field) + } + TupleTrait::SerializeTupleVariant => { + quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field) + } + } + } +} diff --git a/third_party/rust/serde_derive/src/try.rs b/third_party/rust/serde_derive/src/try.rs new file mode 100644 index 0000000000..48829b6354 --- /dev/null +++ b/third_party/rust/serde_derive/src/try.rs @@ -0,0 +1,24 @@ +use proc_macro2::{Punct, Spacing, TokenStream}; + +// None of our generated code requires the `From::from` error conversion +// performed by the standard library's `try!` macro. With this simplified macro +// we see a significant improvement in type checking and borrow checking time of +// the generated code and a slight improvement in binary size. +pub fn replacement() -> TokenStream { + // Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it. + let dollar = Punct::new('$', Spacing::Alone); + + quote! { + #[allow(unused_macros)] + macro_rules! try { + (#dollar __expr:expr) => { + match #dollar __expr { + _serde::export::Ok(__val) => __val, + _serde::export::Err(__err) => { + return _serde::export::Err(__err); + } + } + } + } + } +} 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 0000000000..b8867e5874 --- /dev/null +++ b/third_party/rust/serde_json/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"a823b487f62df520ee18a40f0f79564b76a770b10950b39ff21ddd7d399f1b6e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"115523105e7a22d12431db82517fbb6067f0c7658a9e9cd68184af025bd9dcd3","src/de.rs":"dbde342795700d07494cb31179187187a951cd8647a4d80bbf84d220dff96b9f","src/error.rs":"cfe58033d9ac80dc7f5f53333b7e35d188280f4342e58519b1c3b7b99e04be57","src/iter.rs":"181565ab2ac9f964efcebf206bca38cc704f0ae6d74c8321a21c927c9299483e","src/lib.rs":"584d052f558f8be69a82a025f328d071e225fbc7b491006eebd39cbda26ed984","src/macros.rs":"c4578cb13f32a59417aae9dd78168860caaf7519c23babd889df0563d3c28c8a","src/map.rs":"2bec9b9c749a5c58787295dbacb28442cbe49573a87a6f478d781ceb9bdc0c7d","src/number.rs":"030e822024278c6901f2fca9c59452f35442a2be598f62b99ae671f6a6dc2cf1","src/raw.rs":"b75575758bb9185fac3b8ef8faf67b8b2fd99f1d4a7595a93e61c57189d63662","src/read.rs":"0feadc63746c5749f88d4e6fc105c6ae62ca460d0c4eb8895dc5d090890c5a5c","src/ser.rs":"6057f3bf65420ed6928f4e69997351a4acc6e2c7ac74c14f9fdaec4271b6b5b2","src/value/de.rs":"c385339a6db6128043c5ead24b68dd99b7877c6a2aca7740fb2786741fbe198a","src/value/from.rs":"d96549514be863b57e4760bd2b4acdac281b00b3391d2741ab77f5b84aa8f73b","src/value/index.rs":"ab8c66dd093feabd235c1cc6c43629619ca450e83a0c7cd7f65d5fc92e68204f","src/value/mod.rs":"7f1a01ed095b9210bac9f5439bc465682a8044dccbff7f6003cc00c0090caf55","src/value/partial_eq.rs":"4f174d84f3de0bc686b2ce039f0eeacf48d747b8dabb2fe8c088156721320e6b","src/value/ser.rs":"ddd4ad344f2978775def9a7db92931a37cd74f479257498c8b87da4c261f79eb"},"package":"48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"}
\ 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 0000000000..d9b07f8342 --- /dev/null +++ b/third_party/rust/serde_json/Cargo.toml @@ -0,0 +1,70 @@ +# 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.44" +authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] +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 OR Apache-2.0" +repository = "https://github.com/serde-rs/json" +[package.metadata.docs.rs] +features = ["raw_value", "unbounded_depth"] + +[package.metadata.playground] +features = ["raw_value"] +[dependencies.indexmap] +version = "1.2" +optional = true + +[dependencies.itoa] +version = "0.4.3" + +[dependencies.ryu] +version = "1.0" + +[dependencies.serde] +version = "1.0.60" +[dev-dependencies.automod] +version = "0.1" + +[dev-dependencies.rustversion] +version = "1.0" + +[dev-dependencies.serde_bytes] +version = "0.11" + +[dev-dependencies.serde_derive] +version = "1.0" + +[dev-dependencies.serde_stacker] +version = "0.1" + +[dev-dependencies.trybuild] +version = "1.0" + +[features] +arbitrary_precision = [] +default = [] +preserve_order = ["indexmap"] +raw_value = [] +unbounded_depth = [] +[badges.appveyor] +repository = "serde-rs/json" + +[badges.travis-ci] +repository = "serde-rs/json" diff --git a/third_party/rust/serde_json/LICENSE-APACHE b/third_party/rust/serde_json/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_json/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/serde_json/LICENSE-MIT b/third_party/rust/serde_json/LICENSE-MIT new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/third_party/rust/serde_json/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_json/README.md b/third_party/rust/serde_json/README.md new file mode 100644 index 0000000000..d67cf229b3 --- /dev/null +++ b/third_party/rust/serde_json/README.md @@ -0,0 +1,353 @@ +# 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 +{ + "name": "John Doe", + "age": 43, + "address": { + "street": "10 Downing Street", + "city": "London" + }, + "phones": [ + "+44 1234567", + "+44 2345678" + ] +} +``` + +There are three common ways that you might find yourself needing to work +with JSON data in Rust. + + - **As text data.** An unprocessed string of JSON data that you receive on + an HTTP endpoint, read from a file, or prepare to send to a remote + server. + - **As an untyped or loosely typed representation.** Maybe you want to + check that some JSON data is valid before passing it on, but without + knowing the structure of what it contains. Or you want to do very basic + manipulations like insert a key in a particular spot. + - **As a strongly typed Rust data structure.** When you expect all or most + of your data to conform to a particular structure and want to get real + work done without JSON's loosey-goosey nature tripping you up. + +Serde JSON provides efficient, flexible, safe ways of converting data +between each of these representations. + +## Operating on untyped JSON values + +Any valid JSON data can be manipulated in the following recursive enum +representation. This data structure is [`serde_json::Value`][value]. + +```rust +enum Value { + Null, + Bool(bool), + Number(Number), + String(String), + Array(Vec<Value>), + Object(Map<String, Value>), +} +``` + +A string of JSON data can be parsed into a `serde_json::Value` by the +[`serde_json::from_str`][from_str] function. There is also +[`from_slice`][from_slice] for parsing from a byte slice &[u8] and +[`from_reader`][from_reader] for parsing from any `io::Read` like a File or +a TCP stream. + +<a href="https://play.rust-lang.org/?edition=2018&gist=d69d8e3156d4bb81c4461b60b772ab72" target="_blank"> +<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png"> +</a> + +```rust +use serde_json::{Result, Value}; + +fn untyped_example() -> Result<()> { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#" + { + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + // Parse the string of data into serde_json::Value. + let v: Value = serde_json::from_str(data)?; + + // Access parts of the data by indexing with square brackets. + println!("Please call {} at the number {}", v["name"], v["phones"][0]); + + Ok(()) +} +``` + +The result of square bracket indexing like `v["name"]` is a borrow of the data +at that index, so the type is `&Value`. A JSON map can be indexed with string +keys, while a JSON array can be indexed with integer keys. If the type of the +data is not right for the type with which it is being indexed, or if a map does +not contain the key being indexed, or if the index into a vector is out of +bounds, the returned element is `Value::Null`. + +When a `Value` is printed, it is printed as a JSON string. So in the code above, +the output looks like `Please call "John Doe" at the number "+44 1234567"`. The +quotation marks appear because `v["name"]` is a `&Value` containing a JSON +string and its JSON representation is `"John Doe"`. Printing as a plain string +without quotation marks involves converting from a JSON string to a Rust string +with [`as_str()`] or avoiding the use of `Value` as described in the following +section. + +[`as_str()`]: https://docs.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. + +<a href="https://play.rust-lang.org/?edition=2018&gist=15cfab66d38ff8a15a9cf1d8d897ac68" target="_blank"> +<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png"> +</a> + +```rust +use serde::{Deserialize, Serialize}; +use serde_json::Result; + +#[derive(Serialize, Deserialize)] +struct Person { + name: String, + age: u8, + phones: Vec<String>, +} + +fn typed_example() -> Result<()> { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#" + { + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + // Parse the string of data into a Person object. This is exactly the + // same function as the one that produced serde_json::Value above, but + // now we are asking it for a Person as output. + let p: Person = serde_json::from_str(data)?; + + // Do things just like with any other Rust data structure. + println!("Please call {} at the number {}", p.name, p.phones[0]); + + Ok(()) +} +``` + +This is the same `serde_json::from_str` function as before, but this time we +assign the return value to a variable of type `Person` so Serde will +automatically interpret the input data as a `Person` and produce informative +error messages if the layout does not conform to what a `Person` is expected +to look like. + +Any type that implements Serde's `Deserialize` trait can be deserialized +this way. This includes built-in Rust standard library types like `Vec<T>` +and `HashMap<K, V>`, as well as any structs or enums annotated with +`#[derive(Deserialize)]`. + +Once we have `p` of type `Person`, our IDE and the Rust compiler can help us +use it correctly like they do for any other Rust code. The IDE can +autocomplete field names to prevent typos, which was impossible in the +`serde_json::Value` representation. And the Rust compiler can check that +when we write `p.phones[0]`, then `p.phones` is guaranteed to be a +`Vec<String>` so indexing into it makes sense and produces a `String`. + +## Constructing JSON values + +Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +objects with very natural JSON syntax. + +<a href="https://play.rust-lang.org/?edition=2018&gist=6ccafad431d72b62e77cc34c8e879b24" target="_blank"> +<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png"> +</a> + +```rust +use serde_json::json; + +fn main() { + // The type of `john` is `serde_json::Value` + let john = json!({ + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }); + + println!("first phone number: {}", john["phones"][0]); + + // Convert to a string of JSON and print it out + println!("{}", john.to_string()); +} +``` + +The `Value::to_string()` function converts a `serde_json::Value` into a +`String` of JSON text. + +One neat thing about the `json!` macro is that variables and expressions can +be interpolated directly into the JSON value as you are building it. Serde +will check at compile time that the value you are interpolating is able to +be represented as JSON. + +<a href="https://play.rust-lang.org/?edition=2018&gist=f9101a6e61dfc9e02c6a67f315ed24f2" target="_blank"> +<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png"> +</a> + +```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<u8>` and +[`serde_json::to_writer`][to_writer] which serializes to any `io::Write` +such as a File or a TCP stream. + +<a href="https://play.rust-lang.org/?edition=2018&gist=3472242a08ed2ff88a944f2a2283b0ee" target="_blank"> +<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png"> +</a> + +```rust +use serde::{Deserialize, Serialize}; +use serde_json::Result; + +#[derive(Serialize, Deserialize)] +struct Address { + street: String, + city: String, +} + +fn print_an_address() -> Result<()> { + // Some data structure. + let address = Address { + street: "10 Downing Street".to_owned(), + city: "London".to_owned(), + }; + + // Serialize it to a JSON string. + let j = serde_json::to_string(&address)?; + + // Print, write to a file, or send to an HTTP server. + println!("{}", j); + + Ok(()) +} +``` + +Any type that implements Serde's `Serialize` trait can be serialized this +way. This includes built-in Rust standard library types like `Vec<T>` and +`HashMap<K, V>`, as well as any structs or enums annotated with +`#[derive(Serialize)]`. + +## Performance + +It is fast. You should expect in the ballpark of 500 to 1000 megabytes per +second deserialization and 600 to 900 megabytes per second serialization, +depending on the characteristics of your data. This is competitive with the +fastest C and C++ JSON libraries or even 30% faster for many use cases. +Benchmarks live in the [serde-rs/json-benchmark] repo. + +[serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark + +## Getting help + +Serde 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/ + +[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 + +<br> + +#### License + +<sup> +Licensed under either of <a href="LICENSE-APACHE">Apache License, Version +2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. +</sup> + +<br> + +<sub> +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. +</sub> 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 0000000000..5c9c20b20c --- /dev/null +++ b/third_party/rust/serde_json/src/de.rs @@ -0,0 +1,2380 @@ +//! 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<R> { + read: R, + scratch: Vec<u8>, + remaining_depth: u8, + #[cfg(feature = "unbounded_depth")] + disable_recursion_limit: bool, +} + +impl<'de, R> Deserializer<R> +where + R: read::Read<'de>, +{ + /// Create a JSON deserializer from one of the possible serde_json input + /// sources. + /// + /// Typically it is more convenient to use one of these methods instead: + /// + /// - Deserializer::from_str + /// - Deserializer::from_bytes + /// - Deserializer::from_reader + pub fn new(read: R) -> Self { + #[cfg(not(feature = "unbounded_depth"))] + { + Deserializer { + read: read, + scratch: Vec::new(), + remaining_depth: 128, + } + } + + #[cfg(feature = "unbounded_depth")] + { + Deserializer { + read: read, + scratch: Vec::new(), + remaining_depth: 128, + disable_recursion_limit: false, + } + } + } +} + +impl<R> Deserializer<read::IoRead<R>> +where + R: io::Read, +{ + /// Creates a JSON deserializer from an `io::Read`. + /// + /// Reader-based deserializers do not support deserializing borrowed types + /// like `&str`, since the `std::io::Read` trait has no non-copying methods + /// -- everything it does involves copying bytes out of the data source. + pub fn from_reader(reader: R) -> Self { + Deserializer::new(read::IoRead::new(reader)) + } +} + +impl<'a> Deserializer<read::SliceRead<'a>> { + /// Creates a JSON deserializer from a `&[u8]`. + pub fn from_slice(bytes: &'a [u8]) -> Self { + Deserializer::new(read::SliceRead::new(bytes)) + } +} + +impl<'a> Deserializer<read::StrRead<'a>> { + /// 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<V::Value> + 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<R> { + /// 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<T>(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, + } + } + + /// Parse arbitrarily deep JSON structures without any consideration for + /// overflowing the stack. + /// + /// You will want to provide some other way to protect against stack + /// overflows, such as by wrapping your Deserializer in the dynamically + /// growing stack adapter provided by the serde_stacker crate. Additionally + /// you will need to be careful around other recursive operations on the + /// parsed result which may overflow the stack after deserialization has + /// completed, including, but not limited to, Display and Debug and Drop + /// impls. + /// + /// *This method is only available if serde_json is built with the + /// `"unbounded_depth"` feature.* + /// + /// # Examples + /// + /// ```edition2018 + /// use serde::Deserialize; + /// use serde_json::Value; + /// + /// fn main() { + /// let mut json = String::new(); + /// for _ in 0..10000 { + /// json = format!("[{}]", json); + /// } + /// + /// let mut deserializer = serde_json::Deserializer::from_str(&json); + /// deserializer.disable_recursion_limit(); + /// let deserializer = serde_stacker::Deserializer::new(&mut deserializer); + /// let value = Value::deserialize(deserializer).unwrap(); + /// + /// carefully_drop_nested_arrays(value); + /// } + /// + /// fn carefully_drop_nested_arrays(value: Value) { + /// let mut stack = vec![value]; + /// while let Some(value) = stack.pop() { + /// if let Value::Array(array) = value { + /// stack.extend(array); + /// } + /// } + /// } + /// ``` + #[cfg(feature = "unbounded_depth")] + pub fn disable_recursion_limit(&mut self) { + self.disable_recursion_limit = true; + } + + fn peek(&mut self) -> Result<Option<u8>> { + self.read.peek() + } + + fn peek_or_null(&mut self) -> Result<u8> { + Ok(try!(self.peek()).unwrap_or(b'\x00')) + } + + fn eat_char(&mut self) { + self.read.discard(); + } + + fn next_char(&mut self) -> Result<Option<u8>> { + self.read.next() + } + + fn next_char_or_null(&mut self) -> Result<u8> { + 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<Option<u8>> { + 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.scratch.clear(); + match self.read.parse_str(&mut self.scratch) { + Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp), + Err(err) => return err, + } + } + b'[' => de::Error::invalid_type(Unexpected::Seq, exp), + b'{' => de::Error::invalid_type(Unexpected::Map, exp), + _ => self.peek_error(ErrorCode::ExpectedSomeValue), + }; + + self.fix_position(err) + } + + fn deserialize_prim_number<V>(&mut self, visitor: V) -> Result<V::Value> + 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<ParserNumber> { + let next = match try!(self.next_char()) { + Some(b) => b, + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + }; + + match next { + b'0' => { + // There can be only one leading '0'. + match 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<f64> { + 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<ParserNumber> { + 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<f64> { + 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 { + match try!(self.peek()) { + Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + 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<f64> { + self.eat_char(); + + let positive_exp = match try!(self.peek_or_null()) { + b'+' => { + self.eat_char(); + true + } + b'-' => { + self.eat_char(); + false + } + _ => true, + }; + + let next = match try!(self.next_char()) { + Some(b) => b, + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + }; + + // Make sure a digit follows the exponent place. + let mut exp = match next { + c @ b'0'...b'9' => (c - b'0') as i32, + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + }; + + while let c @ b'0'...b'9' = 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<f64> { + // 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<ParserNumber> { + 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<ParserNumber> { + self.parse_integer(positive) + } + + #[cfg(feature = "arbitrary_precision")] + fn parse_any_number(&mut self, positive: bool) -> Result<ParserNumber> { + let mut buf = String::with_capacity(16); + if !positive { + buf.push('-'); + } + self.scan_integer(&mut buf)?; + Ok(ParserNumber::String(buf)) + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_or_eof(&mut self, buf: &mut String) -> Result<u8> { + match try!(self.next_char()) { + Some(b) => { + buf.push(b as char); + Ok(b) + } + None => Err(self.error(ErrorCode::EofWhileParsingValue)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_integer(&mut self, buf: &mut String) -> Result<()> { + match try!(self.scan_or_eof(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 { + match try!(self.peek()) { + Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + 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_eof(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<f64> { + let mut f = significand as f64; + loop { + match POW10.get(exponent.wrapping_abs() as usize) { + Some(&pow) => { + if exponent >= 0 { + f *= pow; + if f.is_infinite() { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + } else { + f /= pow; + } + break; + } + 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<()> { + self.scratch.clear(); + let mut enclosing = None; + + loop { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let frame = match peek { + b'n' => { + self.eat_char(); + try!(self.parse_ident(b"ull")); + None + } + b't' => { + self.eat_char(); + try!(self.parse_ident(b"rue")); + None + } + b'f' => { + self.eat_char(); + try!(self.parse_ident(b"alse")); + None + } + b'-' => { + self.eat_char(); + try!(self.ignore_integer()); + None + } + b'0'...b'9' => { + try!(self.ignore_integer()); + None + } + b'"' => { + self.eat_char(); + try!(self.read.ignore_str()); + None + } + frame @ b'[' | frame @ b'{' => { + self.scratch.extend(enclosing.take()); + self.eat_char(); + Some(frame) + } + _ => return Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + }; + + let (mut accept_comma, mut frame) = match frame { + Some(frame) => (false, frame), + None => match enclosing.take() { + Some(frame) => (true, frame), + None => match self.scratch.pop() { + Some(frame) => (true, frame), + None => return Ok(()), + }, + }, + }; + + loop { + match try!(self.parse_whitespace()) { + Some(b',') if accept_comma => { + self.eat_char(); + break; + } + Some(b']') if frame == b'[' => {} + Some(b'}') if frame == b'{' => {} + Some(_) => { + if accept_comma { + return Err(self.peek_error(match frame { + b'[' => ErrorCode::ExpectedListCommaOrEnd, + b'{' => ErrorCode::ExpectedObjectCommaOrEnd, + _ => unreachable!(), + })); + } else { + break; + } + } + None => { + return Err(self.peek_error(match frame { + b'[' => ErrorCode::EofWhileParsingList, + b'{' => ErrorCode::EofWhileParsingObject, + _ => unreachable!(), + })); + } + } + + self.eat_char(); + frame = match self.scratch.pop() { + Some(frame) => frame, + None => return Ok(()), + }; + accept_comma = true; + } + + if frame == b'{' { + match try!(self.parse_whitespace()) { + Some(b'"') => self.eat_char(), + Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + try!(self.read.ignore_str()); + match try!(self.parse_whitespace()) { + Some(b':') => self.eat_char(), + Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + + enclosing = Some(frame); + } + } + + fn ignore_integer(&mut self) -> Result<()> { + match 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(()) + } + + #[cfg(feature = "raw_value")] + fn deserialize_raw_value<V>(&mut self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.parse_whitespace()?; + self.read.begin_raw_buffering(); + self.ignore_value()?; + self.read.end_raw_buffering(visitor) + } +} + +impl FromStr for Number { + type Err = Error; + + fn from_str(s: &str) -> result::Result<Self, Self::Err> { + Deserializer::from_str(s) + .parse_any_signed_number() + .map(Into::into) + } +} + +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<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.deserialize_prim_number(visitor) + } + } +} + +#[cfg(not(feature = "unbounded_depth"))] +macro_rules! if_checking_recursion_limit { + ($($body:tt)*) => { + $($body)* + }; +} + +#[cfg(feature = "unbounded_depth")] +macro_rules! if_checking_recursion_limit { + ($this:ident $($body:tt)*) => { + if !$this.disable_recursion_limit { + $this $($body)* + } + }; +} + +macro_rules! check_recursion { + ($this:ident $($body:tt)*) => { + if_checking_recursion_limit! { + $this.remaining_depth -= 1; + if $this.remaining_depth == 0 { + return Err($this.peek_error(ErrorCode::RecursionLimitExceeded)); + } + } + + $this $($body)* + + if_checking_recursion_limit! { + $this.remaining_depth += 1; + } + }; +} + +impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> { + type Error = Error; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + 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.scratch.clear(); + match try!(self.read.parse_str(&mut self.scratch)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + b'[' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + } + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + b'{' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + } + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + }; + + match value { + Ok(value) => Ok(value), + // The de::Error impl creates errors with unknown line and column. + // Fill in the position here by looking at the current index in the + // input. There is no way to tell whether this should call `error` + // or `peek_error` so pick the one that seems correct more often. + // Worst case, the position is off by one character. + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> + 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.scratch.clear(); + match try!(self.read.parse_str(&mut self.scratch)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> + 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. + /// + /// ```edition2018 + /// use serde_bytes::ByteBuf; + /// + /// fn look_at_bytes() -> Result<(), serde_json::Error> { + /// let json_data = b"\"some bytes: \xe5\x00\xe5\""; + /// let bytes: ByteBuf = serde_json::from_slice(json_data)?; + /// + /// assert_eq!(b'\xe5', bytes[12]); + /// assert_eq!(b'\0', bytes[13]); + /// assert_eq!(b'\xe5', bytes[14]); + /// + /// Ok(()) + /// } + /// # + /// # look_at_bytes().unwrap(); + /// ``` + /// + /// Backslash escape sequences like `\n` are still interpreted and required + /// to be valid, and `\u` escape sequences are required to represent valid + /// Unicode code points. + /// + /// ```edition2018 + /// use serde_bytes::ByteBuf; + /// + /// fn look_at_bytes() { + /// let json_data = b"\"invalid unicode surrogate: \\uD801\""; + /// let parsed: Result<ByteBuf, _> = serde_json::from_slice(json_data); + /// + /// assert!(parsed.is_err()); + /// + /// let expected_msg = "unexpected end of hex escape at line 1 column 35"; + /// assert_eq!(expected_msg, parsed.unwrap_err().to_string()); + /// } + /// # + /// # look_at_bytes(); + /// ``` + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> + 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.scratch.clear(); + match try!(self.read.parse_str_raw(&mut self.scratch)) { + Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), + Reference::Copied(b) => visitor.visit_bytes(b), + } + } + b'[' => self.deserialize_seq(visitor), + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + #[inline] + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + /// Parses a newtype struct as the underlying value. + #[inline] + fn deserialize_newtype_struct<V>(self, name: &str, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == ::raw::TOKEN { + return self.deserialize_raw_value(visitor); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> + 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'[' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + } + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> + 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'{' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + } + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + 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'[' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + } + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + b'{' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + } + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + /// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight + /// value, a `[..]`, or a `{..}`. + #[inline] + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + match try!(self.parse_whitespace()) { + Some(b'{') => { + check_recursion! { + self.eat_char(); + let value = try!(visitor.visit_enum(VariantAccess::new(self))); + } + + 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<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + try!(self.ignore_value()); + visitor.visit_unit() + } +} + +struct SeqAccess<'a, R: 'a> { + de: &'a mut Deserializer<R>, + first: bool, +} + +impl<'a, R: 'a> SeqAccess<'a, R> { + fn new(de: &'a mut Deserializer<R>) -> 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<T>(&mut self, seed: T) -> Result<Option<T::Value>> + 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<R>, + first: bool, +} + +impl<'a, R: 'a> MapAccess<'a, R> { + fn new(de: &'a mut Deserializer<R>) -> 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<K>(&mut self, seed: K) -> Result<Option<K::Value>> + 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<V>(&mut self, seed: V) -> Result<V::Value> + 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<R>, +} + +impl<'a, R: 'a> VariantAccess<'a, R> { + fn new(de: &'a mut Deserializer<R>) -> 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<V>(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<T>(self, seed: T) -> Result<T::Value> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self.de) + } + + fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + de::Deserializer::deserialize_seq(self.de, visitor) + } + + fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + de::Deserializer::deserialize_struct(self.de, "", fields, visitor) + } +} + +struct UnitVariantAccess<'a, R: 'a> { + de: &'a mut Deserializer<R>, +} + +impl<'a, R: 'a> UnitVariantAccess<'a, R> { + fn new(de: &'a mut Deserializer<R>) -> 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<V>(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<T>(self, _seed: T) -> Result<T::Value> + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value> + 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<R>, +} + +macro_rules! deserialize_integer_key { + ($method:ident => $visit:ident) => { + fn $method<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + self.de.scratch.clear(); + let string = try!(self.de.read.parse_str(&mut self.de.scratch)); + match (string.parse(), string) { + (Ok(integer), _) => visitor.$visit(integer), + (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s), + (Err(_), Reference::Copied(s)) => visitor.visit_str(s), + } + } + } +} + +impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R> +where + R: Read<'de>, +{ + type Error = Error; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + self.de.scratch.clear(); + match try!(self.de.read.parse_str(&mut self.de.scratch)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + + deserialize_integer_key!(deserialize_i8 => visit_i8); + deserialize_integer_key!(deserialize_i16 => visit_i16); + deserialize_integer_key!(deserialize_i32 => visit_i32); + deserialize_integer_key!(deserialize_i64 => visit_i64); + deserialize_integer_key!(deserialize_u8 => visit_u8); + deserialize_integer_key!(deserialize_u16 => visit_u16); + deserialize_integer_key!(deserialize_u32 => visit_u32); + deserialize_integer_key!(deserialize_u64 => visit_u64); + + serde_if_integer128! { + deserialize_integer_key!(deserialize_i128 => visit_i128); + deserialize_integer_key!(deserialize_u128 => visit_u128); + } + + #[inline] + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + #[inline] + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.de.deserialize_enum(name, variants, visitor) + } + + #[inline] + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> + where + V: de::Visitor<'de>, + { + self.de.deserialize_bytes(visitor) + } + + #[inline] + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> + 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. +/// +/// ```edition2018 +/// 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::<Value>(); +/// +/// for value in stream { +/// println!("{}", value.unwrap()); +/// } +/// } +/// ``` +pub struct StreamDeserializer<'de, R, T> { + de: Deserializer<R>, + offset: usize, + output: PhantomData<T>, + 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. + /// + /// ```edition2018 + /// let data = b"[0] [1] ["; + /// + /// let de = serde_json::Deserializer::from_slice(data); + /// let mut stream = de.into_iter::<Vec<i32>>(); + /// 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<T>; + + fn next(&mut self) -> Option<Result<T>> { + // 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<T> +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. +/// +/// The content of the IO stream is deserialized directly from the stream +/// without being buffered in memory by serde_json. +/// +/// When reading from a source against which short reads are not efficient, such +/// as a [`File`], you will want to apply your own buffering because serde_json +/// will not buffer the input. See [`std::io::BufReader`]. +/// +/// It is expected that the input stream ends after the deserialized object. +/// If the stream does not end, such as in the case of a persistent socket connection, +/// this function will not return. It is possible instead to deserialize from a prefix of an input +/// stream without looking for EOF by managing your own [`Deserializer`]. +/// +/// Note that counter to intuition, this function is usually slower than +/// reading a file completely into memory and then applying [`from_str`] +/// or [`from_slice`] on it. See [issue #160]. +/// +/// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html +/// [`std::io::BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html +/// [`from_str`]: ./fn.from_str.html +/// [`from_slice`]: ./fn.from_slice.html +/// [issue #160]: https://github.com/serde-rs/json/issues/160 +/// +/// # Example +/// +/// Reading the contents of a file. +/// +/// ```edition2018 +/// use serde::Deserialize; +/// +/// use std::error::Error; +/// use std::fs::File; +/// use std::io::BufReader; +/// use std::path::Path; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn read_user_from_file<P: AsRef<Path>>(path: P) -> Result<User, Box<Error>> { +/// // Open the file in read-only mode with buffer. +/// let file = File::open(path)?; +/// let reader = BufReader::new(file); +/// +/// // Read the JSON contents of the file as an instance of `User`. +/// let u = serde_json::from_reader(reader)?; +/// +/// // Return the `User`. +/// Ok(u) +/// } +/// +/// fn main() { +/// # } +/// # fn fake_main() { +/// let u = read_user_from_file("test.json").unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// Reading from a persistent socket connection. +/// +/// ```edition2018 +/// use serde::Deserialize; +/// +/// use std::error::Error; +/// use std::net::{TcpListener, TcpStream}; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn read_user_from_stream(tcp_stream: TcpStream) -> Result<User, Box<dyn Error>> { +/// let mut de = serde_json::Deserializer::from_reader(tcp_stream); +/// let u = User::deserialize(&mut de)?; +/// +/// Ok(u) +/// } +/// +/// fn main() { +/// # } +/// # fn fake_main() { +/// let listener = TcpListener::bind("127.0.0.1:4000").unwrap(); +/// +/// for stream in listener.incoming() { +/// println!("{:#?}", read_user_from_stream(stream.unwrap())); +/// } +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_reader<R, T>(rdr: R) -> Result<T> +where + R: io::Read, + T: de::DeserializeOwned, +{ + from_trait(read::IoRead::new(rdr)) +} + +/// Deserialize an instance of type `T` from bytes of JSON text. +/// +/// # Example +/// +/// ```edition2018 +/// use serde::Deserialize; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `&[u8]` +/// let j = b" +/// { +/// \"fingerprint\": \"0xF9BA143B95FF6D82\", +/// \"location\": \"Menlo Park, CA\" +/// }"; +/// +/// let u: User = serde_json::from_slice(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T> +where + T: de::Deserialize<'a>, +{ + from_trait(read::SliceRead::new(v)) +} + +/// Deserialize an instance of type `T` from a string of JSON text. +/// +/// # Example +/// +/// ```edition2018 +/// use serde::Deserialize; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `&str` +/// let j = " +/// { +/// \"fingerprint\": \"0xF9BA143B95FF6D82\", +/// \"location\": \"Menlo Park, CA\" +/// }"; +/// +/// let u: User = serde_json::from_str(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_str<'a, T>(s: &'a str) -> Result<T> +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 0000000000..42f09373a1 --- /dev/null +++ b/third_party/rust/serde_json/src/error.rs @@ -0,0 +1,472 @@ +//! When serializing or deserializing JSON goes wrong. + +use std::error; +use std::fmt::{self, Debug, Display}; +use std::io; +use std::result; +use std::str::FromStr; + +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<T, Error>`. + err: Box<ErrorImpl>, +} + +/// Alias for a `Result` with the error type `serde_json::Error`. +pub type Result<T> = result::Result<T, Error>; + +impl Error { + /// One-based line number at which the error was detected. + /// + /// Characters in the first line of the input (before the first newline + /// character) are in line 1. + pub fn line(&self) -> usize { + self.err.line + } + + /// One-based column number at which the error was detected. + /// + /// The first character in the input and any characters immediately + /// following a newline character are in column 1. + /// + /// Note that errors may occur in column 0, for example if a read from an 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<Error> 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. + /// + /// ```edition2018 + /// use std::io; + /// + /// enum MyError { + /// Io(io::Error), + /// Json(serde_json::Error), + /// } + /// + /// impl From<serde_json::Error> for MyError { + /// fn from(err: serde_json::Error) -> MyError { + /// use serde_json::error::Category; + /// match err.classify() { + /// Category::Io => { + /// MyError::Io(err.into()) + /// } + /// Category::Syntax | Category::Data | Category::Eof => { + /// MyError::Json(err) + /// } + /// } + /// } + /// } + /// ``` + fn from(j: Error) -> Self { + if let ErrorCode::Io(err) = j.err.code { + err + } else { + match j.classify() { + Category::Io => unreachable!(), + Category::Syntax | Category::Data => io::Error::new(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<str>), + + /// 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<F>(self, f: F) -> Self + where + F: FnOnce(ErrorCode) -> Error, + { + if self.err.line == 0 { + f(self.err.code) + } else { + self + } + } +} + +impl Display for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ErrorCode::Message(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<T: Display>(msg: T) -> Error { + make_error(msg.to_string()) + } + + #[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<T: Display>(msg: T) -> Error { + make_error(msg.to_string()) + } +} + +// Parse our own error message that looks like "{} at line {} column {}" to work +// around erased-serde round-tripping the error through de::Error::custom. +fn make_error(mut msg: String) -> Error { + let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0)); + Error { + err: Box::new(ErrorImpl { + code: ErrorCode::Message(msg.into_boxed_str()), + line: line, + column: column, + }), + } +} + +fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> { + let start_of_suffix = match msg.rfind(" at line ") { + Some(index) => index, + None => return None, + }; + + // Find start and end of line number. + let start_of_line = start_of_suffix + " at line ".len(); + let mut end_of_line = start_of_line; + while starts_with_digit(&msg[end_of_line..]) { + end_of_line += 1; + } + + if !msg[end_of_line..].starts_with(" column ") { + return None; + } + + // Find start and end of column number. + let start_of_column = end_of_line + " column ".len(); + let mut end_of_column = start_of_column; + while starts_with_digit(&msg[end_of_column..]) { + end_of_column += 1; + } + + if end_of_column < msg.len() { + return None; + } + + // Parse numbers. + let line = match usize::from_str(&msg[start_of_line..end_of_line]) { + Ok(line) => line, + Err(_) => return None, + }; + let column = match usize::from_str(&msg[start_of_column..end_of_column]) { + Ok(column) => column, + Err(_) => return None, + }; + + msg.truncate(start_of_suffix); + Some((line, column)) +} + +fn starts_with_digit(slice: &str) -> bool { + match slice.as_bytes().get(0) { + None => false, + Some(&byte) => byte >= b'0' && byte <= b'9', + } +} diff --git a/third_party/rust/serde_json/src/iter.rs b/third_party/rust/serde_json/src/iter.rs new file mode 100644 index 0000000000..1a9a954d15 --- /dev/null +++ b/third_party/rust/serde_json/src/iter.rs @@ -0,0 +1,70 @@ +use std::io; + +pub struct LineColIterator<I> { + iter: I, + + /// Index of the current line. Characters in the first line of the input + /// (before the first newline character) are in line 1. + line: usize, + + /// Index of the current column. The first character in the input and any + /// characters immediately following a newline character are in column 1. + /// The column is 0 immediately after a newline character has been read. + col: usize, + + /// Byte offset of the start of the current line. This is the sum of 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<I> LineColIterator<I> +where + I: Iterator<Item = io::Result<u8>>, +{ + pub fn new(iter: I) -> LineColIterator<I> { + 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<I> Iterator for LineColIterator<I> +where + I: Iterator<Item = io::Result<u8>>, +{ + type Item = io::Result<u8>; + + fn next(&mut self) -> Option<io::Result<u8>> { + match self.iter.next() { + None => None, + Some(Ok(b'\n')) => { + self.start_of_line += self.col + 1; + self.line += 1; + self.col = 0; + Some(Ok(b'\n')) + } + Some(Ok(c)) => { + self.col += 1; + Some(Ok(c)) + } + Some(Err(e)) => Some(Err(e)), + } + } +} 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 0000000000..fe442ca26a --- /dev/null +++ b/third_party/rust/serde_json/src/lib.rs @@ -0,0 +1,372 @@ +//! # Serde JSON +//! +//! JSON is a ubiquitous open-standard format that uses human-readable text to +//! transmit data objects consisting of key-value pairs. +//! +//! ```json +//! { +//! "name": "John Doe", +//! "age": 43, +//! "address": { +//! "street": "10 Downing Street", +//! "city": "London" +//! }, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! } +//! ``` +//! +//! There are three common ways that you might find yourself needing to work +//! with JSON data in Rust. +//! +//! - **As text data.** An unprocessed string of JSON data that you receive on +//! an HTTP endpoint, read from a file, or prepare to send to a remote +//! server. +//! - **As an untyped or loosely typed representation.** Maybe you want to +//! check that some JSON data is valid before passing it on, but without +//! knowing the structure of what it contains. Or you want to do very basic +//! manipulations like insert a key in a particular spot. +//! - **As a strongly typed Rust data structure.** When you expect all or most +//! of your data to conform to a particular structure and want to get real +//! work done without JSON's loosey-goosey nature tripping you up. +//! +//! Serde JSON provides efficient, flexible, safe ways of converting data +//! between each of these representations. +//! +//! # Operating on untyped JSON values +//! +//! Any valid JSON data can be manipulated in the following recursive enum +//! representation. This data structure is [`serde_json::Value`][value]. +//! +//! ```edition2018 +//! # use serde_json::{Number, Map}; +//! # +//! # #[allow(dead_code)] +//! enum Value { +//! Null, +//! Bool(bool), +//! Number(Number), +//! String(String), +//! Array(Vec<Value>), +//! Object(Map<String, Value>), +//! } +//! ``` +//! +//! A string of JSON data can be parsed into a `serde_json::Value` by the +//! [`serde_json::from_str`][from_str] function. There is also +//! [`from_slice`][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. +//! +//! ```edition2018 +//! use serde_json::{Result, Value}; +//! +//! fn untyped_example() -> Result<()> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into serde_json::Value. +//! let v: Value = serde_json::from_str(data)?; +//! +//! // Access parts of the data by indexing with square brackets. +//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # untyped_example().unwrap(); +//! # } +//! ``` +//! +//! The result of square bracket indexing like `v["name"]` is a borrow of the +//! data at that index, so the type is `&Value`. A JSON map can be indexed with +//! string keys, while a JSON array can be indexed with integer keys. If the +//! type of the data is not right for the type with which it is being indexed, +//! or if a map does not contain the key being indexed, or if the index into a +//! vector is out of bounds, the returned element is `Value::Null`. +//! +//! When a `Value` is printed, it is printed as a JSON string. So in the code +//! above, the output looks like `Please call "John Doe" at the number "+44 +//! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value` +//! containing a JSON string and its JSON representation is `"John Doe"`. +//! Printing as a plain string without quotation marks involves converting from +//! a JSON string to a Rust string with [`as_str()`] or avoiding the use of +//! `Value` as described in the following section. +//! +//! [`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str +//! +//! The `Value` representation is sufficient for very basic tasks but can be +//! tedious to work with for anything more significant. Error handling is +//! verbose to implement correctly, for example imagine trying to detect the +//! presence of unrecognized fields in the input data. The compiler is powerless +//! to help you when you make a mistake, for example imagine typoing `v["name"]` +//! as `v["nmae"]` in one of the dozens of places it is used in your code. +//! +//! # Parsing JSON as strongly typed data structures +//! +//! Serde provides a powerful way of mapping JSON data into Rust data structures +//! largely automatically. +//! +//! ```edition2018 +//! use serde::{Deserialize, Serialize}; +//! use serde_json::Result; +//! +//! #[derive(Serialize, Deserialize)] +//! struct Person { +//! name: String, +//! age: u8, +//! phones: Vec<String>, +//! } +//! +//! fn typed_example() -> Result<()> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into a Person object. This is exactly the +//! // same function as the one that produced serde_json::Value above, but +//! // now we are asking it for a Person as output. +//! let p: Person = serde_json::from_str(data)?; +//! +//! // Do things just like with any other Rust data structure. +//! println!("Please call {} at the number {}", p.name, p.phones[0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # typed_example().unwrap(); +//! # } +//! ``` +//! +//! This is the same `serde_json::from_str` function as before, but this time we +//! assign the return value to a variable of type `Person` so Serde will +//! automatically interpret the input data as a `Person` and produce informative +//! error messages if the layout does not conform to what a `Person` is expected +//! to look like. +//! +//! Any type that implements Serde's `Deserialize` trait can be deserialized +//! this way. This includes built-in Rust standard library types like `Vec<T>` +//! and `HashMap<K, V>`, as well as any structs or enums annotated with +//! `#[derive(Deserialize)]`. +//! +//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us +//! use it correctly like they do for any other Rust code. The IDE can +//! autocomplete field names to prevent typos, which was impossible in the +//! `serde_json::Value` representation. And the Rust compiler can check that +//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a +//! `Vec<String>` so indexing into it makes sense and produces a `String`. +//! +//! # Constructing JSON values +//! +//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +//! objects with very natural JSON syntax. +//! +//! ```edition2018 +//! use serde_json::json; +//! +//! fn main() { +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }); +//! +//! println!("first phone number: {}", john["phones"][0]); +//! +//! // Convert to a string of JSON and print it out +//! println!("{}", john.to_string()); +//! } +//! ``` +//! +//! The `Value::to_string()` function converts a `serde_json::Value` into a +//! `String` of JSON text. +//! +//! One neat thing about the `json!` macro is that variables and expressions can +//! be interpolated directly into the JSON value as you are building it. Serde +//! will check at compile time that the value you are interpolating is able to +//! be represented as JSON. +//! +//! ```edition2018 +//! # use serde_json::json; +//! # +//! # fn random_phone() -> u16 { 0 } +//! # +//! let full_name = "John Doe"; +//! let age_last_year = 42; +//! +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": full_name, +//! "age": age_last_year + 1, +//! "phones": [ +//! format!("+44 {}", random_phone()) +//! ] +//! }); +//! ``` +//! +//! This is amazingly convenient but we have the problem we had before with +//! `Value` which is that the IDE and Rust compiler cannot help us if we get it +//! wrong. Serde JSON provides a better way of serializing strongly-typed data +//! structures into JSON text. +//! +//! # Creating JSON by serializing data structures +//! +//! A data structure can be converted to a JSON string by +//! [`serde_json::to_string`][to_string]. There is also +//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and +//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` +//! such as a File or a TCP stream. +//! +//! ```edition2018 +//! use serde::{Deserialize, Serialize}; +//! use serde_json::Result; +//! +//! #[derive(Serialize, Deserialize)] +//! struct Address { +//! street: String, +//! city: String, +//! } +//! +//! fn print_an_address() -> Result<()> { +//! // Some data structure. +//! let address = Address { +//! street: "10 Downing Street".to_owned(), +//! city: "London".to_owned(), +//! }; +//! +//! // Serialize it to a JSON string. +//! let j = serde_json::to_string(&address)?; +//! +//! // Print, write to a file, or send to an HTTP server. +//! println!("{}", j); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # print_an_address().unwrap(); +//! # } +//! ``` +//! +//! Any type that implements Serde's `Serialize` trait can be serialized this +//! way. This includes built-in Rust standard library types like `Vec<T>` and +//! `HashMap<K, V>`, as well as any structs or enums annotated with +//! `#[derive(Serialize)]`. +//! +//! # No-std support +//! +//! 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.44")] +#![allow(unknown_lints, bare_trait_objects, ellipsis_inclusive_range_patterns)] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] +#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] +// Ignored clippy lints +#![cfg_attr( + feature = "cargo-clippy", + allow(deprecated_cfg_attr, doc_markdown, needless_doctest_main) +)] +// Ignored 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_wrap, + cast_precision_loss, + cast_sign_loss, + // correctly used + integer_division, + // things are often more readable this way + cast_lossless, + module_name_repetitions, + shadow_unrelated, + single_match_else, + too_many_lines, + use_self, + zero_prefixed_literal, + // we support older compilers + checked_conversions, + redundant_field_names, + // noisy + must_use_candidate, +))] +#![deny(missing_docs)] + +#[macro_use] +extern crate serde; +#[cfg(feature = "preserve_order")] +extern crate indexmap; +extern crate itoa; +extern crate ryu; + +#[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; + +#[cfg(feature = "raw_value")] +mod raw; 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 0000000000..16116a0179 --- /dev/null +++ b/third_party/rust/serde_json/src/macros.rs @@ -0,0 +1,292 @@ +/// Construct a `serde_json::Value` from a JSON literal. +/// +/// ```edition2018 +/// # use serde_json::json; +/// # +/// let value = json!({ +/// "code": 200, +/// "success": true, +/// "payload": { +/// "features": [ +/// "serde", +/// "json" +/// ] +/// } +/// }); +/// ``` +/// +/// Variables or expressions can be interpolated into the JSON literal. Any type +/// interpolated into an array element or object value must implement Serde's +/// `Serialize` trait, while any type interpolated into a object key must +/// implement `Into<String>`. If the `Serialize` implementation of the +/// interpolated type decides to fail, or if the interpolated type contains a +/// map with non-string keys, the `json!` macro will panic. +/// +/// ```edition2018 +/// # use serde_json::json; +/// # +/// let code = 200; +/// let features = vec!["serde", "json"]; +/// +/// let value = json!({ +/// "code": code, +/// "success": code == 200, +/// "payload": { +/// features[0]: features[1] +/// } +/// }); +/// ``` +/// +/// Trailing commas are allowed inside both arrays and objects. +/// +/// ```edition2018 +/// # use serde_json::json; +/// # +/// let value = json!([ +/// "notice", +/// "the", +/// "trailing", +/// "comma -->", +/// ]); +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! json { + // Hide distracting implementation details from the generated rustdoc. + ($($json:tt)+) => { + json_internal!($($json)+) + }; +} + +// Rocket relies on this because they export their own `json!` with a different +// doc comment than ours, and various Rust bugs prevent them from calling our +// `json!` from their `json!` so they call `json_internal!` directly. Check with +// @SergioBenitez before making breaking changes to this macro. +// +// Changes are fine as long as `json_internal!` does not call any new helper +// macros and can still be invoked as `json_internal!($($json)+)`. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! json_internal { + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an array [...]. Produces a vec![...] + // of the elements. + // + // Must be invoked as: json_internal!(@array [] $($tt)*) + ////////////////////////////////////////////////////////////////////////// + + // Done with trailing comma. + (@array [$($elems:expr,)*]) => { + json_internal_vec![$($elems,)*] + }; + + // Done without trailing comma. + (@array [$($elems:expr),*]) => { + json_internal_vec![$($elems),*] + }; + + // Next element is `null`. + (@array [$($elems:expr,)*] null $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*) + }; + + // Next element is `true`. + (@array [$($elems:expr,)*] true $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*) + }; + + // Next element is `false`. + (@array [$($elems:expr,)*] false $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*) + }; + + // Next element is an array. + (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*) + }; + + // Next element is a map. + (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*) + }; + + // Next element is an expression followed by comma. + (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*) + }; + + // Last element is an expression with no trailing comma. + (@array [$($elems:expr,)*] $last:expr) => { + json_internal!(@array [$($elems,)* json_internal!($last)]) + }; + + // Comma after the most recent element. + (@array [$($elems:expr),*] , $($rest:tt)*) => { + json_internal!(@array [$($elems,)*] $($rest)*) + }; + + // Unexpected token after most recent element. + (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { + json_unexpected!($unexpected) + }; + + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an object {...}. Each entry is + // inserted into the given map variable. + // + // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*)) + // + // We require two copies of the input tokens so that we can match on one + // copy and trigger errors on the other copy. + ////////////////////////////////////////////////////////////////////////// + + // Done. + (@object $object:ident () () ()) => {}; + + // Insert the current entry followed by trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { + let _ = $object.insert(($($key)+).into(), $value); + json_internal!(@object $object () ($($rest)*) ($($rest)*)); + }; + + // Current entry followed by unexpected token. + (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { + json_unexpected!($unexpected); + }; + + // Insert the last entry without trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr)) => { + let _ = $object.insert(($($key)+).into(), $value); + }; + + // Next value is `null`. + (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*); + }; + + // Next value is `true`. + (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*); + }; + + // Next value is `false`. + (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*); + }; + + // Next value is an array. + (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*); + }; + + // Next value is a map. + (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*); + }; + + // Next value is an expression followed by comma. + (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*); + }; + + // Last value is an expression with no trailing comma. + (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!($value))); + }; + + // Missing value for last entry. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { + // "unexpected end of macro invocation" + json_internal!(); + }; + + // Missing colon and value for last entry. Trigger a reasonable error + // message. + (@object $object:ident ($($key:tt)+) () $copy:tt) => { + // "unexpected end of macro invocation" + json_internal!(); + }; + + // Misplaced colon. Trigger a reasonable error message. + (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `:`". + json_unexpected!($colon); + }; + + // Found a comma inside a key. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `,`". + json_unexpected!($comma); + }; + + // Key is fully parenthesized. This avoids clippy double_parens false + // positives because the parenthesization may be necessary here. + (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); + }; + + // Munch a token into the current key. + (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); + }; + + ////////////////////////////////////////////////////////////////////////// + // The main implementation. + // + // Must be invoked as: json_internal!($($json)+) + ////////////////////////////////////////////////////////////////////////// + + (null) => { + $crate::Value::Null + }; + + (true) => { + $crate::Value::Bool(true) + }; + + (false) => { + $crate::Value::Bool(false) + }; + + ([]) => { + $crate::Value::Array(json_internal_vec![]) + }; + + ([ $($tt:tt)+ ]) => { + $crate::Value::Array(json_internal!(@array [] $($tt)+)) + }; + + ({}) => { + $crate::Value::Object($crate::Map::new()) + }; + + ({ $($tt:tt)+ }) => { + $crate::Value::Object({ + let mut object = $crate::Map::new(); + json_internal!(@object object () ($($tt)+) ($($tt)+)); + object + }) + }; + + // Any Serialize type: numbers, strings, struct literals, variables etc. + // Must be below every other rule. + ($other:expr) => { + $crate::to_value(&$other).unwrap() + }; +} + +// The json_internal macro above cannot invoke vec directly because it uses +// local_inner_macros. A vec invocation there would resolve to $crate::vec. +// Instead invoke vec here outside of local_inner_macros. +#[macro_export] +#[doc(hidden)] +macro_rules! json_internal_vec { + ($($content:tt)*) => { + vec![$($content)*] + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! json_unexpected { + () => {}; +} diff --git a/third_party/rust/serde_json/src/map.rs b/third_party/rust/serde_json/src/map.rs new file mode 100644 index 0000000000..3ef3811b1f --- /dev/null +++ b/third_party/rust/serde_json/src/map.rs @@ -0,0 +1,820 @@ +//! 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<K, V> { + map: MapImpl<K, V>, +} + +#[cfg(not(feature = "preserve_order"))] +type MapImpl<K, V> = BTreeMap<K, V>; +#[cfg(feature = "preserve_order")] +type MapImpl<K, V> = IndexMap<K, V>; + +impl Map<String, Value> { + /// Makes a new empty Map. + #[inline] + pub fn new() -> Self { + Map { + map: MapImpl::new(), + } + } + + #[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<Q: ?Sized>(&self, key: &Q) -> Option<&Value> + where + String: Borrow<Q>, + 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<Q: ?Sized>(&self, key: &Q) -> bool + where + String: Borrow<Q>, + 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<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Value> + where + String: Borrow<Q>, + 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<Value> { + self.map.insert(k, v) + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<Value> + where + String: Borrow<Q>, + Q: Ord + Eq + Hash, + { + #[cfg(feature = "preserve_order")] + return self.map.swap_remove(key); + #[cfg(not(feature = "preserve_order"))] + return self.map.remove(key); + } + + /// Gets the given key's corresponding entry in the map for in-place + /// manipulation. + pub fn entry<S>(&mut self, key: S) -> Entry + where + S: Into<String>, + { + #[cfg(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<String, Value> { + #[inline] + fn default() -> Self { + Map { + map: MapImpl::new(), + } + } +} + +impl Clone for Map<String, Value> { + #[inline] + fn clone(&self) -> Self { + Map { + map: self.map.clone(), + } + } +} + +impl PartialEq for Map<String, Value> { + #[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. +/// +/// ```edition2018 +/// # 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<String, Value> +where + String: Borrow<Q>, + 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. +/// +/// ```edition2018 +/// # use serde_json::json; +/// # +/// # let mut map = serde_json::Map::new(); +/// # map.insert("key".to_owned(), serde_json::Value::Null); +/// # +/// map["key"] = json!("value"); +/// ``` +impl<'a, Q: ?Sized> ops::IndexMut<&'a Q> for Map<String, Value> +where + String: Borrow<Q>, + 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<String, Value> { + #[inline] + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + self.map.fmt(formatter) + } +} + +impl ser::Serialize for Map<String, Value> { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + 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<String, Value> { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: de::Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = Map<String, Value>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: de::Error, + { + Ok(Map::new()) + } + + #[inline] + fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> + where + V: de::MapAccess<'de>, + { + let mut values = Map::new(); + + while let Some((key, value)) = try!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(values) + } + } + + deserializer.deserialize_map(Visitor) + } +} + +impl FromIterator<(String, Value)> for Map<String, Value> { + fn from_iter<T>(iter: T) -> Self + where + T: IntoIterator<Item = (String, Value)>, + { + Map { + map: FromIterator::from_iter(iter), + } + } +} + +impl Extend<(String, Value)> for Map<String, Value> { + fn extend<T>(&mut self, iter: T) + where + T: IntoIterator<Item = (String, Value)>, + { + self.map.extend(iter); + } +} + +macro_rules! delegate_iterator { + (($name:ident $($generics:tt)*) => $item:ty) => { + impl $($generics)* Iterator for $name $($generics)* { + type Item = $item; + #[inline] + fn next(&mut self) -> Option<Self::Item> { + self.iter.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } + } + + impl $($generics)* DoubleEndedIterator for $name $($generics)* { + #[inline] + fn next_back(&mut self) -> Option<Self::Item> { + self.iter.next_back() + } + } + + impl $($generics)* ExactSizeIterator for $name $($generics)* { + #[inline] + fn len(&self) -> usize { + self.iter.len() + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +/// 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 + /// + /// ```edition2018 + /// 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 + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut map = serde_json::Map::new(); + /// map.entry("serde").or_insert(json!(12)); + /// + /// assert_eq!(map["serde"], 12); + /// ``` + pub fn or_insert(self, default: Value) -> &'a mut Value { + match self { + Entry::Vacant(entry) => entry.insert(default), + Entry::Occupied(entry) => entry.into_mut(), + } + } + + /// Ensures a value is in the entry by inserting the result of the default + /// function if empty, and returns a mutable reference to the value in the + /// entry. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut map = serde_json::Map::new(); + /// map.entry("serde").or_insert_with(|| json!("hoho")); + /// + /// assert_eq!(map["serde"], "hoho".to_owned()); + /// ``` + pub fn or_insert_with<F>(self, default: F) -> &'a mut Value + where + F: FnOnce() -> Value, + { + match self { + Entry::Vacant(entry) => entry.insert(default()), + Entry::Occupied(entry) => entry.into_mut(), + } + } +} + +impl<'a> VacantEntry<'a> { + /// Gets a reference to the key that would be used when inserting a value + /// through the VacantEntry. + /// + /// # Examples + /// + /// ```edition2018 + /// 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 + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// + /// match map.entry("serde") { + /// Entry::Vacant(vacant) => { + /// vacant.insert(json!("hoho")); + /// } + /// Entry::Occupied(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn insert(self, value: Value) -> &'a mut Value { + self.vacant.insert(value) + } +} + +impl<'a> OccupiedEntry<'a> { + /// Gets a reference to the key in the entry. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// assert_eq!(occupied.key(), &"serde"); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn key(&self) -> &String { + self.occupied.key() + } + + /// Gets a reference to the value in the entry. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// assert_eq!(occupied.get(), 12); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn get(&self) -> &Value { + self.occupied.get() + } + + /// Gets a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!([1, 2, 3])); + /// + /// match map.entry("serde") { + /// Entry::Occupied(mut occupied) => { + /// occupied.get_mut().as_array_mut().unwrap().push(json!(4)); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// + /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); + /// ``` + #[inline] + pub fn get_mut(&mut self) -> &mut Value { + self.occupied.get_mut() + } + + /// Converts the entry into a mutable reference to its value. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!([1, 2, 3])); + /// + /// match map.entry("serde") { + /// Entry::Occupied(mut occupied) => { + /// occupied.into_mut().as_array_mut().unwrap().push(json!(4)); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// + /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); + /// ``` + #[inline] + pub fn into_mut(self) -> &'a mut Value { + self.occupied.into_mut() + } + + /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns + /// the entry's old value. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(mut occupied) => { + /// assert_eq!(occupied.insert(json!(13)), 12); + /// assert_eq!(occupied.get(), 13); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn insert(&mut self, value: Value) -> Value { + self.occupied.insert(value) + } + + /// Takes the value of the entry out of the map, and returns it. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// assert_eq!(occupied.remove(), 12); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn remove(self) -> Value { + #[cfg(feature = "preserve_order")] + return self.occupied.swap_remove(); + #[cfg(not(feature = "preserve_order"))] + return self.occupied.remove(); + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> IntoIterator for &'a Map<String, Value> { + type Item = (&'a String, &'a Value); + type IntoIter = Iter<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + Iter { + iter: self.map.iter(), + } + } +} + +/// An iterator over a serde_json::Map's entries. +pub struct Iter<'a> { + iter: IterImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type IterImpl<'a> = btree_map::Iter<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>; + +delegate_iterator!((Iter<'a>) => (&'a String, &'a Value)); + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> IntoIterator for &'a mut Map<String, Value> { + type Item = (&'a String, &'a mut Value); + type IntoIter = IterMut<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IterMut { + iter: self.map.iter_mut(), + } + } +} + +/// A mutable iterator over a serde_json::Map's entries. +pub struct IterMut<'a> { + iter: IterMutImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>; + +delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value)); + +////////////////////////////////////////////////////////////////////////////// + +impl IntoIterator for Map<String, Value> { + type Item = (String, Value); + type IntoIter = IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IntoIter { + iter: self.map.into_iter(), + } + } +} + +/// An owning iterator over a serde_json::Map's entries. +pub struct IntoIter { + iter: IntoIterImpl, +} + +#[cfg(not(feature = "preserve_order"))] +type IntoIterImpl = btree_map::IntoIter<String, Value>; +#[cfg(feature = "preserve_order")] +type IntoIterImpl = indexmap::map::IntoIter<String, Value>; + +delegate_iterator!((IntoIter) => (String, Value)); + +////////////////////////////////////////////////////////////////////////////// + +/// An iterator over a serde_json::Map's keys. +pub struct Keys<'a> { + iter: KeysImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type KeysImpl<'a> = btree_map::Keys<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>; + +delegate_iterator!((Keys<'a>) => &'a String); + +////////////////////////////////////////////////////////////////////////////// + +/// An iterator over a serde_json::Map's values. +pub struct Values<'a> { + iter: ValuesImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type ValuesImpl<'a> = btree_map::Values<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>; + +delegate_iterator!((Values<'a>) => &'a Value); + +////////////////////////////////////////////////////////////////////////////// + +/// A mutable iterator over a serde_json::Map's values. +pub struct ValuesMut<'a> { + iter: ValuesMutImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>; + +delegate_iterator!((ValuesMut<'a>) => &'a mut Value); 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 0000000000..fd2707aa26 --- /dev/null +++ b/third_party/rust/serde_json/src/number.rs @@ -0,0 +1,752 @@ +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 itoa; +#[cfg(feature = "arbitrary_precision")] +use ryu; +#[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 TOKEN: &'static str = "$serde_json::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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert!(v["a"].is_i64()); + /// + /// // Greater than i64::MAX. + /// assert!(!v["b"].is_i64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_i64()); + /// ``` + #[inline] + pub fn is_i64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(v) => v <= i64::max_value() as u64, + N::NegInt(_) => true, + N::Float(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + self.as_i64().is_some() + } + + /// Returns true if the `Number` is an integer between zero and `u64::MAX`. + /// + /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert!(v["a"].is_u64()); + /// + /// // Negative integer. + /// assert!(!v["b"].is_u64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_u64()); + /// ``` + #[inline] + pub fn is_u64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(_) => true, + N::NegInt(_) | N::Float(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + self.as_u64().is_some() + } + + /// Returns true if the `Number` can be represented by f64. + /// + /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to + /// return the floating point value. + /// + /// Currently this function returns true if and only if both `is_i64` and + /// `is_u64` return false but this is not a guarantee in the future. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// ``` + #[inline] + pub fn is_f64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::Float(_) => true, + N::PosInt(_) | N::NegInt(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + { + for c in self.n.chars() { + if c == '.' || c == 'e' || c == 'E' { + return self.n.parse::<f64>().ok().map_or(false, |f| f.is_finite()); + } + } + false + } + } + + /// If the `Number` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// ``` + #[inline] + pub fn as_i64(&self) -> Option<i64> { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => { + if n <= i64::max_value() as u64 { + Some(n as i64) + } else { + None + } + } + N::NegInt(n) => Some(n), + N::Float(_) => None, + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// If the `Number` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// ``` + #[inline] + pub fn as_u64(&self) -> Option<u64> { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n), + N::NegInt(_) | N::Float(_) => None, + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// Represents the number as f64 if possible. Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// ``` + #[inline] + pub fn as_f64(&self) -> Option<f64> { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n as f64), + N::NegInt(n) => Some(n as f64), + N::Float(n) => Some(n), + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON + /// numbers. + /// + /// ```edition2018 + /// # use std::f64; + /// # + /// # use serde_json::Number; + /// # + /// assert!(Number::from_f64(256.0).is_some()); + /// + /// assert!(Number::from_f64(f64::NAN).is_none()); + /// ``` + #[inline] + pub fn from_f64(f: f64) -> Option<Number> { + if f.is_finite() { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f) + } + #[cfg(feature = "arbitrary_precision")] + { + ryu::Buffer::new().format_finite(f).to_owned() + } + }; + Some(Number { n: 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self.n { + N::PosInt(u) => serializer.serialize_u64(u), + N::NegInt(i) => serializer.serialize_i64(i), + N::Float(f) => serializer.serialize_f64(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + use serde::ser::SerializeStruct; + + let mut s = serializer.serialize_struct(TOKEN, 1)?; + s.serialize_field(TOKEN, &self.n)?; + s.end() + } +} + +impl<'de> Deserialize<'de> for Number { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Number, D::Error> + where + D: Deserializer<'de>, + { + struct NumberVisitor; + + impl<'de> Visitor<'de> for NumberVisitor { + type Value = Number; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a JSON number") + } + + #[inline] + fn visit_i64<E>(self, value: i64) -> Result<Number, E> { + Ok(value.into()) + } + + #[inline] + fn visit_u64<E>(self, value: u64) -> Result<Number, E> { + Ok(value.into()) + } + + #[inline] + fn visit_f64<E>(self, value: f64) -> Result<Number, E> + where + E: de::Error, + { + Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number")) + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn visit_map<V>(self, mut visitor: V) -> Result<Number, V::Error> + where + V: de::MapAccess<'de>, + { + let value = visitor.next_key::<NumberKey>()?; + 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<D>(deserializer: D) -> Result<NumberKey, D::Error> + where + D: de::Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> de::Visitor<'de> for FieldVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a valid number field") + } + + fn visit_str<E>(self, s: &str) -> Result<(), E> + where + E: de::Error, + { + if s == TOKEN { + Ok(()) + } else { + Err(de::Error::custom("expected field with custom name")) + } + } + } + + deserializer.deserialize_identifier(FieldVisitor)?; + Ok(NumberKey) + } +} + +#[cfg(feature = "arbitrary_precision")] +pub struct NumberFromString { + pub value: Number, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'de> de::Deserialize<'de> for NumberFromString { + fn deserialize<D>(deserializer: D) -> Result<NumberFromString, D::Error> + where + D: de::Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = NumberFromString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string containing a number") + } + + fn visit_str<E>(self, s: &str) -> Result<NumberFromString, E> + where + E: de::Error, + { + let n = 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<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self.n { + N::PosInt(u) => visitor.visit_u64(u), + N::NegInt(i) => visitor.visit_i64(i), + N::Float(f) => visitor.visit_f64(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where V: Visitor<'de> + { + if let Some(u) = self.as_u64() { + return visitor.visit_u64(u); + } else if let Some(i) = self.as_i64() { + return visitor.visit_i64(i); + } else if let Some(f) = self.as_f64() { + if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n { + return visitor.visit_f64(f); + } + } + + visitor.visit_map(NumberDeserializer { + number: Some(self.$($num_string)*), + }) + } + }; + + (owned) => { + deserialize_any!(@expand [n]); + }; + + (ref) => { + deserialize_any!(@expand [n.clone()]); + }; +} + +macro_rules! deserialize_number { + ($deserialize:ident => $visit:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_any(visitor) + } + + #[cfg(feature = "arbitrary_precision")] + fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: de::Visitor<'de>, + { + visitor.$visit(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<String>, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'de> MapAccess<'de> for NumberDeserializer { + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.number.is_none() { + return Ok(None); + } + seed.deserialize(NumberFieldDeserializer).map(Some) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(self.number.take().unwrap().into_deserializer()) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberFieldDeserializer; + +#[cfg(feature = "arbitrary_precision")] +impl<'de> Deserializer<'de> for NumberFieldDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(TOKEN) + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq + bytes byte_buf map struct option unit newtype_struct ignored_any + unit_struct tuple_struct tuple enum identifier + } +} + +impl From<ParserNumber> for Number { + fn from(value: ParserNumber) -> Self { + let n = match value { + ParserNumber::F64(f) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f) + } + #[cfg(feature = "arbitrary_precision")] + { + f.to_string() + } + } + ParserNumber::U64(u) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::PosInt(u) + } + #[cfg(feature = "arbitrary_precision")] + { + u.to_string() + } + } + ParserNumber::I64(i) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::NegInt(i) + } + #[cfg(feature = "arbitrary_precision")] + { + i.to_string() + } + } + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(s) => s, + }; + Number { n: n } + } +} + +macro_rules! impl_from_unsigned { + ( + $($ty:ty),* + ) => { + $( + impl From<$ty> for Number { + #[inline] + fn from(u: $ty) -> Self { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { N::PosInt(u as u64) } + #[cfg(feature = "arbitrary_precision")] + { + itoa::Buffer::new().format(u).to_owned() + } + }; + Number { n: n } + } + } + )* + }; +} + +macro_rules! impl_from_signed { + ( + $($ty:ty),* + ) => { + $( + impl From<$ty> for Number { + #[inline] + fn from(i: $ty) -> Self { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + if i < 0 { + N::NegInt(i as i64) + } else { + N::PosInt(i as u64) + } + } + #[cfg(feature = "arbitrary_precision")] + { + itoa::Buffer::new().format(i).to_owned() + } + }; + Number { n: n } + } + } + )* + }; +} + +impl_from_unsigned!(u8, u16, u32, u64, usize); +impl_from_signed!(i8, i16, i32, i64, isize); + +#[cfg(feature = "arbitrary_precision")] +serde_if_integer128! { + impl From<i128> for Number { + fn from(i: i128) -> Self { + Number { n: i.to_string() } + } + } + + impl From<u128> for Number { + fn from(u: u128) -> Self { + Number { n: u.to_string() } + } + } +} + +impl 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/raw.rs b/third_party/rust/serde_json/src/raw.rs new file mode 100644 index 0000000000..5c4f8cfbef --- /dev/null +++ b/third_party/rust/serde_json/src/raw.rs @@ -0,0 +1,456 @@ +use std::fmt::{self, Debug, Display}; +use std::mem; + +use serde::de::value::BorrowedStrDeserializer; +use serde::de::{ + self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected, + Visitor, +}; +use serde::ser::{Serialize, SerializeStruct, Serializer}; + +use error::Error; + +/// Reference to a range of bytes encompassing a single valid JSON value in the +/// input data. +/// +/// A `RawValue` can be used to defer parsing parts of a payload until later, +/// or to avoid parsing it at all in the case that part of the payload just +/// needs to be transferred verbatim into a different output object. +/// +/// When serializing, a value of this type will retain its original formatting +/// and will not be minified or pretty-printed. +/// +/// # Note +/// +/// `RawValue` is only available if serde\_json is built with the `"raw_value"` +/// feature. +/// +/// ```toml +/// [dependencies] +/// serde_json = { version = "1.0", features = ["raw_value"] } +/// ``` +/// +/// # Example +/// +/// ```edition2018 +/// use serde::{Deserialize, Serialize}; +/// use serde_json::{Result, value::RawValue}; +/// +/// #[derive(Deserialize)] +/// struct Input<'a> { +/// code: u32, +/// #[serde(borrow)] +/// payload: &'a RawValue, +/// } +/// +/// #[derive(Serialize)] +/// struct Output<'a> { +/// info: (u32, &'a RawValue), +/// } +/// +/// // Efficiently rearrange JSON input containing separate "code" and "payload" +/// // keys into a single "info" key holding an array of code and payload. +/// // +/// // This could be done equivalently using serde_json::Value as the type for +/// // payload, but &RawValue will perform better because it does not require +/// // memory allocation. The correct range of bytes is borrowed from the input +/// // data and pasted verbatim into the output. +/// fn rearrange(input: &str) -> Result<String> { +/// let input: Input = serde_json::from_str(input)?; +/// +/// let output = Output { +/// info: (input.code, input.payload), +/// }; +/// +/// serde_json::to_string(&output) +/// } +/// +/// fn main() -> Result<()> { +/// let out = rearrange(r#" {"code": 200, "payload": {}} "#)?; +/// +/// assert_eq!(out, r#"{"info":[200,{}]}"#); +/// +/// Ok(()) +/// } +/// ``` +/// +/// # Ownership +/// +/// The typical usage of `RawValue` will be in the borrowed form: +/// +/// ```edition2018 +/// # use serde::Deserialize; +/// # use serde_json::value::RawValue; +/// # +/// #[derive(Deserialize)] +/// struct SomeStruct<'a> { +/// #[serde(borrow)] +/// raw_value: &'a RawValue, +/// } +/// ``` +/// +/// The borrowed form is suitable when deserializing through +/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support +/// borrowing from the input data without memory allocation. +/// +/// When deserializing through [`serde_json::from_reader`] you will need to use +/// the boxed form of `RawValue` instead. This is almost as efficient but +/// involves buffering the raw value from the I/O stream into memory. +/// +/// [`serde_json::from_str`]: ../fn.from_str.html +/// [`serde_json::from_slice`]: ../fn.from_slice.html +/// [`serde_json::from_reader`]: ../fn.from_reader.html +/// +/// ```edition2018 +/// # use serde::Deserialize; +/// # use serde_json::value::RawValue; +/// # +/// #[derive(Deserialize)] +/// struct SomeStruct { +/// raw_value: Box<RawValue>, +/// } +/// ``` +#[repr(C)] +pub struct RawValue { + json: str, +} + +impl RawValue { + fn from_borrowed(json: &str) -> &Self { + unsafe { mem::transmute::<&str, &RawValue>(json) } + } + + fn from_owned(json: Box<str>) -> Box<Self> { + unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) } + } +} + +impl Clone for Box<RawValue> { + fn clone(&self) -> Self { + (**self).to_owned() + } +} + +impl ToOwned for RawValue { + type Owned = Box<RawValue>; + + fn to_owned(&self) -> Self::Owned { + RawValue::from_owned(self.json.to_owned().into_boxed_str()) + } +} + +impl Default for Box<RawValue> { + fn default() -> Self { + RawValue::from_borrowed("null").to_owned() + } +} + +impl Debug for RawValue { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_tuple("RawValue") + .field(&format_args!("{}", &self.json)) + .finish() + } +} + +impl Display for RawValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.json) + } +} + +impl RawValue { + /// Convert an owned `String` of JSON data to an owned `RawValue`. + /// + /// This function is equivalent to `serde_json::from_str::<Box<RawValue>>` + /// except that we avoid an allocation and memcpy if both of the following + /// are true: + /// + /// - the input has no leading or trailing whitespace, and + /// - the input has capacity equal to its length. + pub fn from_string(json: String) -> Result<Box<Self>, Error> { + { + let borrowed = ::from_str::<&Self>(&json)?; + if borrowed.json.len() < json.len() { + return Ok(borrowed.to_owned()); + } + } + Ok(Self::from_owned(json.into_boxed_str())) + } + + /// Access the JSON text underlying a raw value. + /// + /// # Example + /// + /// ```edition2018 + /// use serde::Deserialize; + /// use serde_json::{Result, value::RawValue}; + /// + /// #[derive(Deserialize)] + /// struct Response<'a> { + /// code: u32, + /// #[serde(borrow)] + /// payload: &'a RawValue, + /// } + /// + /// fn process(input: &str) -> Result<()> { + /// let response: Response = serde_json::from_str(input)?; + /// + /// let payload = response.payload.get(); + /// if payload.starts_with('{') { + /// // handle a payload which is a JSON map + /// } else { + /// // handle any other type + /// } + /// + /// Ok(()) + /// } + /// + /// fn main() -> Result<()> { + /// process(r#" {"code": 200, "payload": {}} "#)?; + /// Ok(()) + /// } + /// ``` + pub fn get(&self) -> &str { + &self.json + } +} + +pub const TOKEN: &'static str = "$serde_json::private::RawValue"; + +impl Serialize for RawValue { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut s = serializer.serialize_struct(TOKEN, 1)?; + s.serialize_field(TOKEN, &self.json)?; + s.end() + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct ReferenceVisitor; + + impl<'de> Visitor<'de> for ReferenceVisitor { + type Value = &'de RawValue; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "any valid JSON value") + } + + fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> + where + V: MapAccess<'de>, + { + let value = visitor.next_key::<RawKey>()?; + if value.is_none() { + return Err(de::Error::invalid_type(Unexpected::Map, &self)); + } + visitor.next_value_seed(ReferenceFromString) + } + } + + deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor) + } +} + +impl<'de> Deserialize<'de> for Box<RawValue> { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct BoxedVisitor; + + impl<'de> Visitor<'de> for BoxedVisitor { + type Value = Box<RawValue>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "any valid JSON value") + } + + fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> + where + V: MapAccess<'de>, + { + let value = visitor.next_key::<RawKey>()?; + if value.is_none() { + return Err(de::Error::invalid_type(Unexpected::Map, &self)); + } + visitor.next_value_seed(BoxedFromString) + } + } + + deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor) + } +} + +struct RawKey; + +impl<'de> Deserialize<'de> for RawKey { + fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error> + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("raw value") + } + + fn visit_str<E>(self, s: &str) -> Result<(), E> + where + E: de::Error, + { + if s == TOKEN { + Ok(()) + } else { + Err(de::Error::custom("unexpected raw value")) + } + } + } + + deserializer.deserialize_identifier(FieldVisitor)?; + Ok(RawKey) + } +} + +pub struct ReferenceFromString; + +impl<'de> DeserializeSeed<'de> for ReferenceFromString { + type Value = &'de RawValue; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for ReferenceFromString { + type Value = &'de RawValue; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("raw value") + } + + fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E> + where + E: de::Error, + { + Ok(RawValue::from_borrowed(s)) + } +} + +pub struct BoxedFromString; + +impl<'de> DeserializeSeed<'de> for BoxedFromString { + type Value = Box<RawValue>; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for BoxedFromString { + type Value = Box<RawValue>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("raw value") + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + self.visit_string(s.to_owned()) + } + + fn visit_string<E>(self, s: String) -> Result<Self::Value, E> + where + E: de::Error, + { + Ok(RawValue::from_owned(s.into_boxed_str())) + } +} + +struct RawKeyDeserializer; + +impl<'de> Deserializer<'de> for RawKeyDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(TOKEN) + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq + bytes byte_buf map struct option unit newtype_struct ignored_any + unit_struct tuple_struct tuple enum identifier + } +} + +pub struct OwnedRawDeserializer { + pub raw_value: Option<String>, +} + +impl<'de> MapAccess<'de> for OwnedRawDeserializer { + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.raw_value.is_none() { + return Ok(None); + } + seed.deserialize(RawKeyDeserializer).map(Some) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(self.raw_value.take().unwrap().into_deserializer()) + } +} + +pub struct BorrowedRawDeserializer<'de> { + pub raw_value: Option<&'de str>, +} + +impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> { + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.raw_value.is_none() { + return Ok(None); + } + seed.deserialize(RawKeyDeserializer).map(Some) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap())) + } +} 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 0000000000..71b0504138 --- /dev/null +++ b/third_party/rust/serde_json/src/read.rs @@ -0,0 +1,859 @@ +use std::ops::Deref; +use std::{char, cmp, io, str}; + +#[cfg(feature = "raw_value")] +use serde::de::Visitor; + +use iter::LineColIterator; + +use error::{Error, ErrorCode, Result}; + +#[cfg(feature = "raw_value")] +use raw::{BorrowedRawDeserializer, OwnedRawDeserializer}; + +/// Trait used by the deserializer for iterating over input. This is manually +/// "specialized" for iterating over &[u8]. Once feature(specialization) is +/// stable we can use actual specialization. +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_json`. +pub trait Read<'de>: private::Sealed { + #[doc(hidden)] + fn next(&mut self) -> Result<Option<u8>>; + #[doc(hidden)] + fn peek(&mut self) -> Result<Option<u8>>; + + /// 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<u8>) -> Result<Reference<'de, 's, str>>; + + /// 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<u8>, + ) -> Result<Reference<'de, 's, [u8]>>; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark but discards the data. + #[doc(hidden)] + fn ignore_str(&mut self) -> Result<()>; + + /// Assumes the previous byte was a hex escape sequnce ('\u') in a string. + /// Parses next hexadecimal sequence. + #[doc(hidden)] + fn decode_hex_escape(&mut self) -> Result<u16>; + + /// Switch raw buffering mode on. + /// + /// This is used when deserializing `RawValue`. + #[cfg(feature = "raw_value")] + #[doc(hidden)] + fn begin_raw_buffering(&mut self); + + /// Switch raw buffering mode off and provides the raw buffered data to the + /// given visitor. + #[cfg(feature = "raw_value")] + #[doc(hidden)] + fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>; +} + +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<R> +where + R: io::Read, +{ + iter: LineColIterator<io::Bytes<R>>, + /// Temporary storage of peeked byte. + ch: Option<u8>, + #[cfg(feature = "raw_value")] + raw_buffer: Option<Vec<u8>>, +} + +/// JSON input source that reads from a slice of bytes. +// +// This is more efficient than other iterators because peek() can be read-only +// and we can compute line/col position only if an error happens. +pub struct SliceRead<'a> { + slice: &'a [u8], + /// Index of the *next* byte that will be returned by next() or peek(). + index: usize, + #[cfg(feature = "raw_value")] + raw_buffering_start_index: usize, +} + +/// JSON input source that reads from a UTF-8 string. +// +// Able to elide UTF-8 checks by assuming that the input is valid UTF-8. +pub struct StrRead<'a> { + delegate: SliceRead<'a>, + #[cfg(feature = "raw_value")] + data: &'a str, +} + +// Prevent users from implementing the Read trait. +mod private { + pub trait Sealed {} +} + +////////////////////////////////////////////////////////////////////////////// + +impl<R> IoRead<R> +where + R: io::Read, +{ + /// Create a JSON input source to read from a std::io input stream. + pub fn new(reader: R) -> Self { + #[cfg(not(feature = "raw_value"))] + { + IoRead { + iter: LineColIterator::new(reader.bytes()), + ch: None, + } + } + #[cfg(feature = "raw_value")] + { + IoRead { + iter: LineColIterator::new(reader.bytes()), + ch: None, + raw_buffer: None, + } + } + } +} + +impl<R> private::Sealed for IoRead<R> where R: io::Read {} + +impl<R> IoRead<R> +where + R: io::Read, +{ + fn parse_str_bytes<'s, T, F>( + &'s mut self, + scratch: &'s mut Vec<u8>, + validate: bool, + result: F, + ) -> Result<T> + where + T: 's, + F: FnOnce(&'s Self, &'s [u8]) -> Result<T>, + { + 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<R> +where + R: io::Read, +{ + #[inline] + fn next(&mut self) -> Result<Option<u8>> { + match self.ch.take() { + Some(ch) => { + #[cfg(feature = "raw_value")] + { + if let Some(ref mut buf) = self.raw_buffer { + buf.push(ch); + } + } + Ok(Some(ch)) + } + None => match self.iter.next() { + Some(Err(err)) => Err(Error::io(err)), + Some(Ok(ch)) => { + #[cfg(feature = "raw_value")] + { + if let Some(ref mut buf) = self.raw_buffer { + buf.push(ch); + } + } + Ok(Some(ch)) + } + None => Ok(None), + }, + } + } + + #[inline] + fn peek(&mut self) -> Result<Option<u8>> { + match self.ch { + Some(ch) => Ok(Some(ch)), + None => match self.iter.next() { + Some(Err(err)) => Err(Error::io(err)), + Some(Ok(ch)) => { + self.ch = Some(ch); + Ok(self.ch) + } + None => Ok(None), + }, + } + } + + #[cfg(not(feature = "raw_value"))] + #[inline] + fn discard(&mut self) { + self.ch = None; + } + + #[cfg(feature = "raw_value")] + fn discard(&mut self) { + if let Some(ch) = self.ch.take() { + if let Some(ref mut buf) = self.raw_buffer { + buf.push(ch); + } + } + } + + fn position(&self) -> Position { + Position { + line: self.iter.line(), + column: self.iter.col(), + } + } + + fn peek_position(&self) -> Position { + // The LineColIterator updates its position during peek() so it has the + // right one here. + self.position() + } + + fn byte_offset(&self) -> usize { + match self.ch { + Some(_) => self.iter.byte_offset() - 1, + None => self.iter.byte_offset(), + } + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> { + self.parse_str_bytes(scratch, true, as_str) + .map(Reference::Copied) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec<u8>, + ) -> Result<Reference<'de, 's, [u8]>> { + 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); + } + } + } + } + + fn decode_hex_escape(&mut self) -> Result<u16> { + let mut n = 0; + for _ in 0..4 { + match decode_hex_val(try!(next_or_eof(self))) { + None => return error(self, ErrorCode::InvalidEscape), + Some(val) => { + n = (n << 4) + val; + } + } + } + Ok(n) + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + self.raw_buffer = Some(Vec::new()); + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let raw = self.raw_buffer.take().unwrap(); + let raw = String::from_utf8(raw).unwrap(); + visitor.visit_map(OwnedRawDeserializer { + raw_value: Some(raw), + }) + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> SliceRead<'a> { + /// Create a JSON input source to read from a slice of bytes. + pub fn new(slice: &'a [u8]) -> Self { + #[cfg(not(feature = "raw_value"))] + { + SliceRead { + slice: slice, + index: 0, + } + } + #[cfg(feature = "raw_value")] + { + SliceRead { + slice: slice, + index: 0, + raw_buffering_start_index: 0, + } + } + } + + fn position_of_index(&self, i: usize) -> Position { + let mut position = Position { line: 1, column: 0 }; + for ch in &self.slice[..i] { + match *ch { + b'\n' => { + position.line += 1; + position.column = 0; + } + _ => { + position.column += 1; + } + } + } + position + } + + /// The big optimization here over IoRead is that if the string contains no + /// backslash escape sequences, the returned &str is a slice of the raw JSON + /// data so we avoid copying into the scratch space. + fn parse_str_bytes<'s, T: ?Sized, F>( + &'s mut self, + scratch: &'s mut Vec<u8>, + validate: bool, + result: F, + ) -> Result<Reference<'a, 's, T>> + 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; + } + _ => { + self.index += 1; + if validate { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + } + } + } + } +} + +impl<'a> private::Sealed for SliceRead<'a> {} + +impl<'a> Read<'a> for SliceRead<'a> { + #[inline] + fn next(&mut self) -> Result<Option<u8>> { + // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))` + // is about 10% slower. + Ok(if self.index < self.slice.len() { + let ch = self.slice[self.index]; + self.index += 1; + Some(ch) + } else { + None + }) + } + + #[inline] + fn peek(&mut self) -> Result<Option<u8>> { + // `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<u8>) -> Result<Reference<'a, 's, str>> { + self.parse_str_bytes(scratch, true, as_str) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec<u8>, + ) -> Result<Reference<'a, 's, [u8]>> { + 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); + } + } + } + } + + fn decode_hex_escape(&mut self) -> Result<u16> { + if self.index + 4 > self.slice.len() { + self.index = self.slice.len(); + return error(self, ErrorCode::EofWhileParsingString); + } + + let mut n = 0; + for _ in 0..4 { + let ch = decode_hex_val(self.slice[self.index]); + self.index += 1; + match ch { + None => return error(self, ErrorCode::InvalidEscape), + Some(val) => { + n = (n << 4) + val; + } + } + } + Ok(n) + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + self.raw_buffering_start_index = self.index; + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'a>, + { + let raw = &self.slice[self.raw_buffering_start_index..self.index]; + let raw = str::from_utf8(raw).unwrap(); + visitor.visit_map(BorrowedRawDeserializer { + raw_value: Some(raw), + }) + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> StrRead<'a> { + /// Create a JSON input source to read from a UTF-8 string. + pub fn new(s: &'a str) -> Self { + #[cfg(not(feature = "raw_value"))] + { + StrRead { + delegate: SliceRead::new(s.as_bytes()), + } + } + #[cfg(feature = "raw_value")] + { + StrRead { + delegate: SliceRead::new(s.as_bytes()), + data: s, + } + } + } +} + +impl<'a> private::Sealed for StrRead<'a> {} + +impl<'a> Read<'a> for StrRead<'a> { + #[inline] + fn next(&mut self) -> Result<Option<u8>> { + self.delegate.next() + } + + #[inline] + fn peek(&mut self) -> Result<Option<u8>> { + 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<u8>) -> Result<Reference<'a, 's, str>> { + 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<u8>, + ) -> Result<Reference<'a, 's, [u8]>> { + self.delegate.parse_str_raw(scratch) + } + + fn ignore_str(&mut self) -> Result<()> { + self.delegate.ignore_str() + } + + fn decode_hex_escape(&mut self) -> Result<u16> { + self.delegate.decode_hex_escape() + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + self.delegate.begin_raw_buffering() + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'a>, + { + let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index]; + visitor.visit_map(BorrowedRawDeserializer { + raw_value: Some(raw), + }) + } +} + +////////////////////////////////////////////////////////////////////////////// + +// Lookup table of bytes that must be escaped. A value of true at index i means +// that byte i requires an escape sequence in the input. +static ESCAPE: [bool; 256] = { + const CT: bool = true; // control character \x00...\x1F + const QU: bool = true; // quote \x22 + const BS: bool = true; // backslash \x5C + const __: bool = false; // allow unescaped + [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 + CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 + __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F + ] +}; + +fn next_or_eof<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result<u8> { + match try!(read.next()) { + Some(b) => Ok(b), + None => error(read, ErrorCode::EofWhileParsingString), + } +} + +fn error<'de, R: ?Sized + Read<'de>, T>(read: &R, reason: ErrorCode) -> Result<T> { + 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<u8>) -> 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!(read.decode_hex_escape()) { + 0xDC00...0xDFFF => { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + // Non-BMP characters are encoded as a sequence of + // two hex escapes, representing UTF-16 surrogates. + n1 @ 0xD800...0xDBFF => { + if 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!(read.decode_hex_escape()); + + if n2 < 0xDC00 || n2 > 0xDFFF { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000; + + match char::from_u32(n) { + Some(c) => c, + None => { + return error(read, ErrorCode::InvalidUnicodeCodePoint); + } + } + } + + n => match char::from_u32(n as u32) { + Some(c) => c, + None => { + return error(read, ErrorCode::InvalidUnicodeCodePoint); + } + }, + }; + + scratch.extend_from_slice(c.encode_utf8(&mut [0_u8; 4]).as_bytes()); + } + _ => { + return error(read, ErrorCode::InvalidEscape); + } + } + + Ok(()) +} + +/// Parses a JSON escape sequence and discards the value. Assumes the previous +/// byte read was a backslash. +fn ignore_escape<'de, R: ?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!(read.decode_hex_escape()) { + 0xDC00...0xDFFF => { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + // Non-BMP characters are encoded as a sequence of + // two hex escapes, representing UTF-16 surrogates. + n1 @ 0xD800...0xDBFF => { + if 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!(read.decode_hex_escape()); + + if n2 < 0xDC00 || n2 > 0xDFFF { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000 + } + + n => n as u32, + }; + + if char::from_u32(n).is_none() { + return error(read, ErrorCode::InvalidUnicodeCodePoint); + } + } + _ => { + return error(read, ErrorCode::InvalidEscape); + } + } + + Ok(()) +} + +static HEX: [u8; 256] = { + const __: u8 = 255; // not a hex digit + [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 1 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, __, __, __, __, __, __, // 3 + __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 5 + __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F + ] +}; + +fn decode_hex_val(val: u8) -> Option<u16> { + let n = HEX[val as usize] as u16; + if n == 255 { + None + } else { + Some(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 0000000000..cfae3815fa --- /dev/null +++ b/third_party/rust/serde_json/src/ser.rs @@ -0,0 +1,2262 @@ +//! 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, Serialize}; + +use itoa; +use ryu; + +/// A structure for serializing Rust values into JSON. +pub struct Serializer<W, F = CompactFormatter> { + writer: W, + formatter: F, +} + +impl<W> Serializer<W> +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<W, PrettyFormatter<'a>> +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<W, F> Serializer<W, F> +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<W, F> +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<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()> + where + T: Serialize, + { + value.serialize(self) + } + + #[inline] + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<()> + where + T: 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<T: ?Sized>(self, value: &T) -> Result<()> + where + T: Serialize, + { + value.serialize(self) + } + + #[inline] + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> { + 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::SerializeTuple> { + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct> { + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant> { + 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<usize>) -> Result<Self::SerializeMap> { + 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, + }) + } + } + + #[inline] + fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> { + match name { + #[cfg(feature = "arbitrary_precision")] + ::number::TOKEN => Ok(Compound::Number { ser: self }), + #[cfg(feature = "raw_value")] + ::raw::TOKEN => Ok(Compound::RawValue { ser: self }), + _ => self.serialize_map(Some(len)), + } + } + + #[inline] + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeStructVariant> { + 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<T: ?Sized>(self, value: &T) -> Result<Self::Ok> + 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<io::Error>, + } + + 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<W, F>, + state: State, + }, + #[cfg(feature = "arbitrary_precision")] + Number { ser: &'a mut Serializer<W, F> }, + #[cfg(feature = "raw_value")] + RawValue { ser: &'a mut Serializer<W, F> }, +} + +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<T: ?Sized>(&mut self, value: &T) -> Result<()> + where + T: 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> + where + T: 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<T: ?Sized>(&mut self, value: &T) -> Result<()> + where + T: 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<T: ?Sized>(&mut self, value: &T) -> Result<()> + where + T: 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> + where + T: 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } + + #[inline] + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> + where + T: 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: 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 == ::number::TOKEN { + try!(value.serialize(NumberStrEmitter(&mut *ser))); + Ok(()) + } else { + Err(invalid_number()) + } + } + #[cfg(feature = "raw_value")] + Compound::RawValue { ref mut ser, .. } => { + if key == ::raw::TOKEN { + try!(value.serialize(RawValueStrEmitter(&mut *ser))); + Ok(()) + } else { + Err(invalid_raw_value()) + } + } + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { .. } => ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => Ok(()), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => Ok(()), + } + } +} + +impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: Serialize, + { + match *self { + Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => 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!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer<'a, W: 'a, F: 'a> { + ser: &'a mut Serializer<W, F>, +} + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +#[cfg(feature = "raw_value")] +fn invalid_raw_value() -> Error { + Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) +} + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_str(self, value: &str) -> Result<()> { + self.ser.serialize_str(value) + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<()> { + self.ser.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()> + where + T: 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<()> { + try!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + try!(self + .ser + .formatter + .write_number_str(&mut self.ser.writer, &value.to_string()) + .map_err(Error::io)); + try!(self + .ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io)); + Ok(()) + } + } + + 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<()> { + try!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + try!(self + .ser + .formatter + .write_number_str(&mut self.ser.writer, &value.to_string()) + .map_err(Error::io)); + try!(self + .ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io)); + Ok(()) + } + } + + fn serialize_f32(self, _value: f32) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_f64(self, _value: f64) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_char(self, value: char) -> Result<()> { + self.ser.serialize_str(&value.to_string()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant<T: ?Sized>( + 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<T: ?Sized>(self, _value: &T) -> Result<()> + where + T: Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct> { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant> { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { + Err(key_must_be_a_string()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant> { + Err(key_must_be_a_string()) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>); + +#[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<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result<Self::Ok> { + Err(invalid_number()) + } + + serde_if_integer128! { + fn serialize_i128(self, _v: i128) -> Result<Self::Ok> { + Err(invalid_number()) + } + } + + fn serialize_u8(self, _v: u8) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result<Self::Ok> { + Err(invalid_number()) + } + + serde_if_integer128! { + fn serialize_u128(self, _v: u128) -> Result<Self::Ok> { + Err(invalid_number()) + } + } + + fn serialize_f32(self, _v: f32) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result<Self::Ok> { + let NumberStrEmitter(serializer) = self; + serializer + .formatter + .write_number_str(&mut serializer.writer, value) + .map_err(Error::io) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok> + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok> { + Err(invalid_number()) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok> + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok> + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct> { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant> { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { + Err(invalid_number()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant> { + Err(invalid_number()) + } +} + +#[cfg(feature = "raw_value")] +struct RawValueStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>); + +#[cfg(feature = "raw_value")] +impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a, W, F> { + type Ok = (); + type Error = Error; + + type SerializeSeq = Impossible<(), Error>; + type SerializeTuple = Impossible<(), Error>; + type SerializeTupleStruct = Impossible<(), Error>; + type SerializeTupleVariant = Impossible<(), Error>; + type SerializeMap = Impossible<(), Error>; + type SerializeStruct = Impossible<(), Error>; + type SerializeStructVariant = Impossible<(), Error>; + + fn serialize_bool(self, _v: bool) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i8(self, _v: i8) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i16(self, _v: i16) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i32(self, _v: i32) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i64(self, _v: i64) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + serde_if_integer128! { + fn serialize_i128(self, _v: i128) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + } + + fn serialize_u8(self, _v: u8) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u16(self, _v: u16) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u32(self, _v: u32) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u64(self, _v: u64) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + serde_if_integer128! { + fn serialize_u128(self, _v: u128) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + } + + fn serialize_f32(self, _v: f32) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_f64(self, _v: f64) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_char(self, _v: char) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_str(self, value: &str) -> Result<Self::Ok> { + let RawValueStrEmitter(serializer) = self; + serializer + .formatter + .write_raw_fragment(&mut serializer.writer, value) + .map_err(Error::io) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_none(self) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok> + where + T: Serialize, + { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_unit(self) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok> + where + T: Serialize, + { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok> + where + T: Serialize, + { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant> { + Err(ser::Error::custom("expected RawValue")) + } +} + +/// Represents a character escape code in a type-safe manner. +pub enum CharEscape { + /// An escaped quote `"` + Quote, + /// An escaped reverse solidus `\` + ReverseSolidus, + /// An escaped solidus `/` + Solidus, + /// An escaped backspace character (usually escaped as `\b`) + Backspace, + /// An escaped form feed character (usually escaped as `\f`) + FormFeed, + /// An escaped line feed character (usually escaped as `\n`) + LineFeed, + /// An escaped carriage return character (usually escaped as `\r`) + CarriageReturn, + /// An escaped tab character (usually escaped as `\t`) + Tab, + /// An escaped ASCII plane control character (usually escaped as + /// `\u00XX` where `XX` are two hex characters) + AsciiControl(u8), +} + +impl CharEscape { + #[inline] + fn from_escape_table(escape: u8, byte: u8) -> CharEscape { + match escape { + self::BB => CharEscape::Backspace, + self::TT => CharEscape::Tab, + self::NN => CharEscape::LineFeed, + self::FF => CharEscape::FormFeed, + self::RR => CharEscape::CarriageReturn, + self::QU => CharEscape::Quote, + self::BS => CharEscape::ReverseSolidus, + self::UU => CharEscape::AsciiControl(byte), + _ => unreachable!(), + } + } +} + +/// This trait abstracts away serializing the JSON control characters, which allows the user to +/// optionally pretty print the JSON output. +pub trait Formatter { + /// Writes a `null` value to the specified writer. + #[inline] + fn write_null<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&mut self, writer: &mut W, value: f32) -> io::Result<()> + where + W: io::Write, + { + let mut buffer = ryu::Buffer::new(); + let s = buffer.format_finite(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a floating point value like `-31.26e+12` to the specified writer. + #[inline] + fn write_f64<W: ?Sized>(&mut self, writer: &mut W, value: f64) -> io::Result<()> + where + W: io::Write, + { + let mut buffer = ryu::Buffer::new(); + let s = buffer.format_finite(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a number that has already been rendered to a string. + #[inline] + fn write_number_str<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>( + &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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + Ok(()) + } + + /// Writes a raw JSON fragment that doesn't need any escaping to the + /// specified writer. + #[inline] + fn write_raw_fragment<W: ?Sized>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(fragment.as_bytes()) + } +} + +/// This structure compacts a JSON value with no extra whitespace. +#[derive(Clone, Debug)] +pub struct CompactFormatter; + +impl Formatter for CompactFormatter {} + +/// This structure pretty prints a JSON value to make it human readable. +#[derive(Clone, Debug)] +pub struct PrettyFormatter<'a> { + current_indent: usize, + has_value: bool, + indent: &'a [u8], +} + +impl<'a> PrettyFormatter<'a> { + /// Construct a pretty printer formatter that defaults to using two spaces for indentation. + pub fn new() -> Self { + PrettyFormatter::with_indent(b" ") + } + + /// Construct a pretty printer formatter that uses the `indent` string for indentation. + pub fn with_indent(indent: &'a [u8]) -> Self { + PrettyFormatter { + current_indent: 0, + has_value: false, + indent: indent, + } + } +} + +impl<'a> Default for PrettyFormatter<'a> { + fn default() -> Self { + PrettyFormatter::new() + } +} + +impl<'a> Formatter for PrettyFormatter<'a> { + #[inline] + fn begin_array<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.has_value = true; + Ok(()) + } + + #[inline] + fn begin_object<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&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<W: ?Sized>(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b": ") + } + + #[inline] + fn end_object_value<W: ?Sized>(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.has_value = true; + Ok(()) + } +} + +fn format_escaped_str<W: ?Sized, F: ?Sized>( + 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<W: ?Sized, F: ?Sized>( + 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 UU: u8 = b'u'; // \x00...\x1F except the ones above +const __: u8 = 0; + +// Lookup table of escape sequences. A value of b'x' at index i means that byte +// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped. +static ESCAPE: [u8; 256] = [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0 + UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1 + __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F +]; + +/// Serialize the given data structure as JSON into the IO stream. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: 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<W, T: ?Sized>(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: 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<T: ?Sized>(value: &T) -> Result<Vec<u8>> +where + T: 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<T: ?Sized>(value: &T) -> Result<Vec<u8>> +where + T: 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<T: ?Sized>(value: &T) -> Result<String> +where + T: 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<T: ?Sized>(value: &T) -> Result<String> +where + T: 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<W: ?Sized>(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 0000000000..c1f0810dd0 --- /dev/null +++ b/third_party/rust/serde_json/src/value/de.rs @@ -0,0 +1,1488 @@ +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; + +use serde::de; + +#[cfg(feature = "arbitrary_precision")] +use number::NumberFromString; + +impl<'de> Deserialize<'de> for Value { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Value, D::Error> + 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<E>(self, value: bool) -> Result<Value, E> { + Ok(Value::Bool(value)) + } + + #[inline] + fn visit_i64<E>(self, value: i64) -> Result<Value, E> { + Ok(Value::Number(value.into())) + } + + #[inline] + fn visit_u64<E>(self, value: u64) -> Result<Value, E> { + Ok(Value::Number(value.into())) + } + + #[inline] + fn visit_f64<E>(self, value: f64) -> Result<Value, E> { + Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) + } + + #[inline] + fn visit_str<E>(self, value: &str) -> Result<Value, E> + where + E: serde::de::Error, + { + self.visit_string(String::from(value)) + } + + #[inline] + fn visit_string<E>(self, value: String) -> Result<Value, E> { + Ok(Value::String(value)) + } + + #[inline] + fn visit_none<E>(self) -> Result<Value, E> { + Ok(Value::Null) + } + + #[inline] + fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error> + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit<E>(self) -> Result<Value, E> { + Ok(Value::Null) + } + + #[inline] + fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error> + where + V: SeqAccess<'de>, + { + let mut vec = Vec::new(); + + while let Some(elem) = try!(visitor.next_element()) { + vec.push(elem); + } + + Ok(Value::Array(vec)) + } + + fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error> + where + V: MapAccess<'de>, + { + match visitor.next_key_seed(KeyClassifier)? { + #[cfg(feature = "arbitrary_precision")] + Some(KeyClass::Number) => { + let number: NumberFromString = visitor.next_value()?; + Ok(Value::Number(number.value)) + } + #[cfg(feature = "raw_value")] + Some(KeyClass::RawValue) => { + let value = visitor.next_value_seed(::raw::BoxedFromString)?; + ::from_str(value.get()).map_err(de::Error::custom) + } + Some(KeyClass::Map(first_key)) => { + let mut values = Map::new(); + + values.insert(first_key, try!(visitor.next_value())); + while let Some((key, value)) = try!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(Value::Object(values)) + } + None => Ok(Value::Object(Map::new())), + } + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} + +impl str::FromStr for Value { + type Err = Error; + fn from_str(s: &str) -> Result<Value, Error> { + super::super::de::from_str(s) + } +} + +macro_rules! deserialize_prim_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + } +} + +fn visit_array<'de, V>(array: Vec<Value>, visitor: V) -> Result<V::Value, Error> +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<String, Value>, visitor: V) -> Result<V::Value, Error> +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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + #[inline] + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + 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<V>( + self, + name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == ::raw::TOKEN { + return visitor.visit_map(::raw::OwnedRawDeserializer { + raw_value: Some(self.to_string()), + }); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_string(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> + 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self { + Value::Object(v) => visit_object(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } +} + +struct EnumDeserializer { + variant: String, + value: Option<Value>, +} + +impl<'de> EnumAccess<'de> for EnumDeserializer { + type Error = Error; + type Variant = VariantDeserializer; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +impl<'de> IntoDeserializer<'de, Error> for Value { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +struct VariantDeserializer { + value: Option<Value>, +} + +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<T>(self, seed: T) -> Result<T::Value, Error> + 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<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error> + 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<V>( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + 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<Value>, +} + +impl SeqDeserializer { + fn new(vec: Vec<Value>) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + } + } +} + +impl<'de> serde::Deserializer<'de> for SeqDeserializer { + type Error = Error; + + #[inline] + fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Error> + 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<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapDeserializer { + iter: <Map<String, Value> as IntoIterator>::IntoIter, + value: Option<Value>, +} + +impl MapDeserializer { + fn new(map: Map<String, Value>) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapDeserializer { + type Error = Error; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, 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<T>(&mut self, seed: T) -> Result<T::Value, Error> + 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<usize> { + 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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V::Value, Error> +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<String, Value>, visitor: V) -> Result<V::Value, Error> +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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + 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<V>( + self, + name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == ::raw::TOKEN { + return visitor.visit_map(::raw::OwnedRawDeserializer { + raw_value: Some(self.to_string()), + }); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self { + Value::String(ref v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> + 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self { + Value::Array(ref v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match *self { + Value::Object(ref v) => visit_object_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + 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<V>(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<T>(self, seed: T) -> Result<T::Value, Error> + 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<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error> + 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<V>( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + 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<V>(mut self, visitor: V) -> Result<V::Value, Error> + 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<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapRefDeserializer<'de> { + iter: <&'de Map<String, Value> as IntoIterator>::IntoIter, + value: Option<&'de Value>, +} + +impl<'de> MapRefDeserializer<'de> { + fn new(map: &'de Map<String, Value>) -> Self { + MapRefDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { + type Error = Error; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, 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<T>(&mut self, seed: T) -> Result<T::Value, Error> + 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<usize> { + 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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor) + } + + deserialize_integer_key!(deserialize_i8 => visit_i8); + deserialize_integer_key!(deserialize_i16 => visit_i16); + deserialize_integer_key!(deserialize_i32 => visit_i32); + deserialize_integer_key!(deserialize_i64 => visit_i64); + deserialize_integer_key!(deserialize_u8 => visit_u8); + deserialize_integer_key!(deserialize_u16 => visit_u16); + deserialize_integer_key!(deserialize_u32 => visit_u32); + deserialize_integer_key!(deserialize_u64 => visit_u64); + + serde_if_integer128! { + deserialize_integer_key!(deserialize_i128 => visit_i128); + deserialize_integer_key!(deserialize_u128 => visit_u128); + } + + #[inline] + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.key + .into_deserializer() + .deserialize_enum(name, variants, visitor) + } + + forward_to_deserialize_any! { + bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +struct KeyClassifier; + +enum KeyClass { + Map(String), + #[cfg(feature = "arbitrary_precision")] + Number, + #[cfg(feature = "raw_value")] + RawValue, +} + +impl<'de> DeserializeSeed<'de> for KeyClassifier { + type Value = KeyClass; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for KeyClassifier { + type Value = KeyClass; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string key") + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + match s { + #[cfg(feature = "arbitrary_precision")] + ::number::TOKEN => Ok(KeyClass::Number), + #[cfg(feature = "raw_value")] + ::raw::TOKEN => Ok(KeyClass::RawValue), + _ => Ok(KeyClass::Map(s.to_owned())), + } + } + + fn visit_string<E>(self, s: String) -> Result<Self::Value, E> + where + E: de::Error, + { + match s.as_str() { + #[cfg(feature = "arbitrary_precision")] + ::number::TOKEN => Ok(KeyClass::Number), + #[cfg(feature = "raw_value")] + ::raw::TOKEN => Ok(KeyClass::RawValue), + _ => Ok(KeyClass::Map(s)), + } + } +} + +impl Value { + #[cold] + fn invalid_type<E>(&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, + } + } +} + +struct BorrowedCowStrDeserializer<'de> { + value: Cow<'de, str>, +} + +impl<'de> BorrowedCowStrDeserializer<'de> { + fn new(value: Cow<'de, str>) -> Self { + BorrowedCowStrDeserializer { value: value } + } +} + +impl<'de> de::Deserializer<'de> for BorrowedCowStrDeserializer<'de> { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.value { + Cow::Borrowed(string) => visitor.visit_borrowed_str(string), + Cow::Owned(string) => visitor.visit_string(string), + } + } + + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> { + type Error = Error; + type Variant = UnitOnly; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + let value = seed.deserialize(self)?; + Ok((value, UnitOnly)) + } +} + +struct UnitOnly; + +impl<'de> de::VariantAccess<'de> for UnitOnly { + type Error = Error; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } +} 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 0000000000..2b743d2af0 --- /dev/null +++ b/third_party/rust/serde_json/src/value/from.rs @@ -0,0 +1,229 @@ +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 +} + +#[cfg(feature = "arbitrary_precision")] +serde_if_integer128! { + from_integer! { + i128 u128 + } +} + +impl From<f32> for Value { + /// Convert 32-bit floating point number to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// 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<f64> for Value { + /// Convert 64-bit floating point number to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let f: f64 = 13.37; + /// let x: Value = f.into(); + /// ``` + fn from(f: f64) -> Self { + Number::from_f64(f).map_or(Value::Null, Value::Number) + } +} + +impl From<bool> for Value { + /// Convert boolean to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let b = false; + /// let x: Value = b.into(); + /// ``` + fn from(f: bool) -> Self { + Value::Bool(f) + } +} + +impl From<String> for Value { + /// Convert `String` to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// 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 + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let s: &str = "lorem"; + /// let x: Value = s.into(); + /// ``` + fn from(f: &str) -> Self { + Value::String(f.to_string()) + } +} + +impl<'a> From<Cow<'a, str>> for Value { + /// Convert copy-on-write string to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow<str> = Cow::Borrowed("lorem"); + /// let x: Value = s.into(); + /// ``` + /// + /// ```edition2018 + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow<str> = Cow::Owned("lorem".to_string()); + /// let x: Value = s.into(); + /// ``` + fn from(f: Cow<'a, str>) -> Self { + Value::String(f.into_owned()) + } +} + +impl From<Map<String, Value>> for Value { + /// Convert map (with string keys) to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::{Map, Value}; + /// + /// let mut m = Map::new(); + /// m.insert("Lorem".to_string(), "ipsum".into()); + /// let x: Value = m.into(); + /// ``` + fn from(f: Map<String, Value>) -> Self { + Value::Object(f) + } +} + +impl<T: Into<Value>> From<Vec<T>> for Value { + /// Convert a `Vec` to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let v = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: Vec<T>) -> Self { + Value::Array(f.into_iter().map(Into::into).collect()) + } +} + +impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value { + /// Convert a slice to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: &'a [T]) -> Self { + Value::Array(f.iter().cloned().map(Into::into).collect()) + } +} + +impl<T: Into<Value>> ::std::iter::FromIterator<T> for Value { + /// Convert an iteratable type to a `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let v = std::iter::repeat(42).take(5); + /// let x: Value = v.collect(); + /// ``` + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into_iter().collect(); + /// ``` + /// + /// ```edition2018 + /// use std::iter::FromIterator; + /// use serde_json::Value; + /// + /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); + /// ``` + fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { + Value::Array(iter.into_iter().map(Into::into).collect()) + } +} + +impl From<()> for Value { + /// Convert `()` to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_json::Value; + /// + /// let u = (); + /// let x: Value = u.into(); + /// ``` + fn from((): ()) -> Self { + Value::Null + } +} 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 0000000000..47990a5473 --- /dev/null +++ b/third_party/rust/serde_json/src/value/index.rs @@ -0,0 +1,257 @@ +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 +/// +/// ```edition2018 +/// # use serde_json::json; +/// # +/// let data = json!({ "inner": [1, 2, 3] }); +/// +/// // Data is a JSON map so it can be indexed with a string. +/// let inner = &data["inner"]; +/// +/// // Inner is a JSON array so it can be indexed with an integer. +/// let first = &inner[0]; +/// +/// assert_eq!(first, 1); +/// ``` +pub trait Index: private::Sealed { + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; + + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; + + /// Panic if array index out of bounds. If key is not already in the object, + /// insert it with a value of null. Panic if Value is a type that cannot be + /// indexed into, except if Value is null then it can be treated as an empty + /// object. + #[doc(hidden)] + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; +} + +impl Index for usize { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match *v { + Value::Array(ref vec) => vec.get(*self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match *v { + Value::Array(ref mut vec) => vec.get_mut(*self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + match *v { + Value::Array(ref mut vec) => { + let len = vec.len(); + vec.get_mut(*self).unwrap_or_else(|| { + panic!( + "cannot access index {} of JSON array of length {}", + self, len + ) + }) + } + _ => panic!("cannot access index {} of JSON {}", self, Type(v)), + } + } +} + +impl Index for str { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match *v { + Value::Object(ref map) => map.get(self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match *v { + Value::Object(ref mut map) => map.get_mut(self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + if let Value::Null = *v { + *v = Value::Object(Map::new()); + } + match *v { + Value::Object(ref mut map) => map.entry(self.to_owned()).or_insert(Value::Null), + _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), + } + } +} + +impl Index for String { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + self[..].index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + self[..].index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + self[..].index_or_insert(v) + } +} + +impl<'a, T: ?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<I> ops::Index<I> for Value +where + I: Index, +{ + type Output = Value; + + /// Index into a `serde_json::Value` using the syntax `value[0]` or + /// `value["k"]`. + /// + /// Returns `Value::Null` if the type of `self` does not match the type of + /// the index, for example if the index is a string and `self` is an array + /// or a number. Also returns `Value::Null` if the given key does not exist + /// in the map or the given index is not within the bounds of the array. + /// + /// For retrieving deeply nested values, you should have a look at the + /// `Value::pointer` method. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); + /// assert_eq!(data["x"]["y"][0], json!("z")); + /// + /// assert_eq!(data["a"], json!(null)); // returns null for undefined values + /// assert_eq!(data["a"]["b"], json!(null)); // does not panic + /// ``` + fn index(&self, index: I) -> &Value { + static NULL: Value = Value::Null; + index.index_into(self).unwrap_or(&NULL) + } +} + +impl<I> ops::IndexMut<I> for Value +where + I: Index, +{ + /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or + /// `value["k"] = ...`. + /// + /// If the index is a number, the value must be an array of length bigger + /// than the index. Indexing into a value that is not an array or an array + /// that is too small will panic. + /// + /// If the index is a string, the value must be an object or null which is + /// treated like an empty object. If the key is not already present in the + /// object, it will be inserted with a value of null. Indexing into a value + /// that is neither an object nor null will panic. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut data = json!({ "x": 0 }); + /// + /// // replace an existing key + /// data["x"] = json!(1); + /// + /// // insert a new key + /// data["y"] = json!([false, false, false]); + /// + /// // replace an array value + /// data["y"][0] = json!(true); + /// + /// // inserted a deeply nested key + /// data["a"]["b"]["c"]["d"] = json!(true); + /// + /// println!("{}", data); + /// ``` + fn index_mut(&mut self, index: I) -> &mut Value { + index.index_or_insert(self) + } +} diff --git a/third_party/rust/serde_json/src/value/mod.rs b/third_party/rust/serde_json/src/value/mod.rs new file mode 100644 index 0000000000..eb4b9002ce --- /dev/null +++ b/third_party/rust/serde_json/src/value/mod.rs @@ -0,0 +1,1002 @@ +//! 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. +//! +//! ```edition2018 +//! use serde_json::json; +//! +//! fn main() { +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }); +//! +//! println!("first phone number: {}", john["phones"][0]); +//! +//! // Convert to a string of JSON and print it out +//! println!("{}", john.to_string()); +//! } +//! ``` +//! +//! The `Value::to_string()` function converts a `serde_json::Value` into a +//! `String` of JSON text. +//! +//! One neat thing about the `json!` macro is that variables and expressions can +//! be interpolated directly into the JSON value as you are building it. Serde +//! will check at compile time that the value you are interpolating is able to +//! be represented as JSON. +//! +//! ```edition2018 +//! # use serde_json::json; +//! # +//! # fn random_phone() -> u16 { 0 } +//! # +//! let full_name = "John Doe"; +//! let age_last_year = 42; +//! +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": full_name, +//! "age": age_last_year + 1, +//! "phones": [ +//! format!("+44 {}", random_phone()) +//! ] +//! }); +//! ``` +//! +//! A string of JSON data can be parsed into a `serde_json::Value` by the +//! [`serde_json::from_str`][from_str] function. There is also +//! [`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and +//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or +//! a TCP stream. +//! +//! ```edition2018 +//! use serde_json::{json, Value, Error}; +//! +//! fn untyped_example() -> Result<(), Error> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into serde_json::Value. +//! let v: Value = serde_json::from_str(data)?; +//! +//! // Access parts of the data by indexing with square brackets. +//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); +//! +//! Ok(()) +//! } +//! # +//! # untyped_example().unwrap(); +//! ``` +//! +//! [macro]: https://docs.serde.rs/serde_json/macro.json.html +//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html +//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html +//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html + +use 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; + +#[cfg(feature = "raw_value")] +pub use raw::RawValue; + +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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!(null); + /// ``` + Null, + + /// Represents a JSON boolean. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!(true); + /// ``` + Bool(bool), + + /// Represents a JSON number, whether integer or floating point. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!(12.5); + /// ``` + Number(Number), + + /// Represents a JSON string. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!("a string"); + /// ``` + String(String), + + /// Represents a JSON array. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!(["an", "array"]); + /// ``` + Array(Vec<Value>), + + /// 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "an": "object" }); + /// ``` + Object(Map<String, Value>), +} + +impl Debug for Value { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self { + Value::Null => formatter.debug_tuple("Null").finish(), + Value::Bool(v) => formatter.debug_tuple("Bool").field(&v).finish(), + Value::Number(ref v) => Debug::fmt(v, formatter), + Value::String(ref v) => formatter.debug_tuple("String").field(v).finish(), + Value::Array(ref v) => formatter.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<usize> { + fn io_error<E>(_: 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let json = json!({ "city": "London", "street": "10 Downing Street" }); + /// + /// // Compact format: + /// // + /// // {"city":"London","street":"10 Downing Street"} + /// let compact = format!("{}", json); + /// assert_eq!(compact, + /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}"); + /// + /// // Pretty format: + /// // + /// // { + /// // "city": "London", + /// // "street": "10 Downing Street" + /// // } + /// let pretty = format!("{:#}", json); + /// assert_eq!(pretty, + /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); + /// ``` + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let alternate = f.alternate(); + let mut wr = WriterFormatter { inner: f }; + if alternate { + // {:#} + super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) + } else { + // {} + super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) + } + } +} + +fn parse_index(s: &str) -> Option<usize> { + 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let object = json!({ "A": 65, "B": 66, "C": 67 }); + /// assert_eq!(*object.get("A").unwrap(), json!(65)); + /// + /// let array = json!([ "A", "B", "C" ]); + /// assert_eq!(*array.get(2).unwrap(), json!("C")); + /// + /// assert_eq!(array.get("A"), None); + /// ``` + /// + /// Square brackets can also be used to index into a value in a more concise + /// way. This returns `Value::Null` in cases where `get` would have returned + /// `None`. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let object = json!({ + /// "A": ["a", "á", "à"], + /// "B": ["b", "b́"], + /// "C": ["c", "ć", "ć̣", "ḉ"], + /// }); + /// assert_eq!(object["B"][0], json!("b")); + /// + /// assert_eq!(object["D"], json!(null)); + /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); + /// ``` + pub fn get<I: Index>(&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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); + /// *object.get_mut("A").unwrap() = json!(69); + /// + /// let mut array = json!([ "A", "B", "C" ]); + /// *array.get_mut(2).unwrap() = json!("D"); + /// ``` + pub fn get_mut<I: Index>(&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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// assert!(obj.is_object()); + /// assert!(obj["a"].is_object()); + /// + /// // array, not an object + /// assert!(!obj["b"].is_object()); + /// ``` + pub fn is_object(&self) -> bool { + self.as_object().is_some() + } + + /// If the `Value` is an Object, returns the associated Map. Returns None + /// otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// // The length of `{"nested": true}` is 1 entry. + /// assert_eq!(v["a"].as_object().unwrap().len(), 1); + /// + /// // The array `["an", "array"]` is not an object. + /// assert_eq!(v["b"].as_object(), None); + /// ``` + pub fn as_object(&self) -> Option<&Map<String, Value>> { + match *self { + Value::Object(ref map) => Some(map), + _ => None, + } + } + + /// If the `Value` is an Object, returns the associated mutable Map. + /// Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut v = json!({ "a": { "nested": true } }); + /// + /// v["a"].as_object_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": {} })); + /// ``` + pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> { + 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// assert!(obj["a"].is_array()); + /// + /// // an object, not an array + /// assert!(!obj["b"].is_array()); + /// ``` + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// If the `Value` is an Array, returns the associated vector. Returns None + /// otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// // The length of `["an", "array"]` is 2 elements. + /// assert_eq!(v["a"].as_array().unwrap().len(), 2); + /// + /// // The object `{"an": "object"}` is not an array. + /// assert_eq!(v["b"].as_array(), None); + /// ``` + pub fn as_array(&self) -> Option<&Vec<Value>> { + match *self { + Value::Array(ref array) => Some(&*array), + _ => None, + } + } + + /// If the `Value` is an Array, returns the associated mutable vector. + /// Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut v = json!({ "a": ["an", "array"] }); + /// + /// v["a"].as_array_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": [] })); + /// ``` + pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> { + 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert!(v["a"].is_string()); + /// + /// // The boolean `false` is not a string. + /// assert!(!v["b"].is_string()); + /// ``` + pub fn is_string(&self) -> bool { + self.as_str().is_some() + } + + /// If the `Value` is a String, returns the associated str. Returns None + /// otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert_eq!(v["a"].as_str(), Some("some string")); + /// + /// // The boolean `false` is not a string. + /// assert_eq!(v["b"].as_str(), None); + /// + /// // JSON values are printed in JSON representation, so strings are in quotes. + /// // + /// // The value is: "some string" + /// println!("The value is: {}", v["a"]); + /// + /// // Rust strings are printed without quotes. + /// // + /// // The value is: some string + /// println!("The value is: {}", v["a"].as_str().unwrap()); + /// ``` + pub fn as_str(&self) -> Option<&str> { + match *self { + Value::String(ref s) => Some(s), + _ => None, + } + } + + /// Returns true if the `Value` is a Number. Returns false otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 1, "b": "2" }); + /// + /// assert!(v["a"].is_number()); + /// + /// // The string `"2"` is a string, not a number. + /// assert!(!v["b"].is_number()); + /// ``` + pub fn is_number(&self) -> bool { + match *self { + Value::Number(_) => true, + _ => false, + } + } + + /// Returns true if the `Value` is an integer between `i64::MIN` and + /// `i64::MAX`. + /// + /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to + /// return the integer value. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert!(v["a"].is_i64()); + /// + /// // Greater than i64::MAX. + /// assert!(!v["b"].is_i64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_i64()); + /// ``` + pub fn is_i64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_i64(), + _ => false, + } + } + + /// Returns true if the `Value` is an integer between zero and `u64::MAX`. + /// + /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert!(v["a"].is_u64()); + /// + /// // Negative integer. + /// assert!(!v["b"].is_u64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_u64()); + /// ``` + pub fn is_u64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_u64(), + _ => false, + } + } + + /// Returns true if the `Value` is a number that can be represented by f64. + /// + /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to + /// return the floating point value. + /// + /// Currently this function returns true if and only if both `is_i64` and + /// `is_u64` return false but this is not a guarantee in the future. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// ``` + pub fn is_f64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_f64(), + _ => false, + } + } + + /// If the `Value` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// ``` + pub fn as_i64(&self) -> Option<i64> { + 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// ``` + pub fn as_u64(&self) -> Option<u64> { + 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// ``` + pub fn as_f64(&self) -> Option<f64> { + 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert!(v["a"].is_boolean()); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert!(!v["b"].is_boolean()); + /// ``` + pub fn is_boolean(&self) -> bool { + self.as_bool().is_some() + } + + /// If the `Value` is a Boolean, returns the associated bool. Returns None + /// otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert_eq!(v["a"].as_bool(), Some(false)); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert_eq!(v["b"].as_bool(), None); + /// ``` + pub fn as_bool(&self) -> Option<bool> { + 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(())`. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": null, "b": false }); + /// + /// assert!(v["a"].is_null()); + /// + /// // The boolean `false` is not null. + /// assert!(!v["b"].is_null()); + /// ``` + pub fn is_null(&self) -> bool { + self.as_null().is_some() + } + + /// If the `Value` is a Null, returns (). Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let v = json!({ "a": null, "b": false }); + /// + /// assert_eq!(v["a"].as_null(), Some(())); + /// + /// // The boolean `false` is not null. + /// assert_eq!(v["b"].as_null(), None); + /// ``` + pub fn as_null(&self) -> Option<()> { + match *self { + Value::Null => Some(()), + _ => None, + } + } + + /// Looks up a value by a JSON Pointer. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz")); + /// assert_eq!(data.pointer("/a/b/c"), None); + /// ``` + pub fn pointer<'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 + /// + /// ```edition2018 + /// 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. + /// + /// ```edition2018 + /// # use serde_json::json; + /// # + /// let mut v = json!({ "x": "y" }); + /// assert_eq!(v["x"].take(), json!("y")); + /// assert_eq!(v, json!({ "x": null })); + /// ``` + pub fn take(&mut self) -> Value { + mem::replace(self, Value::Null) + } +} + +/// The default value is `Value::Null`. +/// +/// This is useful for handling omitted `Value` fields when deserializing. +/// +/// # Examples +/// +/// ```edition2018 +/// # use serde::Deserialize; +/// use serde_json::Value; +/// +/// #[derive(Deserialize)] +/// struct Settings { +/// level: i32, +/// #[serde(default)] +/// extras: Value, +/// } +/// +/// # fn try_main() -> Result<(), serde_json::Error> { +/// let data = r#" { "level": 42 } "#; +/// let s: Settings = serde_json::from_str(data)?; +/// +/// assert_eq!(s.level, 42); +/// assert_eq!(s.extras, Value::Null); +/// # +/// # Ok(()) +/// # } +/// # +/// # try_main().unwrap() +/// ``` +impl Default for Value { + fn default() -> Value { + Value::Null + } +} + +mod de; +mod from; +mod index; +mod partial_eq; +mod ser; + +/// Convert a `T` into `serde_json::Value` which is an enum that can represent +/// any valid JSON data. +/// +/// # Example +/// +/// ```edition2018 +/// use serde::Serialize; +/// use serde_json::json; +/// +/// use std::error::Error; +/// +/// #[derive(Serialize)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn compare_json_values() -> Result<(), Box<Error>> { +/// let u = User { +/// fingerprint: "0xF9BA143B95FF6D82".to_owned(), +/// location: "Menlo Park, CA".to_owned(), +/// }; +/// +/// // The type of `expected` is `serde_json::Value` +/// let expected = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA", +/// }); +/// +/// let v = serde_json::to_value(u).unwrap(); +/// assert_eq!(v, expected); +/// +/// Ok(()) +/// } +/// # +/// # compare_json_values().unwrap(); +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +/// +/// ```edition2018 +/// 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<T>(value: T) -> Result<Value, Error> +where + T: Serialize, +{ + value.serialize(Serializer) +} + +/// Interpret a `serde_json::Value` as an instance of type `T`. +/// +/// # Example +/// +/// ```edition2018 +/// use serde::Deserialize; +/// use serde_json::json; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `serde_json::Value` +/// let j = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA" +/// }); +/// +/// let u: User = serde_json::from_value(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the Value does not match the +/// structure expected by `T`, for example if `T` is a struct type but the Value +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_value<T>(value: Value) -> Result<T, Error> +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 0000000000..cfcf957063 --- /dev/null +++ b/third_party/rust/serde_json/src/value/partial_eq.rs @@ -0,0 +1,94 @@ +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<str> 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<Value> for str { + fn eq(&self, other: &Value) -> bool { + eq_str(other, self) + } +} + +impl<'a> PartialEq<Value> for &'a str { + fn eq(&self, other: &Value) -> bool { + eq_str(other, *self) + } +} + +impl PartialEq<String> for Value { + fn eq(&self, other: &String) -> bool { + eq_str(self, other.as_str()) + } +} + +impl PartialEq<Value> for String { + fn eq(&self, other: &Value) -> bool { + eq_str(other, self.as_str()) + } +} + +macro_rules! partialeq_numeric { + ($($eq:ident [$($ty:ty)*])*) => { + $($( + impl PartialEq<$ty> for Value { + fn eq(&self, other: &$ty) -> bool { + $eq(self, *other as _) + } + } + + impl PartialEq<Value> for $ty { + fn eq(&self, other: &Value) -> bool { + $eq(other, *self as _) + } + } + + impl<'a> PartialEq<$ty> for &'a Value { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + + impl<'a> PartialEq<$ty> for &'a mut Value { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + )*)* + } +} + +partialeq_numeric! { + eq_i64[i8 i16 i32 i64 isize] + eq_u64[u8 u16 u32 u64 usize] + eq_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 0000000000..b0e09beb54 --- /dev/null +++ b/third_party/rust/serde_json/src/value/ser.rs @@ -0,0 +1,1018 @@ +use serde::ser::Impossible; +use serde::{self, Serialize}; + +use error::{Error, ErrorCode}; +use map::Map; +use number::Number; +use value::{to_value, Value}; + +impl Serialize for Value { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + 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<Value, Error> { + Ok(Value::Bool(value)) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result<Value, Error> { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result<Value, Error> { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result<Value, Error> { + self.serialize_i64(value as i64) + } + + fn serialize_i64(self, value: i64) -> Result<Value, Error> { + Ok(Value::Number(value.into())) + } + + #[cfg(feature = "arbitrary_precision")] + serde_if_integer128! { + fn serialize_i128(self, value: i128) -> Result<Value, Error> { + Ok(Value::Number(value.into())) + } + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result<Value, Error> { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result<Value, Error> { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result<Value, Error> { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result<Value, Error> { + Ok(Value::Number(value.into())) + } + + #[cfg(feature = "arbitrary_precision")] + serde_if_integer128! { + fn serialize_u128(self, value: u128) -> Result<Value, Error> { + Ok(Value::Number(value.into())) + } + } + + #[inline] + fn serialize_f32(self, value: f32) -> Result<Value, Error> { + self.serialize_f64(value as f64) + } + + #[inline] + fn serialize_f64(self, value: f64) -> Result<Value, Error> { + Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) + } + + #[inline] + fn serialize_char(self, value: char) -> Result<Value, Error> { + let mut s = String::new(); + s.push(value); + self.serialize_str(&s) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result<Value, Error> { + Ok(Value::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<Value, Error> { + let vec = value.iter().map(|&b| Value::Number(b.into())).collect(); + Ok(Value::Array(vec)) + } + + #[inline] + fn serialize_unit(self) -> Result<Value, Error> { + Ok(Value::Null) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<Value, Error> { + self.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + value: &T, + ) -> Result<Value, Error> + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<Value, Error> + 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<Value, Error> { + self.serialize_unit() + } + + #[inline] + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, Error> + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct, Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, Error> { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(len), + }) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> { + Ok(SerializeMap::Map { + map: Map::new(), + next_key: None, + }) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, Error> { + match name { + #[cfg(feature = "arbitrary_precision")] + ::number::TOKEN => Ok(SerializeMap::Number { out_value: None }), + #[cfg(feature = "raw_value")] + ::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }), + _ => self.serialize_map(Some(len)), + } + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Error> { + Ok(SerializeStructVariant { + name: String::from(variant), + map: Map::new(), + }) + } +} + +pub struct SerializeVec { + vec: Vec<Value>, +} + +pub struct SerializeTupleVariant { + name: String, + vec: Vec<Value>, +} + +pub enum SerializeMap { + Map { + map: Map<String, Value>, + next_key: Option<String>, + }, + #[cfg(feature = "arbitrary_precision")] + Number { out_value: Option<Value> }, + #[cfg(feature = "raw_value")] + RawValue { out_value: Option<Value> }, +} + +pub struct SerializeStructVariant { + name: String, + map: Map<String, Value>, +} + +impl serde::ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + self.vec.push(try!(to_value(&value))); + Ok(()) + } + + fn end(self) -> Result<Value, Error> { + Ok(Value::Array(self.vec)) + } +} + +impl serde::ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, Error> { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, Error> { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + self.vec.push(try!(to_value(&value))); + Ok(()) + } + + fn end(self) -> Result<Value, Error> { + 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<T: ?Sized>(&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!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } + + fn serialize_value<T: ?Sized>(&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!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } + + fn end(self) -> Result<Value, Error> { + match self { + SerializeMap::Map { map, .. } => Ok(Value::Object(map)), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer; + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +impl serde::Serializer for MapKeySerializer { + type Ok = String; + type Error = Error; + + type SerializeSeq = Impossible<String, Error>; + type SerializeTuple = Impossible<String, Error>; + type SerializeTupleStruct = Impossible<String, Error>; + type SerializeTupleVariant = Impossible<String, Error>; + type SerializeMap = Impossible<String, Error>; + type SerializeStruct = Impossible<String, Error>; + type SerializeStructVariant = Impossible<String, Error>; + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + Ok(variant.to_owned()) + } + + #[inline] + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_i8(self, value: i8) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_i16(self, value: i16) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_i32(self, value: i32) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_i64(self, value: i64) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_u8(self, value: u8) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_u16(self, value: u16) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_u32(self, value: u32) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_u64(self, value: u64) -> Result<Self::Ok, Self::Error> { + Ok(value.to_string()) + } + + fn serialize_f32(self, _value: f32) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_f64(self, _value: f64) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + #[inline] + fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> { + Ok({ + let mut s = String::new(); + s.push(value); + s + }) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> { + Ok(value.to_owned()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(key_must_be_a_string()) + } +} + +impl serde::ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&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 == ::number::TOKEN { + *out_value = Some(value.serialize(NumberValueEmitter)?); + Ok(()) + } else { + Err(invalid_number()) + } + } + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { ref mut out_value } => { + if key == ::raw::TOKEN { + *out_value = Some(value.serialize(RawValueEmitter)?); + Ok(()) + } else { + Err(invalid_raw_value()) + } + } + } + } + + fn end(self) -> Result<Value, Error> { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { out_value, .. } => { + Ok(out_value.expect("number value was not emitted")) + } + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { out_value, .. } => { + Ok(out_value.expect("raw value was not emitted")) + } + } + } +} + +impl serde::ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&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<Value, Error> { + let mut object = Map::new(); + + object.insert(self.name, Value::Object(self.map)); + + Ok(Value::Object(object)) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberValueEmitter; + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +#[cfg(feature = "arbitrary_precision")] +impl serde::ser::Serializer for NumberValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible<Value, Error>; + type SerializeTuple = Impossible<Value, Error>; + type SerializeTupleStruct = Impossible<Value, Error>; + type SerializeTupleVariant = Impossible<Value, Error>; + type SerializeMap = Impossible<Value, Error>; + type SerializeStruct = Impossible<Value, Error>; + type SerializeStructVariant = Impossible<Value, Error>; + + fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> { + let n = try!(value.to_owned().parse()); + Ok(Value::Number(n)) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + Err(invalid_number()) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Err(invalid_number()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(invalid_number()) + } +} + +#[cfg(feature = "raw_value")] +struct RawValueEmitter; + +#[cfg(feature = "raw_value")] +fn invalid_raw_value() -> Error { + Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) +} + +#[cfg(feature = "raw_value")] +impl serde::ser::Serializer for RawValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible<Value, Error>; + type SerializeTuple = Impossible<Value, Error>; + type SerializeTupleStruct = Impossible<Value, Error>; + type SerializeTupleVariant = Impossible<Value, Error>; + type SerializeMap = Impossible<Value, Error>; + type SerializeStruct = Impossible<Value, Error>; + type SerializeStructVariant = Impossible<Value, Error>; + + fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> { + ::from_str(value) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + Err(invalid_raw_value()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(invalid_raw_value()) + } +} diff --git a/third_party/rust/serde_repr/.cargo-checksum.json b/third_party/rust/serde_repr/.cargo-checksum.json new file mode 100644 index 0000000000..541963b3ca --- /dev/null +++ b/third_party/rust/serde_repr/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"12f7a0095ab071bd65e931e934729b20c4cb59f71f8363ee6242220f08f7fa0f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"1c365193e71eca0287ed4514768ef0d9a41b26f36afd8576068c611814864d1e","src/lib.rs":"63e3e8c186e362636e0f2026169bfa1c5731cb7f48e98ef0084b50dae8834ec1","src/parse.rs":"687cf1436d12c0c26b1c6d06f80e56b4ec0d63a38d71e1f175b981c0fdc10c68","tests/compiletest.rs":"0a52a44786aea1c299c695bf948b2ed2081e4cc344e5c2cadceab4eb03d0010d","tests/test.rs":"69deba0db55c4014b27fe5686b79f67e4926ff31f1655fd8dce0c45a6b3b6b36","tests/ui/empty_enum.rs":"fe1166f2f92ee213d26a23e57572a99c65c163d446fd8d67e1520bab34f4b859","tests/ui/empty_enum.stderr":"c9c64b6126987a255bab90197ae1a39b6666cad437a5d83e21e6ea651be83130","tests/ui/missing_repr.rs":"b7ba9341111582cad52e761b82f14778c60352014c4265566e4d4d01ccdcb306","tests/ui/missing_repr.stderr":"71f1dc0094b13fbbf4eb8d3bdd4c3bb25bf150ea5aa9cd991827482071a381f8","tests/ui/multiple_others.rs":"569658516619719f21e5071873a37125d5390edb77558e4381401f03efda0c83","tests/ui/multiple_others.stderr":"b5eb2b8887e9a234365f8686dfdc0584f2a7a106c3f884ac6386de64559f1b48","tests/ui/non_unit_variant.rs":"0d8295ae08d882fc3ef4164857240038c5b0674ff0811da9b6ea7343e8bb955c","tests/ui/non_unit_variant.stderr":"ba863a840fae03b5b41e09e6dddf5773873b95d0b39775baacb04301b648a8b8","tests/ui/not_enum.rs":"ada7637821c924a6b99175363c820375991be60223f96ca553d304fde2721386","tests/ui/not_enum.stderr":"f55f707b8038a6f491c302b8b00ae6e96bf11fee24ab5b7c16cc97f5fa8ea241"},"package":"cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"}
\ No newline at end of file diff --git a/third_party/rust/serde_repr/Cargo.toml b/third_party/rust/serde_repr/Cargo.toml new file mode 100644 index 0000000000..cb4d12181e --- /dev/null +++ b/third_party/rust/serde_repr/Cargo.toml @@ -0,0 +1,44 @@ +# 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] +edition = "2018" +name = "serde_repr" +version = "0.1.5" +authors = ["David Tolnay <dtolnay@gmail.com>"] +description = "Derive Serialize and Deserialize that delegates to the underlying repr of a C-like enum." +documentation = "https://docs.rs/serde_repr" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/serde-repr" + +[lib] +proc-macro = true +[dependencies.proc-macro2] +version = "1.0" + +[dependencies.quote] +version = "1.0" + +[dependencies.syn] +version = "1.0" +[dev-dependencies.rustversion] +version = "0.1" + +[dev-dependencies.serde] +version = "1.0" + +[dev-dependencies.serde_json] +version = "1.0" + +[dev-dependencies.trybuild] +version = "1.0" diff --git a/third_party/rust/serde_repr/LICENSE-APACHE b/third_party/rust/serde_repr/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_repr/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/serde_repr/LICENSE-MIT b/third_party/rust/serde_repr/LICENSE-MIT new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/third_party/rust/serde_repr/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_repr/README.md b/third_party/rust/serde_repr/README.md new file mode 100644 index 0000000000..5f294d6bdf --- /dev/null +++ b/third_party/rust/serde_repr/README.md @@ -0,0 +1,56 @@ +Serde repr derive +================= + +[![Build Status](https://api.travis-ci.com/dtolnay/serde-repr.svg?branch=master)](https://travis-ci.com/dtolnay/serde-repr) +[![Latest Version](https://img.shields.io/crates/v/serde_repr.svg)](https://crates.io/crates/serde_repr) +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/serde_repr) + +This crate provides a derive macro to derive Serde's `Serialize` and +`Deserialize` traits in a way that delegates to the underlying repr of a C-like +enum. + +```toml +[dependencies] +serde = "1.0" +serde_repr = "0.1" +``` + +```rust +use serde_repr::{Serialize_repr, Deserialize_repr}; + +#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] +#[repr(u8)] +enum SmallPrime { + Two = 2, + Three = 3, + Five = 5, + Seven = 7, +} + +fn main() -> serde_json::Result<()> { + let j = serde_json::to_string(&SmallPrime::Seven)?; + assert_eq!(j, "7"); + + let p: SmallPrime = serde_json::from_str("2")?; + assert_eq!(p, SmallPrime::Two); + + Ok(()) +} +``` + +<br> + +#### License + +<sup> +Licensed under either of <a href="LICENSE-APACHE">Apache License, Version +2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. +</sup> + +<br> + +<sub> +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. +</sub> diff --git a/third_party/rust/serde_repr/src/lib.rs b/third_party/rust/serde_repr/src/lib.rs new file mode 100644 index 0000000000..b80fa9988f --- /dev/null +++ b/third_party/rust/serde_repr/src/lib.rs @@ -0,0 +1,135 @@ +//! Derive `Serialize` and `Deserialize` that delegates to the underlying repr +//! of a C-like enum. +//! +//! # Examples +//! +//! ``` +//! use serde_repr::{Serialize_repr, Deserialize_repr}; +//! +//! #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] +//! #[repr(u8)] +//! enum SmallPrime { +//! Two = 2, +//! Three = 3, +//! Five = 5, +//! Seven = 7, +//! } +//! +//! fn main() -> serde_json::Result<()> { +//! let j = serde_json::to_string(&SmallPrime::Seven)?; +//! assert_eq!(j, "7"); +//! +//! let p: SmallPrime = serde_json::from_str("2")?; +//! assert_eq!(p, SmallPrime::Two); +//! +//! Ok(()) +//! } +//! ``` + +#![recursion_limit = "128"] + +extern crate proc_macro; + +mod parse; + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; + +use crate::parse::Input; + +use std::iter; + +#[proc_macro_derive(Serialize_repr)] +pub fn derive_serialize(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as Input); + let ident = input.ident; + let repr = input.repr; + + let match_variants = input.variants.iter().map(|variant| { + let variant = &variant.ident; + quote! { + #ident::#variant => #ident::#variant as #repr, + } + }); + + TokenStream::from(quote! { + impl serde::Serialize for #ident { + fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error> + where + S: serde::Serializer + { + let value: #repr = match *self { + #(#match_variants)* + }; + serde::Serialize::serialize(&value, serializer) + } + } + }) +} + +#[proc_macro_derive(Deserialize_repr, attributes(serde))] +pub fn derive_deserialize(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as Input); + let ident = input.ident; + let repr = input.repr; + let variants = input.variants.iter().map(|variant| &variant.ident); + + let declare_discriminants = input.variants.iter().map(|variant| { + let variant = &variant.ident; + quote! { + #[allow(non_upper_case_globals)] + const #variant: #repr = #ident::#variant as #repr; + } + }); + + let match_discriminants = input.variants.iter().map(|variant| { + let variant = &variant.ident; + quote! { + discriminant::#variant => core::result::Result::Ok(#ident::#variant), + } + }); + + let error_format = match input.variants.len() { + 1 => "invalid value: {}, expected {}".to_owned(), + 2 => "invalid value: {}, expected {} or {}".to_owned(), + n => { + "invalid value: {}, expected one of: {}".to_owned() + + &iter::repeat(", {}").take(n - 1).collect::<String>() + } + }; + + let other_arm = match input.default_variant { + Some(variant) => { + let variant = &variant.ident; + quote! { + core::result::Result::Ok(#ident::#variant) + } + } + None => quote! { + core::result::Result::Err(serde::de::Error::custom( + format_args!(#error_format, other #(, discriminant::#variants)*) + )) + }, + }; + + TokenStream::from(quote! { + impl<'de> serde::Deserialize<'de> for #ident { + fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error> + where + D: serde::Deserializer<'de>, + { + struct discriminant; + + impl discriminant { + #(#declare_discriminants)* + } + + match <#repr as serde::Deserialize>::deserialize(deserializer)? { + #(#match_discriminants)* + other => #other_arm, + } + } + } + }) +} diff --git a/third_party/rust/serde_repr/src/parse.rs b/third_party/rust/serde_repr/src/parse.rs new file mode 100644 index 0000000000..2c0ad1e7dc --- /dev/null +++ b/third_party/rust/serde_repr/src/parse.rs @@ -0,0 +1,114 @@ +use proc_macro2::Span; +use syn::parse::{Error, Parse, ParseStream, Parser, Result}; +use syn::{parenthesized, Data, DeriveInput, Fields, Ident, Meta, NestedMeta}; + +pub struct Input { + pub ident: Ident, + pub repr: Ident, + pub variants: Vec<Variant>, + pub default_variant: Option<Variant>, +} + +#[derive(Clone)] +pub struct Variant { + pub ident: Ident, + pub attrs: VariantAttrs, +} + +#[derive(Clone)] +pub struct VariantAttrs { + pub is_default: bool, +} + +fn parse_meta(attrs: &mut VariantAttrs, meta: &Meta) { + if let Meta::List(value) = meta { + for meta in &value.nested { + if let NestedMeta::Meta(Meta::Path(path)) = meta { + if path.is_ident("other") { + attrs.is_default = true; + } + } + } + } +} + +fn parse_attrs(variant: &syn::Variant) -> Result<VariantAttrs> { + let mut attrs = VariantAttrs { is_default: false }; + for attr in &variant.attrs { + if attr.path.is_ident("serde") { + parse_meta(&mut attrs, &attr.parse_meta()?); + } + } + Ok(attrs) +} + +impl Parse for Input { + fn parse(input: ParseStream) -> Result<Self> { + let call_site = Span::call_site(); + let derive_input = DeriveInput::parse(input)?; + + let data = match derive_input.data { + Data::Enum(data) => data, + _ => { + return Err(Error::new(call_site, "input must be an enum")); + } + }; + + let variants = data + .variants + .into_iter() + .map(|variant| match variant.fields { + Fields::Unit => { + let attrs = parse_attrs(&variant)?; + Ok(Variant { + ident: variant.ident, + attrs, + }) + } + Fields::Named(_) | Fields::Unnamed(_) => { + Err(Error::new(variant.ident.span(), "must be a unit variant")) + } + }) + .collect::<Result<Vec<Variant>>>()?; + + if variants.is_empty() { + return Err(Error::new(call_site, "there must be at least one variant")); + } + + let generics = derive_input.generics; + if !generics.params.is_empty() || generics.where_clause.is_some() { + return Err(Error::new(call_site, "generic enum is not supported")); + } + + let mut repr = None; + for attr in derive_input.attrs { + if attr.path.is_ident("repr") { + fn repr_arg(input: ParseStream) -> Result<Ident> { + let content; + parenthesized!(content in input); + content.parse() + } + let ty = repr_arg.parse2(attr.tokens)?; + repr = Some(ty); + break; + } + } + let repr = repr.ok_or_else(|| Error::new(call_site, "missing #[repr(...)] attribute"))?; + + let mut default_variants = variants.iter().filter(|x| x.attrs.is_default); + let default_variant = default_variants.next().cloned(); + if default_variants.next().is_some() { + return Err(Error::new( + call_site, + "only one variant can be #[serde(other)]", + )); + } + + Ok(Input { + ident: derive_input.ident, + repr, + variants, + default_variant, + }) + } +} diff --git a/third_party/rust/serde_repr/tests/compiletest.rs b/third_party/rust/serde_repr/tests/compiletest.rs new file mode 100644 index 0000000000..f9aea23b51 --- /dev/null +++ b/third_party/rust/serde_repr/tests/compiletest.rs @@ -0,0 +1,6 @@ +#[rustversion::attr(not(nightly), ignore)] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/third_party/rust/serde_repr/tests/test.rs b/third_party/rust/serde_repr/tests/test.rs new file mode 100644 index 0000000000..e7e9eff558 --- /dev/null +++ b/third_party/rust/serde_repr/tests/test.rs @@ -0,0 +1,74 @@ +use serde_repr::{Deserialize_repr, Serialize_repr}; + +mod small_prime { + use super::*; + + #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] + #[repr(u8)] + enum SmallPrime { + Two = 2, + Three = 3, + Five = 5, + Seven = 7, + } + + #[test] + fn test_serialize() { + let j = serde_json::to_string(&SmallPrime::Seven).unwrap(); + assert_eq!(j, "7"); + } + + #[test] + fn test_deserialize() { + let p: SmallPrime = serde_json::from_str("2").unwrap(); + assert_eq!(p, SmallPrime::Two); + } +} + +mod other { + use super::*; + + #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] + #[repr(u8)] + enum TestOther { + A, + B, + #[serde(other, rename = "useless")] + Other, + } + + #[test] + fn test_deserialize() { + let p: TestOther = serde_json::from_str("0").unwrap(); + assert_eq!(p, TestOther::A); + let p: TestOther = serde_json::from_str("1").unwrap(); + assert_eq!(p, TestOther::B); + let p: TestOther = serde_json::from_str("5").unwrap(); + assert_eq!(p, TestOther::Other); + } +} + +mod implicit_discriminant { + use super::*; + + #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] + #[repr(u8)] + enum ImplicitDiscriminant { + Zero, + One, + Two, + Three, + } + + #[test] + fn test_serialize() { + let j = serde_json::to_string(&ImplicitDiscriminant::Three).unwrap(); + assert_eq!(j, "3"); + } + + #[test] + fn test_deserialize() { + let p: ImplicitDiscriminant = serde_json::from_str("2").unwrap(); + assert_eq!(p, ImplicitDiscriminant::Two); + } +} diff --git a/third_party/rust/serde_repr/tests/ui/empty_enum.rs b/third_party/rust/serde_repr/tests/ui/empty_enum.rs new file mode 100644 index 0000000000..f1fb6f9d56 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/empty_enum.rs @@ -0,0 +1,6 @@ +use serde_repr::Serialize_repr; + +#[derive(Serialize_repr)] +enum SmallPrime {} + +fn main() {} diff --git a/third_party/rust/serde_repr/tests/ui/empty_enum.stderr b/third_party/rust/serde_repr/tests/ui/empty_enum.stderr new file mode 100644 index 0000000000..417677be31 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/empty_enum.stderr @@ -0,0 +1,5 @@ +error: there must be at least one variant + --> $DIR/empty_enum.rs:3:10 + | +3 | #[derive(Serialize_repr)] + | ^^^^^^^^^^^^^^ diff --git a/third_party/rust/serde_repr/tests/ui/missing_repr.rs b/third_party/rust/serde_repr/tests/ui/missing_repr.rs new file mode 100644 index 0000000000..00836356b9 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/missing_repr.rs @@ -0,0 +1,11 @@ +use serde_repr::Serialize_repr; + +#[derive(Serialize_repr)] +enum SmallPrime { + Two = 2, + Three = 3, + Five = 5, + Seven = 7, +} + +fn main() {} diff --git a/third_party/rust/serde_repr/tests/ui/missing_repr.stderr b/third_party/rust/serde_repr/tests/ui/missing_repr.stderr new file mode 100644 index 0000000000..966db21506 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/missing_repr.stderr @@ -0,0 +1,5 @@ +error: missing #[repr(...)] attribute + --> $DIR/missing_repr.rs:3:10 + | +3 | #[derive(Serialize_repr)] + | ^^^^^^^^^^^^^^ diff --git a/third_party/rust/serde_repr/tests/ui/multiple_others.rs b/third_party/rust/serde_repr/tests/ui/multiple_others.rs new file mode 100644 index 0000000000..fdb552b109 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/multiple_others.rs @@ -0,0 +1,12 @@ +use serde_repr::Deserialize_repr; + +#[derive(Deserialize_repr)] +#[repr(u8)] +enum MultipleOthers { + #[serde(other)] + A, + #[serde(other)] + B, +} + +fn main() {} diff --git a/third_party/rust/serde_repr/tests/ui/multiple_others.stderr b/third_party/rust/serde_repr/tests/ui/multiple_others.stderr new file mode 100644 index 0000000000..76bf1f5653 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/multiple_others.stderr @@ -0,0 +1,5 @@ +error: only one variant can be #[serde(other)] + --> $DIR/multiple_others.rs:3:10 + | +3 | #[derive(Deserialize_repr)] + | ^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/serde_repr/tests/ui/non_unit_variant.rs b/third_party/rust/serde_repr/tests/ui/non_unit_variant.rs new file mode 100644 index 0000000000..9cdc80d0af --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/non_unit_variant.rs @@ -0,0 +1,12 @@ +use serde_repr::Serialize_repr; + +#[derive(Serialize_repr)] +#[repr(u8)] +enum SmallPrime { + Two(u8), + Three(u8), + Five(u8), + Seven(u8), +} + +fn main() {} diff --git a/third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr b/third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr new file mode 100644 index 0000000000..556f75a9a6 --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr @@ -0,0 +1,5 @@ +error: must be a unit variant + --> $DIR/non_unit_variant.rs:6:5 + | +6 | Two(u8), + | ^^^ diff --git a/third_party/rust/serde_repr/tests/ui/not_enum.rs b/third_party/rust/serde_repr/tests/ui/not_enum.rs new file mode 100644 index 0000000000..92a1d746dc --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/not_enum.rs @@ -0,0 +1,11 @@ +use serde_repr::Serialize_repr; + +#[derive(Serialize_repr)] +struct SmallPrime { + two: u8, + three: u8, + five: u8, + seven: u8, +} + +fn main() {} diff --git a/third_party/rust/serde_repr/tests/ui/not_enum.stderr b/third_party/rust/serde_repr/tests/ui/not_enum.stderr new file mode 100644 index 0000000000..882c5b0b8b --- /dev/null +++ b/third_party/rust/serde_repr/tests/ui/not_enum.stderr @@ -0,0 +1,5 @@ +error: input must be an enum + --> $DIR/not_enum.rs:3:10 + | +3 | #[derive(Serialize_repr)] + | ^^^^^^^^^^^^^^ diff --git a/third_party/rust/serde_urlencoded/.cargo-checksum.json b/third_party/rust/serde_urlencoded/.cargo-checksum.json new file mode 100644 index 0000000000..d9c93ff825 --- /dev/null +++ b/third_party/rust/serde_urlencoded/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"7f9a0ac0673db3e3894a56da2cdb7cb410075a09a1ef2162bbdc97fbe9ed73db","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"b9eb266294324f672cbe945fe8f2e32f85024f0d61a1a7d14382cdde0ac44769","README.md":"22d4c36a0b84f531cd8c254287593f6d963437cfb6df80839eb6989c240d3d7d","bors.toml":"1d8a7a56c5c76925a3daa8c50a40cc82cbfc638f521f864106bd60b1e8a219a2","rustfmt.toml":"b9eb3a50d2c594712da21780876526d5a9f79fdd2d795becaeb0f7016303006f","src/de.rs":"034b769aac212a93895cdfd72987b4f924cb6c9937ffd29cde9c1336ed5aface","src/lib.rs":"b69d313ea5c2f5f2da8b89dd0e268921ccf2d6e14d4f570e0c97ede26a8db2a8","src/ser/key.rs":"f0a4bd175b78b3127c3fbe050c22f45371c17b84968ea8a8a0a6df7847f43f5d","src/ser/mod.rs":"2d360e7e465d88bd76cbf059e7d8aa1f80bc5d66d7e91bfed0dbd80c2702819d","src/ser/pair.rs":"2ce910603e2f83a72b2789377ba27d1b66c49c6a07eff2f13f806da54ebc8bd7","src/ser/part.rs":"5b09e3c60c6eaad94f68e91e8712246d89215b94913772b3ef1e8ba3fcdda871","src/ser/value.rs":"e589e2b35e19d4f7f866bdb706686ea350c8d6a63dbe775e6433c502d27a716d","tests/test_deserialize.rs":"3f3bae6903150757f1dbaf42eeccdd2fcccba5e277bce83c7a3d0eafcc60a79e","tests/test_serialize.rs":"2bb829519c35ea9873d7cc18ebff7aa4b09f09be5a554963f4d18bc6e6c3348f"},"package":"9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"}
\ No newline at end of file diff --git a/third_party/rust/serde_urlencoded/Cargo.toml b/third_party/rust/serde_urlencoded/Cargo.toml new file mode 100644 index 0000000000..4dad7187fc --- /dev/null +++ b/third_party/rust/serde_urlencoded/Cargo.toml @@ -0,0 +1,40 @@ +# 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_urlencoded" +version = "0.6.1" +authors = ["Anthony Ramine <n.oxyde@gmail.com>"] +description = "`x-www-form-urlencoded` meets Serde" +documentation = "https://docs.rs/serde_urlencoded" +keywords = ["serde", "serialization", "urlencoded"] +categories = ["encoding", "web-programming"] +license = "MIT/Apache-2.0" +repository = "https://github.com/nox/serde_urlencoded" + +[lib] +test = false +[dependencies.dtoa] +version = "0.4.0" + +[dependencies.itoa] +version = "0.4.0" + +[dependencies.serde] +version = "1.0.0" + +[dependencies.url] +version = "2.0.0" +[dev-dependencies.serde_derive] +version = "1.0" +[badges.travis-ci] +repository = "nox/serde_urlencoded" diff --git a/third_party/rust/serde_urlencoded/LICENSE-APACHE b/third_party/rust/serde_urlencoded/LICENSE-APACHE new file mode 100644 index 0000000000..1b5ec8b78e --- /dev/null +++ b/third_party/rust/serde_urlencoded/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/third_party/rust/serde_urlencoded/LICENSE-MIT b/third_party/rust/serde_urlencoded/LICENSE-MIT new file mode 100644 index 0000000000..39f6303ad3 --- /dev/null +++ b/third_party/rust/serde_urlencoded/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2016 Anthony Ramine + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_urlencoded/README.md b/third_party/rust/serde_urlencoded/README.md new file mode 100644 index 0000000000..e55a86c217 --- /dev/null +++ b/third_party/rust/serde_urlencoded/README.md @@ -0,0 +1,50 @@ +`x-www-form-urlencoded` meets Serde +=================================== + +This crate is a Rust library for serialising to and deserialising from +the [`application/x-www-form-urlencoded`][urlencoded] format. It is built +upon [Serde], a high performance generic serialization framework and [rust-url], +a URL parser for Rust. + +[rust-url]: https://github.com/servo/rust-url +[Serde]: https://github.com/serde-rs/serde +[urlencoded]: https://url.spec.whatwg.org/#application/x-www-form-urlencoded + +Installation +============ + +This crate works with Cargo and can be found on +[crates.io] with a `Cargo.toml` like: + +```toml +[dependencies] +serde_urlencoded = "0.5.1" +``` + +[crates.io]: https://crates.io/crates/serde_urlencoded + +## Getting help + +Serde developers live in the #serde channel on +[`irc.mozilla.org`](https://wiki.mozilla.org/IRC) and most rust-url developers +live in the #servo one. The #rust channel is also a good resource with generally +faster response time but less specific knowledge about Serde, rust-url or this +crate. If IRC is not your thing, we are happy to respond to [GitHub +issues](https://github.com/nox/serde_urlencoded/issues/new) as well. + +## License + +serde_urlencoded 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_urlencoded by you, as defined in the Apache-2.0 license, +shall be dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/serde_urlencoded/bors.toml b/third_party/rust/serde_urlencoded/bors.toml new file mode 100644 index 0000000000..359f8947ba --- /dev/null +++ b/third_party/rust/serde_urlencoded/bors.toml @@ -0,0 +1 @@ +status = ["continuous-integration/travis-ci/push"] diff --git a/third_party/rust/serde_urlencoded/rustfmt.toml b/third_party/rust/serde_urlencoded/rustfmt.toml new file mode 100644 index 0000000000..2b7608b300 --- /dev/null +++ b/third_party/rust/serde_urlencoded/rustfmt.toml @@ -0,0 +1,5 @@ +match_block_trailing_comma = true +max_width = 80 +newline_style = "Unix" +reorder_imports = true +use_try_shorthand = true diff --git a/third_party/rust/serde_urlencoded/src/de.rs b/third_party/rust/serde_urlencoded/src/de.rs new file mode 100644 index 0000000000..3558f3e2be --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/de.rs @@ -0,0 +1,320 @@ +//! Deserialization support for the `application/x-www-form-urlencoded` format. + +use serde::de::value::MapDeserializer; +use serde::de::Error as de_Error; +use serde::de::{self, IntoDeserializer}; +use std::borrow::Cow; +use std::io::Read; +use url::form_urlencoded::parse; +use url::form_urlencoded::Parse as UrlEncodedParse; + +#[doc(inline)] +pub use serde::de::value::Error; + +/// Deserializes a `application/x-wwww-url-encoded` value from a `&[u8]`. +/// +/// ``` +/// let meal = vec![ +/// ("bread".to_owned(), "baguette".to_owned()), +/// ("cheese".to_owned(), "comté".to_owned()), +/// ("meat".to_owned(), "ham".to_owned()), +/// ("fat".to_owned(), "butter".to_owned()), +/// ]; +/// +/// assert_eq!( +/// serde_urlencoded::from_bytes::<Vec<(String, String)>>( +/// b"bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"), +/// Ok(meal)); +/// ``` +pub fn from_bytes<'de, T>(input: &'de [u8]) -> Result<T, Error> +where + T: de::Deserialize<'de>, +{ + T::deserialize(Deserializer::new(parse(input))) +} + +/// Deserializes a `application/x-wwww-url-encoded` value from a `&str`. +/// +/// ``` +/// let meal = vec![ +/// ("bread".to_owned(), "baguette".to_owned()), +/// ("cheese".to_owned(), "comté".to_owned()), +/// ("meat".to_owned(), "ham".to_owned()), +/// ("fat".to_owned(), "butter".to_owned()), +/// ]; +/// +/// assert_eq!( +/// serde_urlencoded::from_str::<Vec<(String, String)>>( +/// "bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"), +/// Ok(meal)); +/// ``` +pub fn from_str<'de, T>(input: &'de str) -> Result<T, Error> +where + T: de::Deserialize<'de>, +{ + from_bytes(input.as_bytes()) +} + +/// Convenience function that reads all bytes from `reader` and deserializes +/// them with `from_bytes`. +pub fn from_reader<T, R>(mut reader: R) -> Result<T, Error> +where + T: de::DeserializeOwned, + R: Read, +{ + let mut buf = vec![]; + reader.read_to_end(&mut buf).map_err(|e| { + de::Error::custom(format_args!("could not read input: {}", e)) + })?; + from_bytes(&buf) +} + +/// A deserializer for the `application/x-www-form-urlencoded` format. +/// +/// * Supported top-level outputs are structs, maps and sequences of pairs, +/// with or without a given length. +/// +/// * Main `deserialize` methods defers to `deserialize_map`. +/// +/// * Everything else but `deserialize_seq` and `deserialize_seq_fixed_size` +/// defers to `deserialize`. +pub struct Deserializer<'de> { + inner: MapDeserializer<'de, PartIterator<'de>, Error>, +} + +impl<'de> Deserializer<'de> { + /// Returns a new `Deserializer`. + pub fn new(parser: UrlEncodedParse<'de>) -> Self { + Deserializer { + inner: MapDeserializer::new(PartIterator(parser)), + } + } +} + +impl<'de> de::Deserializer<'de> for Deserializer<'de> { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.deserialize_map(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_map(self.inner) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_seq(self.inner) + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.inner.end()?; + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool + u8 + u16 + u32 + u64 + i8 + i16 + i32 + i64 + f32 + f64 + char + str + string + option + bytes + byte_buf + unit_struct + newtype_struct + tuple_struct + struct + identifier + tuple + enum + ignored_any + } +} + +struct PartIterator<'de>(UrlEncodedParse<'de>); + +impl<'de> Iterator for PartIterator<'de> { + type Item = (Part<'de>, Part<'de>); + + fn next(&mut self) -> Option<Self::Item> { + self.0.next().map(|(k, v)| (Part(k), Part(v))) + } +} + +struct Part<'de>(Cow<'de, str>); + +impl<'de> IntoDeserializer<'de> for Part<'de> { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +macro_rules! forward_parsed_value { + ($($ty:ident => $method:ident,)*) => { + $( + fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where V: de::Visitor<'de> + { + match self.0.parse::<$ty>() { + Ok(val) => val.into_deserializer().$method(visitor), + Err(e) => Err(de::Error::custom(e)) + } + } + )* + } +} + +impl<'de> de::Deserializer<'de> for Part<'de> { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match self.0 { + Cow::Borrowed(value) => visitor.visit_borrowed_str(value), + Cow::Owned(value) => visitor.visit_string(value), + } + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_some(self) + } + + fn deserialize_enum<V>( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_enum(ValueEnumAccess(self.0)) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + forward_to_deserialize_any! { + char + str + string + unit + bytes + byte_buf + unit_struct + tuple_struct + struct + identifier + tuple + ignored_any + seq + map + } + + forward_parsed_value! { + bool => deserialize_bool, + u8 => deserialize_u8, + u16 => deserialize_u16, + u32 => deserialize_u32, + u64 => deserialize_u64, + i8 => deserialize_i8, + i16 => deserialize_i16, + i32 => deserialize_i32, + i64 => deserialize_i64, + f32 => deserialize_f32, + f64 => deserialize_f64, + } +} + +struct ValueEnumAccess<'de>(Cow<'de, str>); + +impl<'de> de::EnumAccess<'de> for ValueEnumAccess<'de> { + type Error = Error; + type Variant = UnitOnlyVariantAccess; + + fn variant_seed<V>( + self, + seed: V, + ) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: de::DeserializeSeed<'de>, + { + let variant = seed.deserialize(self.0.into_deserializer())?; + Ok((variant, UnitOnlyVariantAccess)) + } +} + +struct UnitOnlyVariantAccess; + +impl<'de> de::VariantAccess<'de> for UnitOnlyVariantAccess { + type Error = Error; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + Err(Error::custom("expected unit variant")) + } + + fn tuple_variant<V>( + self, + _len: usize, + _visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + Err(Error::custom("expected unit variant")) + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + Err(Error::custom("expected unit variant")) + } +} diff --git a/third_party/rust/serde_urlencoded/src/lib.rs b/third_party/rust/serde_urlencoded/src/lib.rs new file mode 100644 index 0000000000..776ae54ab1 --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/lib.rs @@ -0,0 +1,17 @@ +//! `x-www-form-urlencoded` meets Serde + +#![warn(unused_extern_crates)] + +extern crate dtoa; +extern crate itoa; +#[macro_use] +extern crate serde; +extern crate url; + +pub mod de; +pub mod ser; + +#[doc(inline)] +pub use de::{from_bytes, from_reader, from_str, Deserializer}; +#[doc(inline)] +pub use ser::{to_string, Serializer}; diff --git a/third_party/rust/serde_urlencoded/src/ser/key.rs b/third_party/rust/serde_urlencoded/src/ser/key.rs new file mode 100644 index 0000000000..2a2e63ac03 --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/ser/key.rs @@ -0,0 +1,77 @@ +use ser::part::Sink; +use ser::Error; +use serde::Serialize; +use std::borrow::Cow; +use std::ops::Deref; + +pub enum Key<'key> { + Static(&'static str), + Dynamic(Cow<'key, str>), +} + +impl<'key> Deref for Key<'key> { + type Target = str; + + fn deref(&self) -> &str { + match *self { + Key::Static(key) => key, + Key::Dynamic(ref key) => key, + } + } +} + +impl<'key> From<Key<'key>> for Cow<'static, str> { + fn from(key: Key<'key>) -> Self { + match key { + Key::Static(key) => key.into(), + Key::Dynamic(key) => key.into_owned().into(), + } + } +} + +pub struct KeySink<End> { + end: End, +} + +impl<End, Ok> KeySink<End> +where + End: for<'key> FnOnce(Key<'key>) -> Result<Ok, Error>, +{ + pub fn new(end: End) -> Self { + KeySink { end: end } + } +} + +impl<End, Ok> Sink for KeySink<End> +where + End: for<'key> FnOnce(Key<'key>) -> Result<Ok, Error>, +{ + type Ok = Ok; + + fn serialize_static_str(self, value: &'static str) -> Result<Ok, Error> { + (self.end)(Key::Static(value)) + } + + fn serialize_str(self, value: &str) -> Result<Ok, Error> { + (self.end)(Key::Dynamic(value.into())) + } + + fn serialize_string(self, value: String) -> Result<Ok, Error> { + (self.end)(Key::Dynamic(value.into())) + } + + fn serialize_none(self) -> Result<Ok, Error> { + Err(self.unsupported()) + } + + fn serialize_some<T: ?Sized + Serialize>( + self, + _value: &T, + ) -> Result<Ok, Error> { + Err(self.unsupported()) + } + + fn unsupported(self) -> Error { + Error::Custom("unsupported key".into()) + } +} diff --git a/third_party/rust/serde_urlencoded/src/ser/mod.rs b/third_party/rust/serde_urlencoded/src/ser/mod.rs new file mode 100644 index 0000000000..598b3a4dff --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/ser/mod.rs @@ -0,0 +1,538 @@ +//! Serialization support for the `application/x-www-form-urlencoded` format. + +mod key; +mod pair; +mod part; +mod value; + +use serde::ser; +use std::borrow::Cow; +use std::error; +use std::fmt; +use std::str; +use url::form_urlencoded::Serializer as UrlEncodedSerializer; +use url::form_urlencoded::Target as UrlEncodedTarget; + +/// Serializes a value into a `application/x-wwww-url-encoded` `String` buffer. +/// +/// ``` +/// let meal = &[ +/// ("bread", "baguette"), +/// ("cheese", "comté"), +/// ("meat", "ham"), +/// ("fat", "butter"), +/// ]; +/// +/// assert_eq!( +/// serde_urlencoded::to_string(meal), +/// Ok("bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter".to_owned())); +/// ``` +pub fn to_string<T: ser::Serialize>(input: T) -> Result<String, Error> { + let mut urlencoder = UrlEncodedSerializer::new("".to_owned()); + input.serialize(Serializer::new(&mut urlencoder))?; + Ok(urlencoder.finish()) +} + +/// A serializer for the `application/x-www-form-urlencoded` format. +/// +/// * Supported top-level inputs are structs, maps and sequences of pairs, +/// with or without a given length. +/// +/// * Supported keys and values are integers, bytes (if convertible to strings), +/// unit structs and unit variants. +/// +/// * Newtype structs defer to their inner values. +pub struct Serializer<'input, 'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<'input, Target>, +} + +impl<'input, 'output, Target: 'output + UrlEncodedTarget> Serializer<'input, 'output, Target> { + /// Returns a new `Serializer`. + pub fn new(urlencoder: &'output mut UrlEncodedSerializer<'input, Target>) -> Self { + Serializer { + urlencoder: urlencoder, + } + } +} + +/// Errors returned during serializing to `application/x-www-form-urlencoded`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Error { + Custom(Cow<'static, str>), + Utf8(str::Utf8Error), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::Custom(ref msg) => msg.fmt(f), + Error::Utf8(ref err) => write!(f, "invalid UTF-8: {}", err), + } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + match *self { + Error::Custom(ref msg) => msg, + Error::Utf8(ref err) => error::Error::description(err), + } + } + + /// The lower-level cause of this error, in the case of a `Utf8` error. + fn cause(&self) -> Option<&error::Error> { + match *self { + Error::Custom(_) => None, + Error::Utf8(ref err) => Some(err), + } + } +} + +impl ser::Error for Error { + fn custom<T: fmt::Display>(msg: T) -> Self { + Error::Custom(format!("{}", msg).into()) + } +} + +/// Sequence serializer. +pub struct SeqSerializer<'input, 'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<'input, Target>, +} + +/// Tuple serializer. +/// +/// Mostly used for arrays. +pub struct TupleSerializer<'input, 'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<'input, Target>, +} + +/// Tuple struct serializer. +/// +/// Never instantiated, tuple structs are not supported. +pub struct TupleStructSerializer<'input, 'output, T: 'output + UrlEncodedTarget> { + inner: ser::Impossible<&'output mut UrlEncodedSerializer<'input, T>, Error>, +} + +/// Tuple variant serializer. +/// +/// Never instantiated, tuple variants are not supported. +pub struct TupleVariantSerializer<'input, 'output, T: 'output + UrlEncodedTarget> { + inner: ser::Impossible<&'output mut UrlEncodedSerializer<'input, T>, Error>, +} + +/// Map serializer. +pub struct MapSerializer<'input, 'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<'input, Target>, + key: Option<Cow<'static, str>>, +} + +/// Struct serializer. +pub struct StructSerializer<'input, 'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<'input, Target>, +} + +/// Struct variant serializer. +/// +/// Never instantiated, struct variants are not supported. +pub struct StructVariantSerializer<'input, 'output, T: 'output + UrlEncodedTarget> { + inner: ser::Impossible<&'output mut UrlEncodedSerializer<'input, T>, Error>, +} + +impl<'input, 'output, Target> ser::Serializer for Serializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + type SerializeSeq = SeqSerializer<'input, 'output, Target>; + type SerializeTuple = TupleSerializer<'input, 'output, Target>; + type SerializeTupleStruct = TupleStructSerializer<'input, 'output, Target>; + type SerializeTupleVariant = TupleVariantSerializer<'input, 'output, Target>; + type SerializeMap = MapSerializer<'input, 'output, Target>; + type SerializeStruct = StructSerializer<'input, 'output, Target>; + type SerializeStructVariant = StructVariantSerializer<'input, 'output, Target>; + + /// Returns an error. + fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_char(self, _v: char) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_str(self, _value: &str) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_unit(self) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns `Ok`. + fn serialize_unit_struct( + self, + _name: &'static str, + ) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } + + /// Returns an error. + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Serializes the inner value, ignoring the newtype name. + fn serialize_newtype_struct<T: ?Sized + ser::Serialize>( + self, + _name: &'static str, + value: &T, + ) -> Result<Self::Ok, Error> { + value.serialize(self) + } + + /// Returns an error. + fn serialize_newtype_variant<T: ?Sized + ser::Serialize>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Error> { + Err(Error::top_level()) + } + + /// Returns `Ok`. + fn serialize_none(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } + + /// Serializes the given value. + fn serialize_some<T: ?Sized + ser::Serialize>( + self, + value: &T, + ) -> Result<Self::Ok, Error> { + value.serialize(self) + } + + /// Serialize a sequence, given length (if any) is ignored. + fn serialize_seq( + self, + _len: Option<usize>, + ) -> Result<Self::SerializeSeq, Error> { + Ok(SeqSerializer { + urlencoder: self.urlencoder, + }) + } + + /// Returns an error. + fn serialize_tuple( + self, + _len: usize, + ) -> Result<Self::SerializeTuple, Error> { + Ok(TupleSerializer { + urlencoder: self.urlencoder, + }) + } + + /// Returns an error. + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Error> { + Err(Error::top_level()) + } + + /// Returns an error. + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Error> { + Err(Error::top_level()) + } + + /// Serializes a map, given length is ignored. + fn serialize_map( + self, + _len: Option<usize>, + ) -> Result<Self::SerializeMap, Error> { + Ok(MapSerializer { + urlencoder: self.urlencoder, + key: None, + }) + } + + /// Serializes a struct, given length is ignored. + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Error> { + Ok(StructSerializer { + urlencoder: self.urlencoder, + }) + } + + /// Returns an error. + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Error> { + Err(Error::top_level()) + } +} + +impl<'input, 'output, Target> ser::SerializeSeq for SeqSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_element<T: ?Sized + ser::Serialize>( + &mut self, + value: &T, + ) -> Result<(), Error> { + value.serialize(pair::PairSerializer::new(self.urlencoder)) + } + + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } +} + +impl<'input, 'output, Target> ser::SerializeTuple for TupleSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_element<T: ?Sized + ser::Serialize>( + &mut self, + value: &T, + ) -> Result<(), Error> { + value.serialize(pair::PairSerializer::new(self.urlencoder)) + } + + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } +} + +impl<'input, 'output, Target> ser::SerializeTupleStruct + for TupleStructSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>( + &mut self, + value: &T, + ) -> Result<(), Error> { + self.inner.serialize_field(value) + } + + fn end(self) -> Result<Self::Ok, Error> { + self.inner.end() + } +} + +impl<'input, 'output, Target> ser::SerializeTupleVariant + for TupleVariantSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>( + &mut self, + value: &T, + ) -> Result<(), Error> { + self.inner.serialize_field(value) + } + + fn end(self) -> Result<Self::Ok, Error> { + self.inner.end() + } +} + +impl<'input, 'output, Target> ser::SerializeMap for MapSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_entry< + K: ?Sized + ser::Serialize, + V: ?Sized + ser::Serialize, + >( + &mut self, + key: &K, + value: &V, + ) -> Result<(), Error> { + let key_sink = key::KeySink::new(|key| { + let value_sink = value::ValueSink::new(self.urlencoder, &key); + value.serialize(part::PartSerializer::new(value_sink))?; + self.key = None; + Ok(()) + }); + let entry_serializer = part::PartSerializer::new(key_sink); + key.serialize(entry_serializer) + } + + fn serialize_key<T: ?Sized + ser::Serialize>( + &mut self, + key: &T, + ) -> Result<(), Error> { + let key_sink = key::KeySink::new(|key| Ok(key.into())); + let key_serializer = part::PartSerializer::new(key_sink); + self.key = Some(key.serialize(key_serializer)?); + Ok(()) + } + + fn serialize_value<T: ?Sized + ser::Serialize>( + &mut self, + value: &T, + ) -> Result<(), Error> { + { + let key = self.key.as_ref().ok_or_else(|| Error::no_key())?; + let value_sink = value::ValueSink::new(self.urlencoder, &key); + value.serialize(part::PartSerializer::new(value_sink))?; + } + self.key = None; + Ok(()) + } + + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } +} + +impl<'input, 'output, Target> ser::SerializeStruct for StructSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Error> { + let value_sink = value::ValueSink::new(self.urlencoder, key); + value.serialize(part::PartSerializer::new(value_sink)) + } + + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } +} + +impl<'input, 'output, Target> ser::SerializeStructVariant + for StructVariantSerializer<'input, 'output, Target> +where + Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<'input, Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Error> { + self.inner.serialize_field(key, value) + } + + fn end(self) -> Result<Self::Ok, Error> { + self.inner.end() + } +} + +impl Error { + fn top_level() -> Self { + let msg = "top-level serializer supports only maps and structs"; + Error::Custom(msg.into()) + } + + fn no_key() -> Self { + let msg = "tried to serialize a value before serializing key"; + Error::Custom(msg.into()) + } +} diff --git a/third_party/rust/serde_urlencoded/src/ser/pair.rs b/third_party/rust/serde_urlencoded/src/ser/pair.rs new file mode 100644 index 0000000000..e7235e43e3 --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/ser/pair.rs @@ -0,0 +1,267 @@ +use ser::key::KeySink; +use ser::part::PartSerializer; +use ser::value::ValueSink; +use ser::Error; +use serde::ser; +use std::borrow::Cow; +use std::mem; +use url::form_urlencoded::Serializer as UrlEncodedSerializer; +use url::form_urlencoded::Target as UrlEncodedTarget; + +pub struct PairSerializer<'input, 'target, Target: 'target + UrlEncodedTarget> { + urlencoder: &'target mut UrlEncodedSerializer<'input, Target>, + state: PairState, +} + +impl<'input, 'target, Target> PairSerializer<'input, 'target, Target> +where + Target: 'target + UrlEncodedTarget, +{ + pub fn new(urlencoder: &'target mut UrlEncodedSerializer<'input, Target>) -> Self { + PairSerializer { + urlencoder: urlencoder, + state: PairState::WaitingForKey, + } + } +} + +impl<'input, 'target, Target> ser::Serializer for PairSerializer<'input, 'target, Target> +where + Target: 'target + UrlEncodedTarget, +{ + type Ok = (); + type Error = Error; + type SerializeSeq = ser::Impossible<(), Error>; + type SerializeTuple = Self; + type SerializeTupleStruct = ser::Impossible<(), Error>; + type SerializeTupleVariant = ser::Impossible<(), Error>; + type SerializeMap = ser::Impossible<(), Error>; + type SerializeStruct = ser::Impossible<(), Error>; + type SerializeStructVariant = ser::Impossible<(), Error>; + + fn serialize_bool(self, _v: bool) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_i8(self, _v: i8) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_i16(self, _v: i16) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_i32(self, _v: i32) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_i64(self, _v: i64) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_u8(self, _v: u8) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_u16(self, _v: u16) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_u32(self, _v: u32) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_u64(self, _v: u64) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_f32(self, _v: f32) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_f64(self, _v: f64) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_char(self, _v: char) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_str(self, _value: &str) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_unit(self) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_newtype_struct<T: ?Sized + ser::Serialize>( + self, + _name: &'static str, + value: &T, + ) -> Result<(), Error> { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized + ser::Serialize>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<(), Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_none(self) -> Result<(), Error> { + Ok(()) + } + + fn serialize_some<T: ?Sized + ser::Serialize>( + self, + value: &T, + ) -> Result<(), Error> { + value.serialize(self) + } + + fn serialize_seq( + self, + _len: Option<usize>, + ) -> Result<Self::SerializeSeq, Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_tuple(self, len: usize) -> Result<Self, Error> { + if len == 2 { + Ok(self) + } else { + Err(Error::unsupported_pair()) + } + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_map( + self, + _len: Option<usize>, + ) -> Result<Self::SerializeMap, Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Error> { + Err(Error::unsupported_pair()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Error> { + Err(Error::unsupported_pair()) + } +} + +impl<'input, 'target, Target> ser::SerializeTuple for PairSerializer<'input, 'target, Target> +where + Target: 'target + UrlEncodedTarget, +{ + type Ok = (); + type Error = Error; + + fn serialize_element<T: ?Sized + ser::Serialize>( + &mut self, + value: &T, + ) -> Result<(), Error> { + match mem::replace(&mut self.state, PairState::Done) { + PairState::WaitingForKey => { + let key_sink = KeySink::new(|key| Ok(key.into())); + let key_serializer = PartSerializer::new(key_sink); + self.state = PairState::WaitingForValue { + key: value.serialize(key_serializer)?, + }; + Ok(()) + }, + PairState::WaitingForValue { key } => { + let result = { + let value_sink = ValueSink::new(self.urlencoder, &key); + let value_serializer = PartSerializer::new(value_sink); + value.serialize(value_serializer) + }; + if result.is_ok() { + self.state = PairState::Done; + } else { + self.state = PairState::WaitingForValue { key: key }; + } + result + }, + PairState::Done => Err(Error::done()), + } + } + + fn end(self) -> Result<(), Error> { + if let PairState::Done = self.state { + Ok(()) + } else { + Err(Error::not_done()) + } + } +} + +enum PairState { + WaitingForKey, + WaitingForValue { key: Cow<'static, str> }, + Done, +} + +impl Error { + fn done() -> Self { + Error::Custom("this pair has already been serialized".into()) + } + + fn not_done() -> Self { + Error::Custom("this pair has not yet been serialized".into()) + } + + fn unsupported_pair() -> Self { + Error::Custom("unsupported pair".into()) + } +} diff --git a/third_party/rust/serde_urlencoded/src/ser/part.rs b/third_party/rust/serde_urlencoded/src/ser/part.rs new file mode 100644 index 0000000000..f72846cc00 --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/ser/part.rs @@ -0,0 +1,232 @@ +use dtoa; +use itoa; +use ser::Error; +use serde::ser; +use std::str; + +pub struct PartSerializer<S> { + sink: S, +} + +impl<S: Sink> PartSerializer<S> { + pub fn new(sink: S) -> Self { + PartSerializer { sink: sink } + } +} + +pub trait Sink: Sized { + type Ok; + + fn serialize_static_str( + self, + value: &'static str, + ) -> Result<Self::Ok, Error>; + + fn serialize_str(self, value: &str) -> Result<Self::Ok, Error>; + fn serialize_string(self, value: String) -> Result<Self::Ok, Error>; + fn serialize_none(self) -> Result<Self::Ok, Error>; + + fn serialize_some<T: ?Sized + ser::Serialize>( + self, + value: &T, + ) -> Result<Self::Ok, Error>; + + fn unsupported(self) -> Error; +} + +impl<S: Sink> ser::Serializer for PartSerializer<S> { + type Ok = S::Ok; + type Error = Error; + type SerializeSeq = ser::Impossible<S::Ok, Error>; + type SerializeTuple = ser::Impossible<S::Ok, Error>; + type SerializeTupleStruct = ser::Impossible<S::Ok, Error>; + type SerializeTupleVariant = ser::Impossible<S::Ok, Error>; + type SerializeMap = ser::Impossible<S::Ok, Error>; + type SerializeStruct = ser::Impossible<S::Ok, Error>; + type SerializeStructVariant = ser::Impossible<S::Ok, Error>; + + fn serialize_bool(self, v: bool) -> Result<S::Ok, Error> { + self.sink + .serialize_static_str(if v { "true" } else { "false" }) + } + + fn serialize_i8(self, v: i8) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_i16(self, v: i16) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_i32(self, v: i32) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_i64(self, v: i64) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_u8(self, v: u8) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_u16(self, v: u16) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_u32(self, v: u32) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_u64(self, v: u64) -> Result<S::Ok, Error> { + self.serialize_integer(v) + } + + fn serialize_f32(self, v: f32) -> Result<S::Ok, Error> { + self.serialize_floating(v) + } + + fn serialize_f64(self, v: f64) -> Result<S::Ok, Error> { + self.serialize_floating(v) + } + + fn serialize_char(self, v: char) -> Result<S::Ok, Error> { + self.sink.serialize_string(v.to_string()) + } + + fn serialize_str(self, value: &str) -> Result<S::Ok, Error> { + self.sink.serialize_str(value) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<S::Ok, Error> { + match str::from_utf8(value) { + Ok(value) => self.sink.serialize_str(value), + Err(err) => Err(Error::Utf8(err)), + } + } + + fn serialize_unit(self) -> Result<S::Ok, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result<S::Ok, Error> { + self.sink.serialize_static_str(name.into()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<S::Ok, Error> { + self.sink.serialize_static_str(variant.into()) + } + + fn serialize_newtype_struct<T: ?Sized + ser::Serialize>( + self, + _name: &'static str, + value: &T, + ) -> Result<S::Ok, Error> { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized + ser::Serialize>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<S::Ok, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_none(self) -> Result<S::Ok, Error> { + self.sink.serialize_none() + } + + fn serialize_some<T: ?Sized + ser::Serialize>( + self, + value: &T, + ) -> Result<S::Ok, Error> { + self.sink.serialize_some(value) + } + + fn serialize_seq( + self, + _len: Option<usize>, + ) -> Result<Self::SerializeSeq, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_tuple( + self, + _len: usize, + ) -> Result<Self::SerializeTuple, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTuple, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_map( + self, + _len: Option<usize>, + ) -> Result<Self::SerializeMap, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Error> { + Err(self.sink.unsupported()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Error> { + Err(self.sink.unsupported()) + } +} + +impl<S: Sink> PartSerializer<S> { + fn serialize_integer<I>(self, value: I) -> Result<S::Ok, Error> + where + I: itoa::Integer, + { + let mut buf = [b'\0'; 20]; + let len = itoa::write(&mut buf[..], value).unwrap(); + let part = unsafe { str::from_utf8_unchecked(&buf[0..len]) }; + ser::Serializer::serialize_str(self, part) + } + + fn serialize_floating<F>(self, value: F) -> Result<S::Ok, Error> + where + F: dtoa::Floating, + { + let mut buf = [b'\0'; 24]; + let len = dtoa::write(&mut buf[..], value).unwrap(); + let part = unsafe { str::from_utf8_unchecked(&buf[0..len]) }; + ser::Serializer::serialize_str(self, part) + } +} diff --git a/third_party/rust/serde_urlencoded/src/ser/value.rs b/third_party/rust/serde_urlencoded/src/ser/value.rs new file mode 100644 index 0000000000..fc12076ae0 --- /dev/null +++ b/third_party/rust/serde_urlencoded/src/ser/value.rs @@ -0,0 +1,64 @@ +use ser::part::{PartSerializer, Sink}; +use ser::Error; +use serde::ser::Serialize; +use std::str; +use url::form_urlencoded::Serializer as UrlEncodedSerializer; +use url::form_urlencoded::Target as UrlEncodedTarget; + +pub struct ValueSink<'input, 'key, 'target, Target> +where + Target: 'target + UrlEncodedTarget, +{ + urlencoder: &'target mut UrlEncodedSerializer<'input, Target>, + key: &'key str, +} + +impl<'input, 'key, 'target, Target> ValueSink<'input, 'key, 'target, Target> +where + Target: 'target + UrlEncodedTarget, +{ + pub fn new( + urlencoder: &'target mut UrlEncodedSerializer<'input, Target>, + key: &'key str, + ) -> Self { + ValueSink { + urlencoder: urlencoder, + key: key, + } + } +} + +impl<'input, 'key, 'target, Target> Sink for ValueSink<'input, 'key, 'target, Target> +where + Target: 'target + UrlEncodedTarget, +{ + type Ok = (); + + fn serialize_str(self, value: &str) -> Result<(), Error> { + self.urlencoder.append_pair(self.key, value); + Ok(()) + } + + fn serialize_static_str(self, value: &'static str) -> Result<(), Error> { + self.serialize_str(value) + } + + fn serialize_string(self, value: String) -> Result<(), Error> { + self.serialize_str(&value) + } + + fn serialize_none(self) -> Result<Self::Ok, Error> { + Ok(()) + } + + fn serialize_some<T: ?Sized + Serialize>( + self, + value: &T, + ) -> Result<Self::Ok, Error> { + value.serialize(PartSerializer::new(self)) + } + + fn unsupported(self) -> Error { + Error::Custom("unsupported value".into()) + } +} diff --git a/third_party/rust/serde_urlencoded/tests/test_deserialize.rs b/third_party/rust/serde_urlencoded/tests/test_deserialize.rs new file mode 100644 index 0000000000..6910599547 --- /dev/null +++ b/third_party/rust/serde_urlencoded/tests/test_deserialize.rs @@ -0,0 +1,85 @@ +extern crate serde_urlencoded; +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize, Debug, PartialEq)] +struct NewType<T>(T); + +#[test] +fn deserialize_newtype_i32() { + let result = vec![("field".to_owned(), NewType(11))]; + + assert_eq!(serde_urlencoded::from_str("field=11"), Ok(result)); +} + +#[test] +fn deserialize_bytes() { + let result = vec![("first".to_owned(), 23), ("last".to_owned(), 42)]; + + assert_eq!( + serde_urlencoded::from_bytes(b"first=23&last=42"), + Ok(result) + ); +} + +#[test] +fn deserialize_str() { + let result = vec![("first".to_owned(), 23), ("last".to_owned(), 42)]; + + assert_eq!(serde_urlencoded::from_str("first=23&last=42"), Ok(result)); +} + +#[test] +fn deserialize_borrowed_str() { + let result = vec![("first", 23), ("last", 42)]; + + assert_eq!(serde_urlencoded::from_str("first=23&last=42"), Ok(result)); +} + +#[test] +fn deserialize_reader() { + let result = vec![("first".to_owned(), 23), ("last".to_owned(), 42)]; + + assert_eq!( + serde_urlencoded::from_reader(b"first=23&last=42" as &[_]), + Ok(result) + ); +} + +#[test] +fn deserialize_option() { + let result = vec![ + ("first".to_owned(), Some(23)), + ("last".to_owned(), Some(42)), + ]; + assert_eq!(serde_urlencoded::from_str("first=23&last=42"), Ok(result)); +} + +#[test] +fn deserialize_unit() { + assert_eq!(serde_urlencoded::from_str(""), Ok(())); + assert_eq!(serde_urlencoded::from_str("&"), Ok(())); + assert_eq!(serde_urlencoded::from_str("&&"), Ok(())); + assert!(serde_urlencoded::from_str::<()>("first=23").is_err()); +} + +#[derive(Deserialize, Debug, PartialEq, Eq)] +enum X { + A, + B, + C, +} + +#[test] +fn deserialize_unit_enum() { + let result = vec![ + ("one".to_owned(), X::A), + ("two".to_owned(), X::B), + ("three".to_owned(), X::C), + ]; + + assert_eq!( + serde_urlencoded::from_str("one=A&two=B&three=C"), + Ok(result) + ); +} diff --git a/third_party/rust/serde_urlencoded/tests/test_serialize.rs b/third_party/rust/serde_urlencoded/tests/test_serialize.rs new file mode 100644 index 0000000000..b0276d2ee3 --- /dev/null +++ b/third_party/rust/serde_urlencoded/tests/test_serialize.rs @@ -0,0 +1,83 @@ +extern crate serde_urlencoded; +#[macro_use] +extern crate serde_derive; + +#[derive(Serialize)] +struct NewType<T>(T); + +#[test] +fn serialize_newtype_i32() { + let params = &[("field", Some(NewType(11)))]; + assert_eq!( + serde_urlencoded::to_string(params), + Ok("field=11".to_owned()) + ); +} + +#[test] +fn serialize_option_map_int() { + let params = &[("first", Some(23)), ("middle", None), ("last", Some(42))]; + + assert_eq!( + serde_urlencoded::to_string(params), + Ok("first=23&last=42".to_owned()) + ); +} + +#[test] +fn serialize_option_map_string() { + let params = &[ + ("first", Some("hello")), + ("middle", None), + ("last", Some("world")), + ]; + + assert_eq!( + serde_urlencoded::to_string(params), + Ok("first=hello&last=world".to_owned()) + ); +} + +#[test] +fn serialize_option_map_bool() { + let params = &[("one", Some(true)), ("two", Some(false))]; + + assert_eq!( + serde_urlencoded::to_string(params), + Ok("one=true&two=false".to_owned()) + ); +} + +#[test] +fn serialize_map_bool() { + let params = &[("one", true), ("two", false)]; + + assert_eq!( + serde_urlencoded::to_string(params), + Ok("one=true&two=false".to_owned()) + ); +} + +#[derive(Serialize)] +enum X { + A, + B, + C, +} + +#[test] +fn serialize_unit_enum() { + let params = &[("one", X::A), ("two", X::B), ("three", X::C)]; + assert_eq!( + serde_urlencoded::to_string(params), + Ok("one=A&two=B&three=C".to_owned()) + ); +} + +#[derive(Serialize)] +struct Unit; + +#[test] +fn serialize_unit_struct() { + assert_eq!(serde_urlencoded::to_string(Unit), Ok("".to_owned())); +} diff --git a/third_party/rust/serde_with/.cargo-checksum.json b/third_party/rust/serde_with/.cargo-checksum.json new file mode 100644 index 0000000000..4eeae6822f --- /dev/null +++ b/third_party/rust/serde_with/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"cc6d02ac64ef3a405c8755730d7ac83311776faacfb5ac97679017faed7a9322","Cargo.toml":"d8d8ebb20c9ab9364bd4c34396475e9287a0f7e0a290acc3f1b3cadc10486e6f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"dc4c1547049c0d11d544b1347aa67f4d947d761842c373729c2014dbb337e70b","src/chrono.rs":"0ac03930e4dff3f404f1dac33e4135eb0eb860156d6986665e6f9c8be933a9c7","src/duplicate_key_impls/error_on_duplicate.rs":"5f1809d1e0285953720cb5872ad3ef30aeadab8baacf064de7afd02d492641d8","src/duplicate_key_impls/first_value_wins.rs":"c766668a3831eb808ba5b995677b266924617fcc07dd103840595eb1d16fd92d","src/duplicate_key_impls/mod.rs":"10aa3b346c0637ff944545d4875844fe71db3ba19dce4f78c0e6d5052b1cdc81","src/flatten_maybe.rs":"5cdb868eca2f43494440150942ba6995e94eed9e194322d7bdcf1e85d9a20d8c","src/json.rs":"33e3a48200e5d9537ca7f5fffc9c58e07836ba8e85d910ecb80abc246da888dd","src/lib.rs":"eb1aa53d0c04c5b1156a0588938ece37913e3c5038c1e646d6e042827ccce6c9","src/rust.rs":"de4a4f9beed67640b358c6b1ff4454c0de59aedbd7633c54a69cb121e0dfdd56","src/with_prefix.rs":"6d168b0f0034b314c1475cc1f7e89ebb9b6c3f130a2a40169a4ae37f213a7198","tests/chrono.rs":"d038fc0ea9f8cc8870e0148ad4327f9ddca0733510a4b20dd9ac449bc8e0d180","tests/rust.rs":"ac3de3639778ea5c99397386c92108ff9cfb4fb009c0d8d4fa5784711da8756a","tests/version_numbers.rs":"1920c271c281db116ca674e6a6bde4e1c09289d48f577f4f9a331ff5ce3cfa42","tests/with_prefix.rs":"c1bc8bf95d717f7becc73468d580add8e29f8a876ea3f040c09520c8bc4bc9c0"},"package":"89d3d595d64120bbbc70b7f6d5ae63298b62a3d9f373ec2f56acf5365ca8a444"}
\ No newline at end of file diff --git a/third_party/rust/serde_with/CHANGELOG.md b/third_party/rust/serde_with/CHANGELOG.md new file mode 100644 index 0000000000..99119e5e37 --- /dev/null +++ b/third_party/rust/serde_with/CHANGELOG.md @@ -0,0 +1,117 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +* Add a helper to deserialize a `Vec<u8>` from `String` (#35) +* Add `default_on_error` helper, which turns errors into `Default`s of the type +* Add `default_on_null` helper, which turns `null` values into `Default`s of the type + +### Changed + +* Bump minimal Rust version to 1.36.0 + * Support Rust Edition 2018 + * version-sync depends on smallvec which requires 1.36 +* Improved CI pipeline by running `cargo audit` and `tarpaulin` in all configurations now. + +## [1.3.1] + +### Fixed + +* Use `serde_with_macros` with proper dependencies specified. + +## [1.3.0] + +### Added + +* Add `skip_serializing_none` attribute, which adds `#[serde(skip_serializing_if = "Option::is_none")]` for each Option in a struct. + This is helpfull for APIs which have many optional fields. + The effect of can be negated by adding `serialize_always` on those fields, which should always be serialized. + Existing `skip_serializing_if` will never be modified and those fields keep their behavior. + +## [1.2.0] + +### Added + +* Add macro helper to support deserializing values with nested or flattened syntax #38 +* Serialize tuple list as map helper + +### Changed + +* Bumped minimal Rust version to 1.30.0 + +## [1.1.0] + +### Added + +* Serialize HashMap/BTreeMap as list of tuples + +## [1.0.0] + +### Added + +* No changes in this release. +* Bumped version number to indicate the stability of the library. + +## [0.2.5] + +### Added + +* Helper which deserializes an empty string as `None` and otherwise uses `FromStr` and `AsRef<str>`. + +## [0.2.4] + +### Added + +* De/Serialize sequences by using `Display` and `FromStr` implementations on each element. Contributed by @katyo + +## [0.2.3] + +### Added + +* Add missing docs and enable deny missing_docs +* Add badges to Cargo.toml and crates.io + +### Changed + +* Improve Travis configuration +* Various clippy improvements + +## [0.2.2] + +### Added + +* `unwrap_or_skip` allows to transparently serialize the inner part of a `Some(T)` +* Add deserialization helpser for sets and maps, inspired by [comment](https://github.com/serde-rs/serde/issues/553#issuecomment-299711855) + * Create an error if duplicate values for a set are detected + * Create an error if duplicate keys for a map are detected + * Implement a first-value wins strategy for sets/maps. This is different to serde's default + which implements a last value wins strategy. + +## [0.2.1] + +### Added + +* Double Option pattern to differentiate between missing, unset, or existing value +* `with_prefix!` macro, which puts a prefix on every struct field + +## [0.2.0] + +### Added + +* Add chrono support: Deserialize timestamps from int, float, and string +* Serialization of embedded JSON strings +* De/Serialization using `Display` and `FromStr` implementations +* String-based collections using `Display` and `FromStr`, allows to deserialize "#foo,#bar" + +## [0.1.0] + +### Added + +* Reserve name on crates.io diff --git a/third_party/rust/serde_with/Cargo.toml b/third_party/rust/serde_with/Cargo.toml new file mode 100644 index 0000000000..26a7ce2a6b --- /dev/null +++ b/third_party/rust/serde_with/Cargo.toml @@ -0,0 +1,73 @@ +# 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_with" +version = "1.4.0" +authors = ["jonasbb"] +exclude = [".codecov.yml", ".gitignore", ".pre-commit-config.yaml", ".travis.yml", "bors.toml", "README.tpl", "rustfmt.toml"] +description = "Custom de/serialization functions for Rust's serde" +documentation = "https://docs.rs/serde_with/" +readme = "README.md" +keywords = ["serde", "utilities", "serialization", "deserialization"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/jonasbb/serde_with" +[package.metadata.docs.rs] +all-features = true +[dependencies.chrono] +version = "0.4.1" +features = ["serde"] +optional = true + +[dependencies.serde] +version = "1.0.75" + +[dependencies.serde_json] +version = "1.0.1" +optional = true + +[dependencies.serde_with_macros] +version = "1.1.0" +optional = true +[dev-dependencies.fnv] +version = "1.0.6" + +[dev-dependencies.pretty_assertions] +version = "0.6.1" + +[dev-dependencies.ron] +version = ">=0.3.0, <0.6" + +[dev-dependencies.serde_derive] +version = "1.0.75" + +[dev-dependencies.serde_json] +version = "1.0.25" + +[dev-dependencies.version-sync] +version = "0.8.1" + +[features] +default = ["macros"] +json = ["serde_json"] +macros = ["serde_with_macros"] +[badges.codecov] +branch = "master" +repository = "jonasbb/serde_with" +service = "github" + +[badges.maintenance] +status = "actively-developed" + +[badges.travis-ci] +branch = "master" +repository = "jonasbb/serde_with" diff --git a/third_party/rust/serde_with/LICENSE-APACHE b/third_party/rust/serde_with/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_with/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/serde_with/LICENSE-MIT b/third_party/rust/serde_with/LICENSE-MIT new file mode 100644 index 0000000000..9203baa055 --- /dev/null +++ b/third_party/rust/serde_with/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2015 + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_with/README.md b/third_party/rust/serde_with/README.md new file mode 100644 index 0000000000..ac02301fe9 --- /dev/null +++ b/third_party/rust/serde_with/README.md @@ -0,0 +1,80 @@ +# Custom de/serialization functions for Rust's [serde](https://serde.rs) + +[![docs.rs badge](https://docs.rs/serde_with/badge.svg)](https://docs.rs/serde_with/) +[![crates.io badge](https://img.shields.io/crates/v/serde_with.svg)](https://crates.io/crates/serde_with/) +[![Build Status](https://travis-ci.org/jonasbb/serde_with.svg?branch=master)](https://travis-ci.org/jonasbb/serde_with) +[![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with) + +--- + +This crate provides custom de/serialization helpers to use in combination with [serde's with-annotation][with-annotation]. + +Serde tracks a wishlist of similar helpers at [serde#553]. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies.serde_with] +version = "1.4.0" +features = [ "..." ] +``` + +The crate is divided into different modules. +They contain helpers for external crates and must be enabled with the correspondig feature. + +Annotate your struct or enum to enable the custom de/serializer. + +```rust +#[derive(Deserialize, Serialize)] +struct Foo { + #[serde(with = "serde_with::rust::display_fromstr")] + bar: u8, +} +``` + +Most helpers implement both deserialize and serialize. +If you do not want to derive both, you can simply derive only the necessary parts. +If you want to mix different helpers, you can write your annotations like + +```rust +#[derive(Deserialize, Serialize)] +struct Foo { + #[serde( + deserialize_with = "serde_with::rust::display_fromstr::deserialize", + serialize_with = "serde_with::json::nested::serialize" + )] + bar: u8, +} +``` + +However, this will prohibit you from applying deserialize on the value returned by serializing a struct. + +## Attributes + +The crate comes with custom attributes, which futher extend how serde serialization can be customized. +They are enabled by default, but can be disabled, by removing the default features from this crate. + +The `serde_with` crate re-exports all items from `serde_with_macros`. +This means, if you want to use any proc_macros, import them like `use serde_with::skip_serializing_none`. + +[The documentation for the custom attributes can be found here.](serde_with_macros) + +[with-annotation]: https://serde.rs/field-attrs.html#serdewith--module +[serde#553]: https://github.com/serde-rs/serde/issues/553 + +## License + +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 the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/serde_with/src/chrono.rs b/third_party/rust/serde_with/src/chrono.rs new file mode 100644 index 0000000000..ea0118d798 --- /dev/null +++ b/third_party/rust/serde_with/src/chrono.rs @@ -0,0 +1,160 @@ +//! De/Serialization of [chrono][] types +//! +//! This modules is only available if using the `chrono` feature of the crate. +//! +//! [chrono]: https://docs.rs/chrono/ + +/// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`. +/// +/// The `DateTime<Utc>` can be serialized from an integer, a float, or a string representing a number. +/// +/// # Examples +/// +/// ``` +/// # extern crate chrono; +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use chrono::{DateTime, Utc}; +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// #[derive(Debug, Deserialize)] +/// struct S { +/// #[serde(with = "serde_with::chrono::datetime_utc_ts_seconds_from_any")] +/// date: DateTime<Utc>, +/// } +/// +/// // Deserializes integers +/// assert!(serde_json::from_str::<S>(r#"{ "date": 1478563200 }"#).is_ok()); +/// // floats +/// assert!(serde_json::from_str::<S>(r#"{ "date": 1478563200.123 }"#).is_ok()); +/// // and strings with numbers, for high-precision values +/// assert!(serde_json::from_str::<S>(r#"{ "date": "1478563200.123" }"#).is_ok()); +/// ``` +/// +pub mod datetime_utc_ts_seconds_from_any { + use chrono_crate::{DateTime, NaiveDateTime, Utc}; + use serde::de::{Deserializer, Error, Unexpected, Visitor}; + + /// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`. + pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error> + where + D: Deserializer<'de>, + { + struct Helper; + impl<'de> Visitor<'de> for Helper { + type Value = DateTime<Utc>; + + fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + formatter.write_str("Invalid timestamp. Must be an integer, float, or string with optional subsecond precision.") + } + + fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> + where + E: Error, + { + let ndt = NaiveDateTime::from_timestamp_opt(value, 0); + if let Some(ndt) = ndt { + Ok(DateTime::<Utc>::from_utc(ndt, Utc)) + } else { + Err(Error::custom(format!( + "Invalid or out of range value '{}' for DateTime", + value + ))) + } + } + + fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> + where + E: Error, + { + let ndt = NaiveDateTime::from_timestamp_opt(value as i64, 0); + if let Some(ndt) = ndt { + Ok(DateTime::<Utc>::from_utc(ndt, Utc)) + } else { + Err(Error::custom(format!( + "Invalid or out of range value '{}' for DateTime", + value + ))) + } + } + + fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> + where + E: Error, + { + let seconds = value.trunc() as i64; + let nsecs = (value.fract() * 1_000_000_000_f64).abs() as u32; + let ndt = NaiveDateTime::from_timestamp_opt(seconds, nsecs); + if let Some(ndt) = ndt { + Ok(DateTime::<Utc>::from_utc(ndt, Utc)) + } else { + Err(Error::custom(format!( + "Invalid or out of range value '{}' for DateTime", + value + ))) + } + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + let parts: Vec<_> = value.split('.').collect(); + + match *parts.as_slice() { + [seconds] => { + if let Ok(seconds) = i64::from_str_radix(seconds, 10) { + let ndt = NaiveDateTime::from_timestamp_opt(seconds, 0); + if let Some(ndt) = ndt { + Ok(DateTime::<Utc>::from_utc(ndt, Utc)) + } else { + Err(Error::custom(format!( + "Invalid or out of range value '{}' for DateTime", + value + ))) + } + } else { + Err(Error::invalid_value(Unexpected::Str(value), &self)) + } + } + [seconds, subseconds] => { + if let Ok(seconds) = i64::from_str_radix(seconds, 10) { + let subseclen = subseconds.chars().count() as u32; + if subseclen > 9 { + return Err(Error::custom(format!( + "DateTimes only support nanosecond precision but '{}' has more than 9 digits.", + value + ))); + } + + if let Ok(mut subseconds) = u32::from_str_radix(subseconds, 10) { + // convert subseconds to nanoseconds (10^-9), require 9 places for nanoseconds + subseconds *= 10u32.pow(9 - subseclen); + let ndt = NaiveDateTime::from_timestamp_opt(seconds, subseconds); + if let Some(ndt) = ndt { + Ok(DateTime::<Utc>::from_utc(ndt, Utc)) + } else { + Err(Error::custom(format!( + "Invalid or out of range value '{}' for DateTime", + value + ))) + } + } else { + Err(Error::invalid_value(Unexpected::Str(value), &self)) + } + } else { + Err(Error::invalid_value(Unexpected::Str(value), &self)) + } + } + + _ => Err(Error::invalid_value(Unexpected::Str(value), &self)), + } + } + } + + deserializer.deserialize_any(Helper) + } +} diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs b/third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs new file mode 100644 index 0000000000..3fc08e8c57 --- /dev/null +++ b/third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs @@ -0,0 +1,86 @@ +use std::{ + collections::{BTreeMap, BTreeSet, HashMap, HashSet}, + hash::{BuildHasher, Hash}, +}; + +pub trait PreventDuplicateInsertsSet<T> { + fn new(size_hint: Option<usize>) -> Self; + + /// Return true if the insert was successful and the value did not exist in the set + fn insert(&mut self, value: T) -> bool; +} + +pub trait PreventDuplicateInsertsMap<K, V> { + fn new(size_hint: Option<usize>) -> Self; + + /// Return true if the insert was successful and the key did not exist in the map + fn insert(&mut self, key: K, value: V) -> bool; +} + +impl<T, S> PreventDuplicateInsertsSet<T> for HashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher + Default, +{ + #[inline] + fn new(size_hint: Option<usize>) -> Self { + match size_hint { + Some(size) => Self::with_capacity_and_hasher(size, S::default()), + None => Self::with_hasher(S::default()), + } + } + + #[inline] + fn insert(&mut self, value: T) -> bool { + self.insert(value) + } +} + +impl<T> PreventDuplicateInsertsSet<T> for BTreeSet<T> +where + T: Ord, +{ + #[inline] + fn new(_size_hint: Option<usize>) -> Self { + Self::new() + } + + #[inline] + fn insert(&mut self, value: T) -> bool { + self.insert(value) + } +} + +impl<K, V, S> PreventDuplicateInsertsMap<K, V> for HashMap<K, V, S> +where + K: Eq + Hash, + S: BuildHasher + Default, +{ + #[inline] + fn new(size_hint: Option<usize>) -> Self { + match size_hint { + Some(size) => Self::with_capacity_and_hasher(size, S::default()), + None => Self::with_hasher(S::default()), + } + } + + #[inline] + fn insert(&mut self, key: K, value: V) -> bool { + self.insert(key, value).is_none() + } +} + +impl<K, V> PreventDuplicateInsertsMap<K, V> for BTreeMap<K, V> +where + K: Ord, +{ + #[inline] + fn new(_size_hint: Option<usize>) -> Self { + Self::new() + } + + #[inline] + fn insert(&mut self, key: K, value: V) -> bool { + self.insert(key, value).is_none() + } +} diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs b/third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs new file mode 100644 index 0000000000..e60ee9227a --- /dev/null +++ b/third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs @@ -0,0 +1,104 @@ +use std::{ + collections::{BTreeMap, BTreeSet, HashMap, HashSet}, + hash::{BuildHasher, Hash}, +}; + +pub trait DuplicateInsertsFirstWinsSet<T> { + fn new(size_hint: Option<usize>) -> Self; + + /// Insert the value into the set, if there is not already an existing value + fn insert(&mut self, value: T); +} + +pub trait DuplicateInsertsFirstWinsMap<K, V> { + fn new(size_hint: Option<usize>) -> Self; + + /// Insert the value into the map, if there is not already an existing value + fn insert(&mut self, key: K, value: V); +} + +impl<T, S> DuplicateInsertsFirstWinsSet<T> for HashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher + Default, +{ + #[inline] + fn new(size_hint: Option<usize>) -> Self { + match size_hint { + Some(size) => Self::with_capacity_and_hasher(size, S::default()), + None => Self::with_hasher(S::default()), + } + } + + #[inline] + fn insert(&mut self, value: T) { + // Hashset already fullfils the contract and always keeps the first value + self.insert(value); + } +} + +impl<T> DuplicateInsertsFirstWinsSet<T> for BTreeSet<T> +where + T: Ord, +{ + #[inline] + fn new(_size_hint: Option<usize>) -> Self { + Self::new() + } + + #[inline] + fn insert(&mut self, value: T) { + // BTreeSet already fullfils the contract and always keeps the first value + self.insert(value); + } +} + +impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for HashMap<K, V, S> +where + K: Eq + Hash, + S: BuildHasher + Default, +{ + #[inline] + fn new(size_hint: Option<usize>) -> Self { + match size_hint { + Some(size) => Self::with_capacity_and_hasher(size, S::default()), + None => Self::with_hasher(S::default()), + } + } + + #[inline] + fn insert(&mut self, key: K, value: V) { + use std::collections::hash_map::Entry; + + match self.entry(key) { + // we want to keep the first value, so do nothing + Entry::Occupied(_) => {} + Entry::Vacant(vacant) => { + vacant.insert(value); + } + } + } +} + +impl<K, V> DuplicateInsertsFirstWinsMap<K, V> for BTreeMap<K, V> +where + K: Ord, +{ + #[inline] + fn new(_size_hint: Option<usize>) -> Self { + Self::new() + } + + #[inline] + fn insert(&mut self, key: K, value: V) { + use std::collections::btree_map::Entry; + + match self.entry(key) { + // we want to keep the first value, so do nothing + Entry::Occupied(_) => {} + Entry::Vacant(vacant) => { + vacant.insert(value); + } + } + } +} diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/mod.rs b/third_party/rust/serde_with/src/duplicate_key_impls/mod.rs new file mode 100644 index 0000000000..e433baa0ac --- /dev/null +++ b/third_party/rust/serde_with/src/duplicate_key_impls/mod.rs @@ -0,0 +1,7 @@ +mod error_on_duplicate; +mod first_value_wins; + +pub use self::{ + error_on_duplicate::{PreventDuplicateInsertsMap, PreventDuplicateInsertsSet}, + first_value_wins::{DuplicateInsertsFirstWinsMap, DuplicateInsertsFirstWinsSet}, +}; diff --git a/third_party/rust/serde_with/src/flatten_maybe.rs b/third_party/rust/serde_with/src/flatten_maybe.rs new file mode 100644 index 0000000000..6ea64ed4fd --- /dev/null +++ b/third_party/rust/serde_with/src/flatten_maybe.rs @@ -0,0 +1,86 @@ +/// Support deserializing from flattened and non-flattened representation +/// +/// When working with different serialization formats, sometimes it is more idiomatic to flatten +/// fields, while other formats prefer nesting. Using `#[serde(flatten)]` only the flattened form +/// is supported. +/// +/// This helper creates a function, which support deserializing from either the flattened or the +/// nested form. It gives an error, when both forms are provided. The `flatten` attribute is +/// required on the field such that the helper works. The serialization format will always be +/// flattened. +/// +/// # Examples +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_json; +/// # #[macro_use] +/// # extern crate serde_with; +/// # +/// # use serde::Deserialize; +/// # +/// // Setup the types +/// #[derive(Deserialize, Debug)] +/// struct S { +/// #[serde(flatten, deserialize_with = "deserialize_t")] +/// t: T, +/// } +/// +/// #[derive(Deserialize, Debug)] +/// struct T { +/// i: i32, +/// } +/// +/// // The macro creates custom deserialization code. +/// // You need to specify a function name and the field name of the flattened field. +/// flattened_maybe!(deserialize_t, "t"); +/// +/// +/// # fn main() { +/// // Supports both flattened +/// let j = r#" {"i":1} "#; +/// assert!(serde_json::from_str::<S>(j).is_ok()); +/// +/// // and non-flattened versions. +/// let j = r#" {"t":{"i":1}} "#; +/// assert!(serde_json::from_str::<S>(j).is_ok()); +/// +/// // Ensure that the value is given +/// let j = r#" {} "#; +/// assert!(serde_json::from_str::<S>(j).is_err()); +/// +/// // and only occurs once, not multiple times. +/// let j = r#" {"i":1,"t":{"i":1}} "#; +/// assert!(serde_json::from_str::<S>(j).is_err()); +/// # } +/// ``` +#[macro_export] +macro_rules! flattened_maybe { + // TODO Change $field to literal, once the compiler version is bumped enough. + ($fn:ident, $field:expr) => { + fn $fn<'de, T, D>(deserializer: D) -> Result<T, D::Error> + where + T: serde::Deserialize<'de>, + D: serde::Deserializer<'de>, + { + #[derive(serde::Deserialize)] + struct Both<T> { + #[serde(flatten)] + flat: Option<T>, + #[serde(rename = $field)] + not_flat: Option<T>, + } + + let both: Both<T> = serde::Deserialize::deserialize(deserializer)?; + match (both.flat, both.not_flat) { + (Some(t), None) | (None, Some(t)) => Ok(t), + (None, None) => Err(serde::de::Error::missing_field($field)), + (Some(_), Some(_)) => Err(serde::de::Error::custom(concat!( + "`", + $field, + "` is both flattened and not" + ))), + } + } + }; +} diff --git a/third_party/rust/serde_with/src/json.rs b/third_party/rust/serde_with/src/json.rs new file mode 100644 index 0000000000..9123713856 --- /dev/null +++ b/third_party/rust/serde_with/src/json.rs @@ -0,0 +1,88 @@ +//! De/Serialization of JSON +//! +//! This modules is only available if using the `json` feature of the crate. + +/// Serialize value as string containing JSON +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::json::nested")] +/// other_struct: B, +/// } +/// #[derive(Deserialize, Serialize)] +/// struct B { +/// value: usize, +/// } +/// +/// let v: A = serde_json::from_str(r#"{"other_struct":"{\"value\":5}"}"#).unwrap(); +/// assert_eq!(5, v.other_struct.value); +/// +/// let x = A { +/// other_struct: B { value: 10 }, +/// }; +/// assert_eq!(r#"{"other_struct":"{\"value\":10}"}"#, serde_json::to_string(&x).unwrap()); +/// ``` +/// +pub mod nested { + use serde::{ + de::{DeserializeOwned, Deserializer, Error, Visitor}, + ser::{self, Serialize, Serializer}, + }; + use serde_json; + use std::{fmt, marker::PhantomData}; + + /// Deserialize value from a string which is valid JSON + pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + T: DeserializeOwned, + { + #[derive(Default)] + struct Helper<S: DeserializeOwned>(PhantomData<S>); + + impl<'de, S> Visitor<'de> for Helper<S> + where + S: DeserializeOwned, + { + type Value = S; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "valid json object") + } + + fn visit_str<E>(self, value: &str) -> Result<S, E> + where + E: Error, + { + serde_json::from_str(value).map_err(Error::custom) + } + } + + deserializer.deserialize_str(Helper(PhantomData)) + } + + /// Serialize value as string containing JSON + /// + /// # Errors + /// + /// Serialization can fail if `T`'s implementation of `Serialize` decides to + /// fail, or if `T` contains a map with non-string keys. + pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error> + where + T: Serialize, + S: Serializer, + { + let s = serde_json::to_string(value).map_err(ser::Error::custom)?; + serializer.serialize_str(&*s) + } +} diff --git a/third_party/rust/serde_with/src/lib.rs b/third_party/rust/serde_with/src/lib.rs new file mode 100644 index 0000000000..5856a0d339 --- /dev/null +++ b/third_party/rust/serde_with/src/lib.rs @@ -0,0 +1,140 @@ +#![deny( + missing_debug_implementations, + missing_copy_implementations, + missing_docs, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_import_braces, + unused_qualifications, + variant_size_differences +)] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] +#![doc(html_root_url = "https://docs.rs/serde_with/1.4.0")] + +//! [![docs.rs badge](https://docs.rs/serde_with/badge.svg)](https://docs.rs/serde_with/) +//! [![crates.io badge](https://img.shields.io/crates/v/serde_with.svg)](https://crates.io/crates/serde_with/) +//! [![Build Status](https://travis-ci.org/jonasbb/serde_with.svg?branch=master)](https://travis-ci.org/jonasbb/serde_with) +//! [![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with) +//! +//! --- +//! +//! This crate provides custom de/serialization helpers to use in combination with [serde's with-annotation][with-annotation]. +//! +//! Serde tracks a wishlist of similar helpers at [serde#553]. +//! +//! # Usage +//! +//! Add this to your `Cargo.toml`: +//! +//! ```toml +//! [dependencies.serde_with] +//! version = "1.4.0" +//! features = [ "..." ] +//! ``` +//! +//! The crate is divided into different modules. +//! They contain helpers for external crates and must be enabled with the correspondig feature. +//! +//! Annotate your struct or enum to enable the custom de/serializer. +//! +//! ```rust +//! # extern crate serde; +//! # extern crate serde_derive; +//! # extern crate serde_with; +//! # use serde_derive::{Deserialize, Serialize}; +//! #[derive(Deserialize, Serialize)] +//! struct Foo { +//! #[serde(with = "serde_with::rust::display_fromstr")] +//! bar: u8, +//! } +//! # fn main() {} +//! ``` +//! +//! Most helpers implement both deserialize and serialize. +//! If you do not want to derive both, you can simply derive only the necessary parts. +//! If you want to mix different helpers, you can write your annotations like +//! +//! ```rust +//! # extern crate serde; +//! # extern crate serde_derive; +//! # extern crate serde_with; +//! # use serde_derive::{Deserialize, Serialize}; +//! # #[cfg(feature = "json")] +//! #[derive(Deserialize, Serialize)] +//! struct Foo { +//! #[serde( +//! deserialize_with = "serde_with::rust::display_fromstr::deserialize", +//! serialize_with = "serde_with::json::nested::serialize" +//! )] +//! bar: u8, +//! } +//! # fn main() {} +//! ``` +//! +//! However, this will prohibit you from applying deserialize on the value returned by serializing a struct. +//! +//! # Attributes +//! +//! The crate comes with custom attributes, which futher extend how serde serialization can be customized. +//! They are enabled by default, but can be disabled, by removing the default features from this crate. +//! +//! The `serde_with` crate re-exports all items from `serde_with_macros`. +//! This means, if you want to use any proc_macros, import them like `use serde_with::skip_serializing_none`. +//! +//! [The documentation for the custom attributes can be found here.](serde_with_macros) +//! +//! [with-annotation]: https://serde.rs/field-attrs.html#serdewith--module +//! [serde#553]: https://github.com/serde-rs/serde/issues/553 + +#[cfg(feature = "chrono")] +extern crate chrono as chrono_crate; +#[doc(hidden)] +pub extern crate serde; +#[cfg(feature = "json")] +extern crate serde_json; +#[cfg(feature = "macros")] +extern crate serde_with_macros; + +#[cfg(feature = "chrono")] +pub mod chrono; +mod duplicate_key_impls; +mod flatten_maybe; +#[cfg(feature = "json")] +pub mod json; +pub mod rust; +#[doc(hidden)] +pub mod with_prefix; + +// Re-Export all proc_macros, as these should be seen as part of the serde_with crate +#[cfg(feature = "macros")] +#[doc(inline)] +pub use serde_with_macros::*; + +/// Separator for string-based collection de/serialization +pub trait Separator { + /// Return the string delimiting two elements in the string-based collection + fn separator() -> &'static str; +} + +/// Predefined separator using a single space +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] +pub struct SpaceSeparator; + +impl Separator for SpaceSeparator { + #[inline] + fn separator() -> &'static str { + " " + } +} + +/// Predefined separator using a single comma +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] +pub struct CommaSeparator; + +impl Separator for CommaSeparator { + #[inline] + fn separator() -> &'static str { + "," + } +} diff --git a/third_party/rust/serde_with/src/rust.rs b/third_party/rust/serde_with/src/rust.rs new file mode 100644 index 0000000000..3a984ed7e4 --- /dev/null +++ b/third_party/rust/serde_with/src/rust.rs @@ -0,0 +1,1534 @@ +//! De/Serialization for Rust's builtin and std types + +use serde::{ + de::{Deserialize, DeserializeOwned, Deserializer, Error, MapAccess, SeqAccess, Visitor}, + ser::{Serialize, SerializeMap, SerializeSeq, Serializer}, +}; +use std::{ + cmp::Eq, + collections::{BTreeMap, HashMap}, + fmt::{self, Display}, + hash::{BuildHasher, Hash}, + iter::FromIterator, + marker::PhantomData, + str::FromStr, +}; +use Separator; + +/// De/Serialize using [`Display`] and [`FromStr`] implementation +/// +/// This allows to deserialize a string as a number. +/// It can be very useful for serialization formats like JSON, which do not support integer +/// numbers and have to resort to strings to represent them. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use std::net::Ipv4Addr; +/// # +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::display_fromstr")] +/// address: Ipv4Addr, +/// #[serde(with = "serde_with::rust::display_fromstr")] +/// b: bool, +/// } +/// +/// let v: A = serde_json::from_str(r#"{ +/// "address": "192.168.2.1", +/// "b": "true" +/// }"#).unwrap(); +/// assert_eq!(Ipv4Addr::new(192, 168, 2, 1), v.address); +/// assert!(v.b); +/// +/// let x = A { +/// address: Ipv4Addr::new(127, 53, 0, 1), +/// b: false, +/// }; +/// assert_eq!(r#"{"address":"127.53.0.1","b":"false"}"#, serde_json::to_string(&x).unwrap()); +/// ``` +pub mod display_fromstr { + use super::*; + use std::str::FromStr; + + /// Deserialize T using [FromStr] + pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + T: FromStr, + T::Err: Display, + { + struct Helper<S>(PhantomData<S>); + + impl<'de, S> Visitor<'de> for Helper<S> + where + S: FromStr, + <S as FromStr>::Err: Display, + { + type Value = S; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "valid json object") + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + value.parse::<Self::Value>().map_err(Error::custom) + } + } + + deserializer.deserialize_str(Helper(PhantomData)) + } + + /// Serialize T using [Display] + pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error> + where + T: Display, + S: Serializer, + { + serializer.serialize_str(&*value.to_string()) + } +} + +/// De/Serialize sequences using [`FromIterator`] and [`IntoIterator`] implementation for it and [`Display`] and [`FromStr`] implementation for each element +/// +/// This allows to serialize and deserialize collections with elements which can be represented as strings. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// use std::collections::BTreeSet; +/// use std::net::Ipv4Addr; +/// +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::seq_display_fromstr")] +/// addresses: BTreeSet<Ipv4Addr>, +/// #[serde(with = "serde_with::rust::seq_display_fromstr")] +/// bs: Vec<bool>, +/// } +/// +/// let v: A = serde_json::from_str(r#"{ +/// "addresses": ["192.168.2.1", "192.168.2.2", "192.168.1.1", "192.168.2.2"], +/// "bs": ["true", "false"] +/// }"#).unwrap(); +/// assert_eq!(v.addresses.len(), 3); +/// assert!(v.addresses.contains(&Ipv4Addr::new(192, 168, 2, 1))); +/// assert!(v.addresses.contains(&Ipv4Addr::new(192, 168, 2, 2))); +/// assert!(!v.addresses.contains(&Ipv4Addr::new(192, 168, 1, 2))); +/// assert_eq!(v.bs.len(), 2); +/// assert!(v.bs[0]); +/// assert!(!v.bs[1]); +/// +/// let x = A { +/// addresses: vec![ +/// Ipv4Addr::new(127, 53, 0, 1), +/// Ipv4Addr::new(127, 53, 1, 1), +/// Ipv4Addr::new(127, 53, 0, 2) +/// ].into_iter().collect(), +/// bs: vec![false, true], +/// }; +/// assert_eq!(r#"{"addresses":["127.53.0.1","127.53.0.2","127.53.1.1"],"bs":["false","true"]}"#, serde_json::to_string(&x).unwrap()); +/// ``` +pub mod seq_display_fromstr { + use serde::{ + de::{Deserializer, Error, SeqAccess, Visitor}, + ser::{SerializeSeq, Serializer}, + }; + use std::{ + fmt::{self, Display}, + iter::{FromIterator, IntoIterator}, + marker::PhantomData, + str::FromStr, + }; + + /// Deserialize collection T using [FromIterator] and [FromStr] for each element + pub fn deserialize<'de, D, T, I>(deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + T: FromIterator<I> + Sized, + I: FromStr, + I::Err: Display, + { + struct Helper<S>(PhantomData<S>); + + impl<'de, S> Visitor<'de> for Helper<S> + where + S: FromStr, + <S as FromStr>::Err: Display, + { + type Value = Vec<S>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a sequence") + } + + fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut values = access + .size_hint() + .map(Self::Value::with_capacity) + .unwrap_or_else(Self::Value::new); + + while let Some(value) = access.next_element::<&str>()? { + values.push(value.parse::<S>().map_err(Error::custom)?); + } + + Ok(values) + } + } + + deserializer + .deserialize_seq(Helper(PhantomData)) + .map(T::from_iter) + } + + /// Serialize collection T using [IntoIterator] and [Display] for each element + pub fn serialize<S, T, I>(value: &T, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + for<'a> &'a T: IntoIterator<Item = &'a I>, + I: Display, + { + let iter = value.into_iter(); + let (_, to) = iter.size_hint(); + let mut seq = serializer.serialize_seq(to)?; + for item in iter { + seq.serialize_element(&item.to_string())?; + } + seq.end() + } +} + +/// De/Serialize a delimited collection using [`Display`] and [`FromStr`] implementation +/// +/// You can define an arbitrary separator, by specifying a type which implements [`Separator`]. +/// Some common ones, like space and comma are already predefined and you can find them [here][Separator]. +/// +/// An empty string deserializes as an empty collection. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// use serde_with::{CommaSeparator, SpaceSeparator}; +/// use std::collections::BTreeSet; +/// +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::StringWithSeparator::<SpaceSeparator>")] +/// tags: Vec<String>, +/// #[serde(with = "serde_with::rust::StringWithSeparator::<CommaSeparator>")] +/// more_tags: BTreeSet<String>, +/// } +/// +/// let v: A = serde_json::from_str(r##"{ +/// "tags": "#hello #world", +/// "more_tags": "foo,bar,bar" +/// }"##).unwrap(); +/// assert_eq!(vec!["#hello", "#world"], v.tags); +/// assert_eq!(2, v.more_tags.len()); +/// +/// let x = A { +/// tags: vec!["1".to_string(), "2".to_string(), "3".to_string()], +/// more_tags: BTreeSet::new(), +/// }; +/// assert_eq!(r#"{"tags":"1 2 3","more_tags":""}"#, serde_json::to_string(&x).unwrap()); +/// ``` +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] +pub struct StringWithSeparator<Sep>(PhantomData<Sep>); + +impl<Sep> StringWithSeparator<Sep> +where + Sep: Separator, +{ + /// Serialize collection into a string with separator symbol + pub fn serialize<S, T, V>(values: T, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + T: IntoIterator<Item = V>, + V: Display, + { + let mut s = String::new(); + for v in values { + s.push_str(&*v.to_string()); + s.push_str(Sep::separator()); + } + serializer.serialize_str(if !s.is_empty() { + // remove trailing separator if present + &s[..s.len() - Sep::separator().len()] + } else { + &s[..] + }) + } + + /// Deserialize a collection from a string with separator symbol + pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + T: FromIterator<V>, + V: FromStr, + V::Err: Display, + { + let s = String::deserialize(deserializer)?; + if s.is_empty() { + Ok(None.into_iter().collect()) + } else { + s.split(Sep::separator()) + .map(FromStr::from_str) + .collect::<Result<_, _>>() + .map_err(Error::custom) + } + } +} + +/// Makes a distinction between a missing, unset, or existing value +/// +/// Some serialization formats make a distinction between missing fields, fields with a `null` +/// value, and existing values. One such format is JSON. By default it is not easily possible to +/// differentiate between a missing value and a field which is `null`, as they deserialize to the +/// same value. This helper changes it, by using an `Option<Option<T>>` to deserialize into. +/// +/// * `None`: Represents a missing value. +/// * `Some(None)`: Represents a `null` value. +/// * `Some(Some(value))`: Represents an existing value. +/// +/// # Examples +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// # #[derive(Debug, PartialEq, Eq)] +/// #[derive(Deserialize, Serialize)] +/// struct Doc { +/// #[serde( +/// default, // <- important for deserialization +/// skip_serializing_if = "Option::is_none", // <- important for serialization +/// with = "::serde_with::rust::double_option", +/// )] +/// a: Option<Option<u8>>, +/// } +/// // Missing Value +/// let s = r#"{}"#; +/// assert_eq!(Doc {a: None}, serde_json::from_str(s).unwrap()); +/// assert_eq!(s, serde_json::to_string(&Doc {a: None}).unwrap()); +/// +/// // Unset Value +/// let s = r#"{"a":null}"#; +/// assert_eq!(Doc {a: Some(None)}, serde_json::from_str(s).unwrap()); +/// assert_eq!(s, serde_json::to_string(&Doc {a: Some(None)}).unwrap()); +/// +/// // Existing Value +/// let s = r#"{"a":5}"#; +/// assert_eq!(Doc {a: Some(Some(5))}, serde_json::from_str(s).unwrap()); +/// assert_eq!(s, serde_json::to_string(&Doc {a: Some(Some(5))}).unwrap()); +/// ``` +#[cfg_attr(feature = "cargo-clippy", allow(option_option))] +pub mod double_option { + use super::*; + + /// Deserialize potentially non-existing optional value + pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Option<Option<T>>, D::Error> + where + T: Deserialize<'de>, + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Some) + } + + /// Serialize optional value + pub fn serialize<S, T>(values: &Option<Option<T>>, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + T: Serialize, + { + match values { + None => serializer.serialize_unit(), + Some(None) => serializer.serialize_none(), + Some(Some(v)) => serializer.serialize_some(&v), + } + } +} + +/// Serialize inner value if [`Some`]`(T)`. If [`None`], serialize the unit struct `()`. +/// +/// When used in conjunction with `skip_serializing_if = "Option::is_none"` and +/// `default`, you can build an optional value by skipping if it is [`None`], or serializing its +/// inner value if [`Some`]`(T)`. +/// +/// Not all serialization formats easily support optional values. +/// While JSON uses the [`Option`] type to represent optional values and only serializes the inner +/// part of the [`Some`]`()`, other serialization formats, such as [RON][], choose to serialize the +/// [`Some`] around a value. +/// This helper helps building a truly optional value for such serializers. +/// +/// [RON]: https://github.com/ron-rs/ron +/// +/// # Example +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # extern crate ron; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// # #[derive(Debug, Eq, PartialEq)] +/// #[derive(Deserialize, Serialize)] +/// struct Doc { +/// mandatory: usize, +/// #[serde( +/// default, // <- important for deserialization +/// skip_serializing_if = "Option::is_none", // <- important for serialization +/// with = "::serde_with::rust::unwrap_or_skip", +/// )] +/// optional: Option<usize>, +/// } +/// +/// // Transparently add/remove Some() wrapper +/// # let pretty_config = ron::ser::PrettyConfig { +/// # new_line: "\n".into(), +/// # ..Default::default() +/// # }; +/// let s = r#"( +/// mandatory: 1, +/// optional: 2, +/// )"#; +/// let v = Doc { +/// mandatory: 1, +/// optional: Some(2), +/// }; +/// assert_eq!(v, ron::de::from_str(s).unwrap()); +/// assert_eq!(s, ron::ser::to_string_pretty(&v, pretty_config).unwrap()); +/// +/// // Missing values are deserialized as `None` +/// // while `None` values are skipped during serialization. +/// # let pretty_config = ron::ser::PrettyConfig { +/// # new_line: "\n".into(), +/// # ..Default::default() +/// # }; +/// let s = r#"( +/// mandatory: 1, +/// )"#; +/// let v = Doc { +/// mandatory: 1, +/// optional: None, +/// }; +/// assert_eq!(v, ron::de::from_str(s).unwrap()); +/// assert_eq!(s, ron::ser::to_string_pretty(&v, pretty_config).unwrap()); +/// ``` +pub mod unwrap_or_skip { + use super::*; + + /// Deserialize value wrapped in Some(T) + pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error> + where + D: Deserializer<'de>, + T: DeserializeOwned, + { + T::deserialize(deserializer).map(Some) + } + + /// Serialize value if Some(T), unit struct if None + pub fn serialize<T, S>(option: &Option<T>, serializer: S) -> Result<S::Ok, S::Error> + where + T: Serialize, + S: Serializer, + { + if let Some(value) = option { + value.serialize(serializer) + } else { + ().serialize(serializer) + } + } +} + +/// Ensure no duplicate values exist in a set. +/// +/// By default serde has a last-value-wins implementation, if duplicate values for a set exist. +/// Sometimes it is desirable to know when such an event happens, as the first value is overwritten +/// and it can indicate an error in the serialized data. +/// +/// This helper returns an error if two identical values exist in a set. +/// +/// The implementation supports both the [`HashSet`] and the [`BTreeSet`] from the standard library. +/// +/// [`HashSet`]: std::collections::HashSet +/// [`BTreeSet`]: std::collections::HashSet +/// +/// # Example +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use std::{collections::HashSet, iter::FromIterator}; +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// # #[derive(Debug, Eq, PartialEq)] +/// #[derive(Deserialize)] +/// struct Doc { +/// #[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] +/// set: HashSet<usize>, +/// } +/// +/// // Sets are serialized normally, +/// let s = r#"{"set": [1, 2, 3, 4]}"#; +/// let v = Doc { +/// set: HashSet::from_iter(vec![1, 2, 3, 4]), +/// }; +/// assert_eq!(v, serde_json::from_str(s).unwrap()); +/// +/// // but create an error if duplicate values, like the `1`, exist. +/// let s = r#"{"set": [1, 2, 3, 4, 1]}"#; +/// let res: Result<Doc, _> = serde_json::from_str(s); +/// assert!(res.is_err()); +/// ``` +pub mod sets_duplicate_value_is_error { + use super::*; + use duplicate_key_impls::PreventDuplicateInsertsSet; + + /// Deserialize a set and return an error on duplicate values + pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error> + where + T: PreventDuplicateInsertsSet<V>, + V: Deserialize<'de>, + D: Deserializer<'de>, + { + struct SeqVisitor<T, V> { + marker: PhantomData<T>, + set_item_type: PhantomData<V>, + }; + + impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V> + where + T: PreventDuplicateInsertsSet<V>, + V: Deserialize<'de>, + { + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut values = Self::Value::new(access.size_hint()); + + while let Some(value) = access.next_element()? { + if !values.insert(value) { + return Err(Error::custom("invalid entry: found duplicate value")); + }; + } + + Ok(values) + } + } + + let visitor = SeqVisitor { + marker: PhantomData, + set_item_type: PhantomData, + }; + deserializer.deserialize_seq(visitor) + } +} + +/// Ensure no duplicate keys exist in a map. +/// +/// By default serde has a last-value-wins implementation, if duplicate keys for a map exist. +/// Sometimes it is desirable to know when such an event happens, as the first value is overwritten +/// and it can indicate an error in the serialized data. +/// +/// This helper returns an error if two identical keys exist in a map. +/// +/// The implementation supports both the [`HashMap`] and the [`BTreeMap`] from the standard library. +/// +/// [`HashMap`]: std::collections::HashMap +/// [`BTreeMap`]: std::collections::HashMap +/// +/// # Example +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use std::collections::HashMap; +/// # +/// # #[derive(Debug, Eq, PartialEq)] +/// #[derive(Deserialize)] +/// struct Doc { +/// #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] +/// map: HashMap<usize, usize>, +/// } +/// +/// // Maps are serialized normally, +/// let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#; +/// let mut v = Doc { +/// map: HashMap::new(), +/// }; +/// v.map.insert(1, 1); +/// v.map.insert(2, 2); +/// v.map.insert(3, 3); +/// assert_eq!(v, serde_json::from_str(s).unwrap()); +/// +/// // but create an error if duplicate keys, like the `1`, exist. +/// let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#; +/// let res: Result<Doc, _> = serde_json::from_str(s); +/// assert!(res.is_err()); +/// ``` +pub mod maps_duplicate_key_is_error { + use super::*; + use duplicate_key_impls::PreventDuplicateInsertsMap; + + /// Deserialize a map and return an error on duplicate keys + pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<T, D::Error> + where + T: PreventDuplicateInsertsMap<K, V>, + K: Deserialize<'de>, + V: Deserialize<'de>, + D: Deserializer<'de>, + { + struct MapVisitor<T, K, V> { + marker: PhantomData<T>, + map_key_type: PhantomData<K>, + map_value_type: PhantomData<V>, + }; + + impl<'de, T, K, V> Visitor<'de> for MapVisitor<T, K, V> + where + T: PreventDuplicateInsertsMap<K, V>, + K: Deserialize<'de>, + V: Deserialize<'de>, + { + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut values = Self::Value::new(access.size_hint()); + + while let Some((key, value)) = access.next_entry()? { + if !values.insert(key, value) { + return Err(Error::custom("invalid entry: found duplicate key")); + }; + } + + Ok(values) + } + } + + let visitor = MapVisitor { + marker: PhantomData, + map_key_type: PhantomData, + map_value_type: PhantomData, + }; + deserializer.deserialize_map(visitor) + } +} + +/// Ensure that the first value is taken, if duplicate values exist +/// +/// By default serde has a last-value-wins implementation, if duplicate keys for a set exist. +/// Sometimes the opposite strategy is desired. This helper implements a first-value-wins strategy. +/// +/// The implementation supports both the [`HashSet`] and the [`BTreeSet`] from the standard library. +/// +/// [`HashSet`]: std::collections::HashSet +/// [`BTreeSet`]: std::collections::HashSet +pub mod sets_first_value_wins { + use super::*; + use duplicate_key_impls::DuplicateInsertsFirstWinsSet; + + /// Deserialize a set and return an error on duplicate values + pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error> + where + T: DuplicateInsertsFirstWinsSet<V>, + V: Deserialize<'de>, + D: Deserializer<'de>, + { + struct SeqVisitor<T, V> { + marker: PhantomData<T>, + set_item_type: PhantomData<V>, + }; + + impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V> + where + T: DuplicateInsertsFirstWinsSet<V>, + V: Deserialize<'de>, + { + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut values = Self::Value::new(access.size_hint()); + + while let Some(value) = access.next_element()? { + values.insert(value); + } + + Ok(values) + } + } + + let visitor = SeqVisitor { + marker: PhantomData, + set_item_type: PhantomData, + }; + deserializer.deserialize_seq(visitor) + } +} + +/// Ensure that the first key is taken, if duplicate keys exist +/// +/// By default serde has a last-key-wins implementation, if duplicate keys for a map exist. +/// Sometimes the opposite strategy is desired. This helper implements a first-key-wins strategy. +/// +/// The implementation supports both the [`HashMap`] and the [`BTreeMap`] from the standard library. +/// +/// [`HashMap`]: std::collections::HashMap +/// [`BTreeMap`]: std::collections::HashMap +/// +/// # Example +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use std::collections::HashMap; +/// # +/// # #[derive(Debug, Eq, PartialEq)] +/// #[derive(Deserialize)] +/// struct Doc { +/// #[serde(with = "::serde_with::rust::maps_first_key_wins")] +/// map: HashMap<usize, usize>, +/// } +/// +/// // Maps are serialized normally, +/// let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#; +/// let mut v = Doc { +/// map: HashMap::new(), +/// }; +/// v.map.insert(1, 1); +/// v.map.insert(2, 2); +/// v.map.insert(3, 3); +/// assert_eq!(v, serde_json::from_str(s).unwrap()); +/// +/// // but create an error if duplicate keys, like the `1`, exist. +/// let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#; +/// let mut v = Doc { +/// map: HashMap::new(), +/// }; +/// v.map.insert(1, 1); +/// v.map.insert(2, 2); +/// assert_eq!(v, serde_json::from_str(s).unwrap()); +/// ``` +pub mod maps_first_key_wins { + use super::*; + use duplicate_key_impls::DuplicateInsertsFirstWinsMap; + + /// Deserialize a map and return an error on duplicate keys + pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<T, D::Error> + where + T: DuplicateInsertsFirstWinsMap<K, V>, + K: Deserialize<'de>, + V: Deserialize<'de>, + D: Deserializer<'de>, + { + struct MapVisitor<T, K, V> { + marker: PhantomData<T>, + map_key_type: PhantomData<K>, + map_value_type: PhantomData<V>, + }; + + impl<'de, T, K, V> Visitor<'de> for MapVisitor<T, K, V> + where + T: DuplicateInsertsFirstWinsMap<K, V>, + K: Deserialize<'de>, + V: Deserialize<'de>, + { + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut values = Self::Value::new(access.size_hint()); + + while let Some((key, value)) = access.next_entry()? { + values.insert(key, value); + } + + Ok(values) + } + } + + let visitor = MapVisitor { + marker: PhantomData, + map_key_type: PhantomData, + map_value_type: PhantomData, + }; + deserializer.deserialize_map(visitor) + } +} + +/// De/Serialize a [`Option`]`<String>` type while transforming the empty string to [`None`] +/// +/// Convert an [`Option`]`<T>` from/to string using [`FromStr`] and [`AsRef`]`<str>` implementations. +/// An empty string is deserialized as [`None`] and a [`None`] vice versa. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::string_empty_as_none")] +/// tags: Option<String>, +/// } +/// +/// let v: A = serde_json::from_str(r##"{ +/// "tags": "" +/// }"##).unwrap(); +/// assert!(v.tags.is_none()); +/// +/// let v: A = serde_json::from_str(r##"{ +/// "tags": "Hi" +/// }"##).unwrap(); +/// assert_eq!(Some("Hi".to_string()), v.tags); +/// +/// let x = A { +/// tags: Some("This is text".to_string()), +/// }; +/// assert_eq!(r#"{"tags":"This is text"}"#, serde_json::to_string(&x).unwrap()); +/// +/// let x = A { +/// tags: None, +/// }; +/// assert_eq!(r#"{"tags":""}"#, serde_json::to_string(&x).unwrap()); +/// ``` +pub mod string_empty_as_none { + use super::*; + + /// Deserialize an `Option<T>` from a string using `FromStr` + pub fn deserialize<'de, D, S>(deserializer: D) -> Result<Option<S>, D::Error> + where + D: Deserializer<'de>, + S: FromStr, + S::Err: Display, + { + struct OptionStringEmptyNone<S>(PhantomData<S>); + impl<'de, S> Visitor<'de> for OptionStringEmptyNone<S> + where + S: FromStr, + S::Err: Display, + { + type Value = Option<S>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("any string") + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: Error, + { + match value { + "" => Ok(None), + v => S::from_str(v).map(Some).map_err(Error::custom), + } + } + + fn visit_string<E>(self, value: String) -> Result<Self::Value, E> + where + E: Error, + { + match &*value { + "" => Ok(None), + v => S::from_str(v).map(Some).map_err(Error::custom), + } + } + + // handles the `null` case + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(None) + } + } + + deserializer.deserialize_any(OptionStringEmptyNone(PhantomData)) + } + + /// Serialize a string from `Option<T>` using `AsRef<str>` or using the empty string if `None`. + pub fn serialize<T, S>(option: &Option<T>, serializer: S) -> Result<S::Ok, S::Error> + where + T: AsRef<str>, + S: Serializer, + { + if let Some(value) = option { + value.as_ref().serialize(serializer) + } else { + "".serialize(serializer) + } + } +} + +/// De/Serialize a [`HashMap`] into a list of tuples +/// +/// Some formats, like JSON, have limitations on the type of keys for maps. +/// In case of JSON, keys are restricted to strings. +/// Rust features more powerfull keys, for example tuple, which can not be serialized to JSON. +/// +/// This helper serializes the [`HashMap`] into a list of tuples, which does not have the same type restrictions. +/// +/// If you need to de/serialize a [`BTreeMap`] then use [`btreemap_as_tuple_list`]. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use serde_json::json; +/// # use std::collections::HashMap; +/// # +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::hashmap_as_tuple_list")] +/// s: HashMap<(String, u32), u32>, +/// } +/// +/// let v: A = serde_json::from_value(json!({ +/// "s": [ +/// [["Hello", 123], 0], +/// [["World", 456], 1] +/// ] +/// })).unwrap(); +/// +/// assert_eq!(2, v.s.len()); +/// assert_eq!(1, v.s[&("World".to_string(), 456)]); +/// ``` +/// +/// The helper is generic over the hasher type of the [`HashMap`] and works with different variants, such as `FnvHashMap`. +/// +/// ``` +/// # extern crate fnv; +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use serde_json::json; +/// # +/// use fnv::FnvHashMap; +/// +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::hashmap_as_tuple_list")] +/// s: FnvHashMap<u32, bool>, +/// } +/// +/// let v: A = serde_json::from_value(json!({ +/// "s": [ +/// [0, false], +/// [1, true] +/// ] +/// })).unwrap(); +/// +/// assert_eq!(2, v.s.len()); +/// assert_eq!(true, v.s[&1]); +/// ``` +pub mod hashmap_as_tuple_list { + use super::{SerializeSeq, *}; // Needed to remove the unused import warning in the parent scope + + /// Serialize the [`HashMap`] as a list of tuples + pub fn serialize<K, V, S, BH>(map: &HashMap<K, V, BH>, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + K: Eq + Hash + Serialize, + V: Serialize, + BH: BuildHasher, + { + let mut seq = serializer.serialize_seq(Some(map.len()))?; + for item in map.iter() { + seq.serialize_element(&item)?; + } + seq.end() + } + + /// Deserialize a [`HashMap`] from a list of tuples + pub fn deserialize<'de, K, V, BH, D>(deserializer: D) -> Result<HashMap<K, V, BH>, D::Error> + where + D: Deserializer<'de>, + K: Eq + Hash + Deserialize<'de>, + V: Deserialize<'de>, + BH: BuildHasher + Default, + { + deserializer.deserialize_seq(HashMapVisitor(PhantomData)) + } + + #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))] + struct HashMapVisitor<K, V, BH>(PhantomData<fn() -> HashMap<K, V, BH>>); + + impl<'de, K, V, BH> Visitor<'de> for HashMapVisitor<K, V, BH> + where + K: Deserialize<'de> + Eq + Hash, + V: Deserialize<'de>, + BH: BuildHasher + Default, + { + type Value = HashMap<K, V, BH>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a list of key-value pairs") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut map = + HashMap::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), BH::default()); + while let Some((key, value)) = seq.next_element()? { + map.insert(key, value); + } + Ok(map) + } + } +} + +/// De/Serialize a [`BTreeMap`] into a list of tuples +/// +/// Some formats, like JSON, have limitations on the type of keys for maps. +/// In case of JSON, keys are restricted to strings. +/// Rust features more powerfull keys, for example tuple, which can not be serialized to JSON. +/// +/// This helper serializes the [`BTreeMap`] into a list of tuples, which does not have the same type restrictions. +/// +/// If you need to de/serialize a [`HashMap`] then use [`hashmap_as_tuple_list`]. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use serde_json::json; +/// # use std::collections::BTreeMap; +/// # +/// #[derive(Deserialize, Serialize)] +/// struct A { +/// #[serde(with = "serde_with::rust::btreemap_as_tuple_list")] +/// s: BTreeMap<(String, u32), u32>, +/// } +/// +/// let v: A = serde_json::from_value(json!({ +/// "s": [ +/// [["Hello", 123], 0], +/// [["World", 456], 1] +/// ] +/// })).unwrap(); +/// +/// assert_eq!(2, v.s.len()); +/// assert_eq!(1, v.s[&("World".to_string(), 456)]); +/// ``` +pub mod btreemap_as_tuple_list { + use super::*; + + /// Serialize the [`BTreeMap`] as a list of tuples + pub fn serialize<K, V, S>(map: &BTreeMap<K, V>, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + K: Eq + Hash + Serialize, + V: Serialize, + { + let mut seq = serializer.serialize_seq(Some(map.len()))?; + for item in map.iter() { + seq.serialize_element(&item)?; + } + seq.end() + } + + /// Deserialize a [`BTreeMap`] from a list of tuples + pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error> + where + D: Deserializer<'de>, + K: Deserialize<'de> + Ord, + V: Deserialize<'de>, + { + deserializer.deserialize_seq(BTreeMapVisitor(PhantomData)) + } + + #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))] + struct BTreeMapVisitor<K, V>(PhantomData<fn() -> BTreeMap<K, V>>); + + impl<'de, K, V> Visitor<'de> for BTreeMapVisitor<K, V> + where + K: Deserialize<'de> + Ord, + V: Deserialize<'de>, + { + type Value = BTreeMap<K, V>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a list of key-value pairs") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut map = BTreeMap::default(); + while let Some((key, value)) = seq.next_element()? { + map.insert(key, value); + } + Ok(map) + } + } +} + +/// This serializes a list of tuples into a map and back +/// +/// Normally, you want to use a [`HashMap`] or a [`BTreeMap`] when deserializing a map. +/// However, sometimes this is not possible due to type contains, e.g., if the type implements neither [`Hash`] nor [`Ord`]. +/// Another use case is deserializing a map with duplicate keys. +/// +/// The implementation is generic using the [`FromIterator`] and [`IntoIterator`] traits. +/// Therefore, all of [`Vec`], [`VecDeque`](std::collections::VecDeque), and [`LinkedList`](std::collections::LinkedList) and anything which implements those are supported. +/// +/// # Examples +/// +/// `Wrapper` does not implement [`Hash`] nor [`Ord`], thus prohibiting the use [`HashMap`] or [`BTreeMap`]. +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use serde_json::json; +/// # +/// #[derive(Debug, Deserialize, Serialize, Default)] +/// struct S { +/// #[serde(with = "serde_with::rust::tuple_list_as_map")] +/// s: Vec<(Wrapper<i32>, Wrapper<String>)>, +/// } +/// +/// #[derive(Clone, Debug, Serialize, Deserialize)] +/// #[serde(transparent)] +/// struct Wrapper<T>(T); +/// +/// let from = r#"{ +/// "s": { +/// "1": "Hi", +/// "2": "Cake", +/// "99": "Lie" +/// } +/// }"#; +/// let mut expected = S::default(); +/// expected.s.push((Wrapper(1), Wrapper("Hi".into()))); +/// expected.s.push((Wrapper(2), Wrapper("Cake".into()))); +/// expected.s.push((Wrapper(99), Wrapper("Lie".into()))); +/// +/// let res: S = serde_json::from_str(from).unwrap(); +/// for ((exp_k, exp_v), (res_k, res_v)) in expected.s.iter().zip(&res.s) { +/// assert_eq!(exp_k.0, res_k.0); +/// assert_eq!(exp_v.0, res_v.0); +/// } +/// assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); +/// ``` +/// +/// In this example, the serialized format contains duplicate keys, which is not supported with [`HashMap`] or [`BTreeMap`]. +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use serde_json::json; +/// # +/// #[derive(Debug, Deserialize, Serialize, PartialEq, Default)] +/// struct S { +/// #[serde(with = "serde_with::rust::tuple_list_as_map")] +/// s: Vec<(i32, String)>, +/// } +/// +/// let from = r#"{ +/// "s": { +/// "1": "Hi", +/// "1": "Cake", +/// "1": "Lie" +/// } +/// }"#; +/// let mut expected = S::default(); +/// expected.s.push((1, "Hi".into())); +/// expected.s.push((1, "Cake".into())); +/// expected.s.push((1, "Lie".into())); +/// +/// let res: S = serde_json::from_str(from).unwrap(); +/// assert_eq!(3, res.s.len()); +/// assert_eq!(expected, res); +/// assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); +/// ``` +pub mod tuple_list_as_map { + use super::{SerializeMap, *}; // Needed to remove the unused import warning in the parent scope + + /// Serialize any iteration of tuples into a map. + pub fn serialize<'a, I, K, V, S>(iter: I, serializer: S) -> Result<S::Ok, S::Error> + where + I: IntoIterator<Item = &'a (K, V)>, + I::IntoIter: ExactSizeIterator, + K: Serialize + 'a, + V: Serialize + 'a, + S: Serializer, + { + let iter = iter.into_iter(); + let mut map = serializer.serialize_map(Some(iter.len()))?; + for (key, value) in iter { + map.serialize_entry(&key, &value)?; + } + map.end() + } + + /// Deserialize a map into an iterator of tuples. + pub fn deserialize<'de, I, K, V, D>(deserializer: D) -> Result<I, D::Error> + where + I: FromIterator<(K, V)>, + K: Deserialize<'de>, + V: Deserialize<'de>, + D: Deserializer<'de>, + { + deserializer.deserialize_map(MapVisitor(PhantomData)) + } + + #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))] + struct MapVisitor<I, K, V>(PhantomData<fn() -> (I, K, V)>); + + impl<'de, I, K, V> Visitor<'de> for MapVisitor<I, K, V> + where + I: FromIterator<(K, V)>, + K: Deserialize<'de>, + V: Deserialize<'de>, + { + type Value = I; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let iter = MapIter(map, PhantomData); + iter.collect() + } + } + + struct MapIter<'de, A, K, V>(A, PhantomData<(&'de (), A, K, V)>); + + impl<'de, A, K, V> Iterator for MapIter<'de, A, K, V> + where + A: MapAccess<'de>, + K: Deserialize<'de>, + V: Deserialize<'de>, + { + type Item = Result<(K, V), A::Error>; + + fn next(&mut self) -> Option<Self::Item> { + match self.0.next_entry() { + Ok(Some(x)) => Some(Ok(x)), + Ok(None) => None, + Err(err) => Some(Err(err)), + } + } + } +} + +/// Deserialize from bytes or String +/// +/// Any Rust [`String`] can be converted into bytes ([`Vec`]`<u8>`). +/// Accepting both as formats while deserializing can be helpful while interacting with language +/// which have a looser definition of string than Rust. +/// +/// # Example +/// ```rust +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::{Deserialize, Serialize}; +/// # use serde_json::json; +/// # +/// #[derive(Debug, Deserialize, Serialize, PartialEq, Default)] +/// struct S { +/// #[serde(deserialize_with = "serde_with::rust::bytes_or_string::deserialize")] +/// bos: Vec<u8>, +/// } +/// +/// // Here we deserialize from a byte array ... +/// let from = r#"{ +/// "bos": [ +/// 0, +/// 1, +/// 2, +/// 3 +/// ] +/// }"#; +/// let expected = S { +/// bos: vec![0, 1, 2, 3], +/// }; +/// +/// let res: S = serde_json::from_str(from).unwrap(); +/// assert_eq!(expected, res); +/// +/// // and serialization works too. +/// assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); +/// +/// // But we also support deserializing from String +/// let from = r#"{ +/// "bos": "✨Works!" +/// }"#; +/// let expected = S { +/// bos: "✨Works!".as_bytes().to_vec(), +/// }; +/// +/// let res: S = serde_json::from_str(from).unwrap(); +/// assert_eq!(expected, res); +/// ``` +pub mod bytes_or_string { + use super::*; + + /// Deserialize a [`Vec`]`<u8>` from either bytes or string + pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(BytesOrStringVisitor) + } + + struct BytesOrStringVisitor; + + impl<'de> Visitor<'de> for BytesOrStringVisitor { + type Value = Vec<u8>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a list of bytes or a string") + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> { + Ok(v.to_vec()) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> { + Ok(v) + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> { + Ok(v.as_bytes().to_vec()) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> { + Ok(v.into_bytes()) + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut res = Vec::with_capacity(seq.size_hint().unwrap_or(0)); + while let Some(value) = seq.next_element()? { + res.push(value); + } + Ok(res) + } + } +} + +/// Deserialize value and return [`Default`] on error +/// +/// The main use case is ignoring error while deserializing. +/// Instead of erroring, it simply deserializes the [`Default`] variant of the type. +/// It is not possible to find the error location, i.e., which field had a deserialization error, with this method. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::Deserialize; +/// # +/// #[derive(Deserialize)] +/// struct A { +/// #[serde(deserialize_with = "serde_with::rust::default_on_error::deserialize")] +/// value: u32, +/// } +/// +/// let a: A = serde_json::from_str(r#"{"value": 123}"#).unwrap(); +/// assert_eq!(123, a.value); +/// +/// // null is of invalid type +/// let a: A = serde_json::from_str(r#"{"value": null}"#).unwrap(); +/// assert_eq!(0, a.value); +/// +/// // String is of invalid type +/// let a: A = serde_json::from_str(r#"{"value": "123"}"#).unwrap(); +/// assert_eq!(0, a.value); +/// +/// // Missing entries still cause errors +/// assert!(serde_json::from_str::<A>(r#"{ }"#).is_err()); +/// ``` +/// +/// Deserializing missing values can be supported by adding the `default` field attribute: +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::Deserialize; +/// # +/// #[derive(Deserialize)] +/// struct B { +/// #[serde(default, deserialize_with = "serde_with::rust::default_on_error::deserialize")] +/// value: u32, +/// } +/// +/// +/// let b: B = serde_json::from_str(r#"{ }"#).unwrap(); +/// assert_eq!(0, b.value); +/// ``` +pub mod default_on_error { + use super::*; + + /// Deserialize T and return the [`Default`] value on error + pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + T: Deserialize<'de> + Default, + { + T::deserialize(deserializer).or_else(|_| Ok(Default::default())) + } +} + +/// Deserialize default value if encountering `null`. +/// +/// One use case are JSON APIs in which the `null` value represents some default state. +/// This adapter allows to turn the `null` directly into the [`Default`] value of the type. +/// +/// # Examples +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_derive; +/// # extern crate serde_json; +/// # extern crate serde_with; +/// # +/// # use serde_derive::Deserialize; +/// # +/// #[derive(Deserialize)] +/// struct A { +/// #[serde(deserialize_with = "serde_with::rust::default_on_null::deserialize")] +/// value: u32, +/// } +/// +/// let a: A = serde_json::from_str(r#"{"value": 123}"#).unwrap(); +/// assert_eq!(123, a.value); +/// +/// let a: A = serde_json::from_str(r#"{"value": null}"#).unwrap(); +/// assert_eq!(0, a.value); +/// +/// // String is invalid type +/// assert!(serde_json::from_str::<A>(r#"{"value": "123"}"#).is_err()); +/// ``` +pub mod default_on_null { + use super::*; + + /// Deserialize T and return the [`Default`] value if original value is `null` + pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error> + where + D: Deserializer<'de>, + T: Deserialize<'de> + Default, + { + Ok(Option::deserialize(deserializer)?.unwrap_or_default()) + } +} diff --git a/third_party/rust/serde_with/src/with_prefix.rs b/third_party/rust/serde_with/src/with_prefix.rs new file mode 100644 index 0000000000..776927d365 --- /dev/null +++ b/third_party/rust/serde_with/src/with_prefix.rs @@ -0,0 +1,607 @@ +use std::fmt; + +use serde::{ + de::{self, DeserializeSeed, Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor}, + forward_to_deserialize_any, + ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}, +}; + +/// Serialize with an added prefix on every field name and deserialize by +/// trimming away the prefix. +/// +/// **Note:** Use of this macro is incompatible with applying the [`deny_unknown_fields`] attribute +/// on the container. +/// While deserializing, it will always warn about unknown fields, even though they are processed +/// by the `with_prefix` wrapper. +/// More details can be found in [this issue][issue-with_prefix-deny_unknown_fields]. +/// +/// # Example +/// +/// The [Challonge REST API] likes to use prefixes to group related fields. In +/// simplified form, their JSON may resemble the following: +/// +/// [Challonge REST API]: https://api.challonge.com/v1/documents/matches/show +/// +/// ```json +/// { +/// "player1_name": "name1", +/// "player1_votes": 1, +/// "player2_name": "name2", +/// "player2_votes": 2 +/// } +/// ``` +/// +/// In Rust we would ideally like to model this data as a pair of `Player` +/// structs, rather than repeating the fields of `Player` for each prefix. +/// +/// ```rust +/// struct Match { +/// player1: Player, +/// player2: Player, +/// } +/// +/// struct Player { +/// name: String, +/// votes: u64, +/// } +/// ``` +/// +/// This `with_prefix!` macro produces an adapter that adds a prefix onto field +/// names during serialization and trims away the prefix during deserialization. +/// An implementation of the Challonge API would use `with_prefix!` like this: +/// +/// ```rust +/// extern crate serde_derive; +/// extern crate serde_json; +/// extern crate serde_with; +/// +/// use serde_derive::{Deserialize, Serialize}; +/// use serde_json::json; +/// use serde_with::with_prefix; +/// +/// #[derive(Serialize, Deserialize)] +/// struct Match { +/// #[serde(flatten, with = "prefix_player1")] +/// player1: Player, +/// #[serde(flatten, with = "prefix_player2")] +/// player2: Player, +/// } +/// +/// #[derive(Serialize, Deserialize)] +/// struct Player { +/// name: String, +/// votes: u64, +/// } +/// +/// with_prefix!(prefix_player1 "player1_"); +/// with_prefix!(prefix_player2 "player2_"); +/// # +/// # const EXPECTED: &str = r#"{ +/// # "player1_name": "name1", +/// # "player1_votes": 1, +/// # "player2_name": "name2", +/// # "player2_votes": 2 +/// # }"#; +/// +/// fn main() { +/// let m = Match { +/// player1: Player { +/// name: "name1".to_owned(), +/// votes: 1, +/// }, +/// player2: Player { +/// name: "name2".to_owned(), +/// votes: 2, +/// }, +/// }; +/// +/// let j = serde_json::to_string_pretty(&m).unwrap(); +/// println!("{}", j); +/// # +/// # assert_eq!(j, EXPECTED); +/// } +/// ``` +/// +/// [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields +/// [issue-with_prefix-deny_unknown_fields]: https://github.com/jonasbb/serde_with/issues/57 +#[macro_export] +macro_rules! with_prefix { + ($module:ident $prefix:expr) => { + mod $module { + use $crate::{ + serde::{Deserialize, Deserializer, Serialize, Serializer}, + with_prefix::WithPrefix, + }; + + #[allow(dead_code)] + pub fn serialize<T, S>(object: &T, serializer: S) -> Result<S::Ok, S::Error> + where + T: Serialize, + S: Serializer, + { + object.serialize(WithPrefix { + delegate: serializer, + prefix: $prefix, + }) + } + + #[allow(dead_code)] + pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error> + where + T: Deserialize<'de>, + D: Deserializer<'de>, + { + T::deserialize(WithPrefix { + delegate: deserializer, + prefix: $prefix, + }) + } + } + }; +} + +#[allow(missing_debug_implementations)] +pub struct WithPrefix<'a, T> { + pub delegate: T, + pub prefix: &'a str, +} + +impl<'a, T> Serialize for WithPrefix<'a, T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + self.delegate.serialize(WithPrefix { + delegate: serializer, + prefix: self.prefix, + }) + } +} + +impl<'a, S> Serializer for WithPrefix<'a, S> +where + S: Serializer, +{ + type Ok = S::Ok; + type Error = S::Error; + type SerializeSeq = Impossible<Self::Ok, Self::Error>; + type SerializeTuple = Impossible<Self::Ok, Self::Error>; + type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>; + type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; + type SerializeMap = WithPrefix<'a, S::SerializeMap>; + type SerializeStruct = WithPrefix<'a, S::SerializeMap>; + type SerializeStructVariant = Impossible<Self::Ok, Self::Error>; + + fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> { + self.delegate + .collect_str(&format_args!("{}{}", self.prefix, v)) + } + + fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + self.delegate.serialize_none() + } + + fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate.serialize_some(&WithPrefix { + delegate: value, + prefix: self.prefix, + }) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_newtype_struct<T>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_newtype_variant<T>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Ok(WithPrefix { + delegate: self.delegate.serialize_map(len)?, + prefix: self.prefix, + }) + } + + fn serialize_struct( + self, + _name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + self.serialize_map(Some(len)) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(ser::Error::custom("wrong type for with_prefix")) + } +} + +impl<'a, S> SerializeMap for WithPrefix<'a, S> +where + S: SerializeMap, +{ + type Ok = S::Ok; + type Error = S::Error; + + fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate.serialize_key(&WithPrefix { + delegate: key, + prefix: self.prefix, + }) + } + + fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate.serialize_value(value) + } + + fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error> + where + K: ?Sized + Serialize, + V: ?Sized + Serialize, + { + self.delegate.serialize_entry( + &WithPrefix { + delegate: key, + prefix: self.prefix, + }, + value, + ) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + self.delegate.end() + } +} + +impl<'a, S> SerializeStruct for WithPrefix<'a, S> +where + S: SerializeMap, +{ + type Ok = S::Ok; + type Error = S::Error; + + fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate + .serialize_entry(&format!("{}{}", self.prefix, key), value) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + self.delegate.end() + } +} + +impl<'de, 'a, T> DeserializeSeed<'de> for WithPrefix<'a, T> +where + T: DeserializeSeed<'de>, +{ + type Value = T::Value; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + self.delegate.deserialize(WithPrefix { + delegate: deserializer, + prefix: self.prefix, + }) + } +} + +impl<'de, 'a, D> Deserializer<'de> for WithPrefix<'a, D> +where + D: Deserializer<'de>, +{ + type Error = D::Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.delegate.deserialize_map(WithPrefix { + delegate: visitor, + prefix: self.prefix, + }) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.delegate.deserialize_any(WithPrefixOption { + first_key: None, + delegate: visitor, + prefix: self.prefix, + }) + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + self.delegate.deserialize_identifier(WithPrefix { + delegate: visitor, + prefix: self.prefix, + }) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum ignored_any + } +} + +impl<'de, 'a, V> Visitor<'de> for WithPrefix<'a, V> +where + V: Visitor<'de>, +{ + type Value = V::Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.delegate.expecting(formatter) + } + + fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + self.delegate.visit_map(WithPrefix { + delegate: map, + prefix: self.prefix, + }) + } +} + +impl<'de, 'a, A> MapAccess<'de> for WithPrefix<'a, A> +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: DeserializeSeed<'de>, + { + while let Some(s) = self.delegate.next_key::<String>()? { + if s.starts_with(self.prefix) { + let without_prefix = s[self.prefix.len()..].into_deserializer(); + return seed.deserialize(without_prefix).map(Some); + } + self.delegate.next_value::<IgnoredAny>()?; + } + Ok(None) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + where + V: DeserializeSeed<'de>, + { + self.delegate.next_value_seed(seed) + } +} + +#[allow(missing_debug_implementations)] +pub struct WithPrefixOption<'a, T> { + first_key: Option<String>, + delegate: T, + prefix: &'a str, +} + +impl<'de, 'a, V> Visitor<'de> for WithPrefixOption<'a, V> +where + V: Visitor<'de>, +{ + type Value = V::Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.delegate.expecting(formatter) + } + + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: de::Error, + { + self.delegate.visit_none() + } + + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + while let Some(s) = map.next_key::<String>()? { + if s.starts_with(self.prefix) { + return self.delegate.visit_some(WithPrefixOption { + first_key: Some(s), + delegate: map, + prefix: self.prefix, + }); + } + map.next_value::<IgnoredAny>()?; + } + self.delegate.visit_none() + } +} + +impl<'de, 'a, A> Deserializer<'de> for WithPrefixOption<'a, A> +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + 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 + } +} + +impl<'de, 'a, A> MapAccess<'de> for WithPrefixOption<'a, A> +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: DeserializeSeed<'de>, + { + if let Some(s) = self.first_key.take() { + let without_prefix = s[self.prefix.len()..].into_deserializer(); + return seed.deserialize(without_prefix).map(Some); + } + while let Some(s) = self.delegate.next_key::<String>()? { + if s.starts_with(self.prefix) { + let without_prefix = s[self.prefix.len()..].into_deserializer(); + return seed.deserialize(without_prefix).map(Some); + } + self.delegate.next_value::<IgnoredAny>()?; + } + Ok(None) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + where + V: DeserializeSeed<'de>, + { + self.delegate.next_value_seed(seed) + } +} diff --git a/third_party/rust/serde_with/tests/chrono.rs b/third_party/rust/serde_with/tests/chrono.rs new file mode 100644 index 0000000000..e20106e62b --- /dev/null +++ b/third_party/rust/serde_with/tests/chrono.rs @@ -0,0 +1,53 @@ +#![cfg(feature = "chrono")] + +extern crate chrono; +extern crate pretty_assertions; +extern crate serde; +extern crate serde_derive; +extern crate serde_json; +extern crate serde_with; + +use chrono::{DateTime, NaiveDateTime, Utc}; +use pretty_assertions::assert_eq; +use serde_derive::Deserialize; + +fn new_datetime(secs: i64, nsecs: u32) -> DateTime<Utc> { + DateTime::from_utc(NaiveDateTime::from_timestamp(secs, nsecs), Utc) +} + +#[test] +fn json_datetime_from_any_to_string_deserialization() { + #[derive(Debug, Deserialize)] + struct S { + #[serde(with = "serde_with::chrono::datetime_utc_ts_seconds_from_any")] + date: DateTime<Utc>, + } + let from = r#"[ + { "date": 1478563200 }, + { "date": 0 }, + { "date": -86000 }, + { "date": 1478563200.123 }, + { "date": 0.000 }, + { "date": -86000.999 }, + { "date": "1478563200.123" }, + { "date": "0.000" }, + { "date": "-86000.999" } + ]"#; + + let res: Vec<S> = serde_json::from_str(from).unwrap(); + + // just integers + assert_eq!(new_datetime(1_478_563_200, 0), res[0].date); + assert_eq!(new_datetime(0, 0), res[1].date); + assert_eq!(new_datetime(-86000, 0), res[2].date); + + // floats, shows precision errors in subsecond part + assert_eq!(new_datetime(1_478_563_200, 122_999_906), res[3].date); + assert_eq!(new_datetime(0, 0), res[4].date); + assert_eq!(new_datetime(-86000, 998_999_999), res[5].date); + + // string representation of floats + assert_eq!(new_datetime(1_478_563_200, 123_000_000), res[6].date); + assert_eq!(new_datetime(0, 0), res[7].date); + assert_eq!(new_datetime(-86000, 999_000_000), res[8].date); +} diff --git a/third_party/rust/serde_with/tests/rust.rs b/third_party/rust/serde_with/tests/rust.rs new file mode 100644 index 0000000000..cd317c6f77 --- /dev/null +++ b/third_party/rust/serde_with/tests/rust.rs @@ -0,0 +1,573 @@ +extern crate fnv; +extern crate pretty_assertions; +extern crate serde; +extern crate serde_derive; +extern crate serde_json; +extern crate serde_with; + +use fnv::FnvHashMap; +use pretty_assertions::assert_eq; +use serde_derive::{Deserialize, Serialize}; +use serde_json::error::Category; +use serde_with::CommaSeparator; +use std::collections::{BTreeMap, HashMap, LinkedList, VecDeque}; + +#[test] +fn string_collection() { + #[derive(Debug, Deserialize)] + struct S { + #[serde(with = "serde_with::rust::StringWithSeparator::<CommaSeparator>")] + s: Vec<String>, + } + let from = r#"[ + { "s": "A,B,C,D" }, + { "s": ",," }, + { "s": "AVeryLongString" } + ]"#; + + let res: Vec<S> = serde_json::from_str(from).unwrap(); + assert_eq!( + vec![ + "A".to_string(), + "B".to_string(), + "C".to_string(), + "D".to_string(), + ], + res[0].s + ); + assert_eq!( + vec!["".to_string(), "".to_string(), "".to_string()], + res[1].s + ); + assert_eq!(vec!["AVeryLongString".to_string()], res[2].s); +} + +#[test] +fn string_collection_non_existing() { + #[derive(Debug, Deserialize, Serialize)] + struct S { + #[serde(with = "serde_with::rust::StringWithSeparator::<CommaSeparator>")] + s: Vec<String>, + } + let from = r#"[ + { "s": "" } + ]"#; + + let res: Vec<S> = serde_json::from_str(from).unwrap(); + assert_eq!(Vec::<String>::new(), res[0].s); + + assert_eq!(r#"{"s":""}"#, serde_json::to_string(&res[0]).unwrap()); +} + +#[test] +fn prohibit_duplicate_value_hashset() { + use std::{collections::HashSet, iter::FromIterator}; + #[derive(Debug, Eq, PartialEq, Deserialize)] + struct Doc { + #[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] + set: HashSet<usize>, + } + + let s = r#"{"set": [1, 2, 3, 4]}"#; + let v = Doc { + set: HashSet::from_iter(vec![1, 2, 3, 4]), + }; + assert_eq!(v, serde_json::from_str(s).unwrap()); + + let s = r#"{"set": [1, 2, 3, 4, 1]}"#; + let res: Result<Doc, _> = serde_json::from_str(s); + assert!(res.is_err()); +} + +#[test] +fn prohibit_duplicate_value_btreeset() { + use std::{collections::BTreeSet, iter::FromIterator}; + #[derive(Debug, Eq, PartialEq, Deserialize)] + struct Doc { + #[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] + set: BTreeSet<usize>, + } + + let s = r#"{"set": [1, 2, 3, 4]}"#; + let v = Doc { + set: BTreeSet::from_iter(vec![1, 2, 3, 4]), + }; + assert_eq!(v, serde_json::from_str(s).unwrap()); + + let s = r#"{"set": [1, 2, 3, 4, 1]}"#; + let res: Result<Doc, _> = serde_json::from_str(s); + assert!(res.is_err()); +} + +#[test] +fn prohibit_duplicate_value_hashmap() { + use std::collections::HashMap; + #[derive(Debug, Eq, PartialEq, Deserialize)] + struct Doc { + #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] + map: HashMap<usize, usize>, + } + + // Different value and key always works + let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#; + let mut v = Doc { + map: HashMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 2); + v.map.insert(3, 3); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Same value for different keys is ok + let s = r#"{"map": {"1": 1, "2": 1, "3": 1}}"#; + let mut v = Doc { + map: HashMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 1); + v.map.insert(3, 1); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Duplicate keys are an error + let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#; + let res: Result<Doc, _> = serde_json::from_str(s); + assert!(res.is_err()); +} + +#[test] +fn prohibit_duplicate_value_btreemap() { + use std::collections::BTreeMap; + #[derive(Debug, Eq, PartialEq, Deserialize)] + struct Doc { + #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] + map: BTreeMap<usize, usize>, + } + + // Different value and key always works + let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#; + let mut v = Doc { + map: BTreeMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 2); + v.map.insert(3, 3); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Same value for different keys is ok + let s = r#"{"map": {"1": 1, "2": 1, "3": 1}}"#; + let mut v = Doc { + map: BTreeMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 1); + v.map.insert(3, 1); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Duplicate keys are an error + let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#; + let res: Result<Doc, _> = serde_json::from_str(s); + assert!(res.is_err()); +} + +#[test] +fn duplicate_key_first_wins_hashmap() { + use std::collections::HashMap; + #[derive(Debug, Eq, PartialEq, Deserialize)] + struct Doc { + #[serde(with = "::serde_with::rust::maps_first_key_wins")] + map: HashMap<usize, usize>, + } + + // Different value and key always works + let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#; + let mut v = Doc { + map: HashMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 2); + v.map.insert(3, 3); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Same value for different keys is ok + let s = r#"{"map": {"1": 1, "2": 1, "3": 1}}"#; + let mut v = Doc { + map: HashMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 1); + v.map.insert(3, 1); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Duplicate keys, the first one is used + let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#; + let mut v = Doc { + map: HashMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 2); + assert_eq!(v, serde_json::from_str(s).unwrap()); +} + +#[test] +fn duplicate_key_first_wins_btreemap() { + use std::collections::BTreeMap; + #[derive(Debug, Eq, PartialEq, Deserialize)] + struct Doc { + #[serde(with = "::serde_with::rust::maps_first_key_wins")] + map: BTreeMap<usize, usize>, + } + + // Different value and key always works + let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#; + let mut v = Doc { + map: BTreeMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 2); + v.map.insert(3, 3); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Same value for different keys is ok + let s = r#"{"map": {"1": 1, "2": 1, "3": 1}}"#; + let mut v = Doc { + map: BTreeMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 1); + v.map.insert(3, 1); + assert_eq!(v, serde_json::from_str(s).unwrap()); + + // Duplicate keys, the first one is used + let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#; + let mut v = Doc { + map: BTreeMap::new(), + }; + v.map.insert(1, 1); + v.map.insert(2, 2); + assert_eq!(v, serde_json::from_str(s).unwrap()); +} + +#[test] +fn test_hashmap_as_tuple_list() { + #[derive(Debug, Deserialize, Serialize, PartialEq, Default)] + struct S { + #[serde(with = "serde_with::rust::hashmap_as_tuple_list")] + s: HashMap<String, u8>, + } + let from = r#"{ + "s": [ + ["ABC", 1], + ["Hello", 0], + ["World", 20] + ] + }"#; + let mut expected = S::default(); + expected.s.insert("ABC".to_string(), 1); + expected.s.insert("Hello".to_string(), 0); + expected.s.insert("World".to_string(), 20); + + let res: S = serde_json::from_str(from).unwrap(); + assert_eq!(expected, res); + + let from = r#"{ + "s": [ + [ + "Hello", + 0 + ] + ] +}"#; + let mut expected = S::default(); + expected.s.insert("Hello".to_string(), 0); + + let res: S = serde_json::from_str(from).unwrap(); + assert_eq!(expected, res); + // We can only do this with a HashMap of size 1 as otherwise the iteration order is unspecified + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": [] +}"#; + let expected = S::default(); + let res: S = serde_json::from_str(from).unwrap(); + assert!(res.s.is_empty()); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + // Test parse error + let from = r#"{ + "s": [ [1] ] +}"#; + let res: Result<S, _> = serde_json::from_str(from); + assert!(res.is_err()); + let err = res.unwrap_err(); + println!("{:?}", err); + assert!(err.is_data()); +} + +#[test] +fn test_hashmap_as_tuple_list_fnv() { + #[derive(Debug, Deserialize, Serialize, PartialEq, Default)] + struct S { + #[serde(with = "serde_with::rust::hashmap_as_tuple_list")] + s: FnvHashMap<String, u8>, + } + let from = r#"{ + "s": [ + ["ABC", 1], + ["Hello", 0], + ["World", 20] + ] + }"#; + let mut expected = S::default(); + expected.s.insert("ABC".to_string(), 1); + expected.s.insert("Hello".to_string(), 0); + expected.s.insert("World".to_string(), 20); + + let res: S = serde_json::from_str(from).unwrap(); + assert_eq!(expected, res); + + let from = r#"{ + "s": [ + [ + "Hello", + 0 + ] + ] +}"#; + let mut expected = S::default(); + expected.s.insert("Hello".to_string(), 0); + + let res: S = serde_json::from_str(from).unwrap(); + assert_eq!(expected, res); + // We can only do this with a HashMap of size 1 as otherwise the iteration order is unspecified + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": [] +}"#; + let expected = S::default(); + let res: S = serde_json::from_str(from).unwrap(); + assert!(res.s.is_empty()); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + // Test parse error + let from = r#"{ + "s": [ [1] ] +}"#; + let res: Result<S, _> = serde_json::from_str(from); + assert!(res.is_err()); + let err = res.unwrap_err(); + println!("{:?}", err); + assert!(err.is_data()); +} + +#[test] +fn test_btreemap_as_tuple_list() { + #[derive(Debug, Deserialize, Serialize, PartialEq, Default)] + struct S { + #[serde(with = "serde_with::rust::btreemap_as_tuple_list")] + s: BTreeMap<String, u8>, + } + let from = r#"{ + "s": [ + [ + "ABC", + 1 + ], + [ + "Hello", + 0 + ], + [ + "World", + 20 + ] + ] +}"#; + let mut expected = S::default(); + expected.s.insert("ABC".to_string(), 1); + expected.s.insert("Hello".to_string(), 0); + expected.s.insert("World".to_string(), 20); + + let res: S = serde_json::from_str(from).unwrap(); + assert_eq!(expected, res); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": [ + [ + "Hello", + 0 + ] + ] +}"#; + let mut expected = S::default(); + expected.s.insert("Hello".to_string(), 0); + + let res: S = serde_json::from_str(from).unwrap(); + assert_eq!(expected, res); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": [] +}"#; + let expected = S::default(); + let res: S = serde_json::from_str(from).unwrap(); + assert!(res.s.is_empty()); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + // Test parse error + let from = r#"{ + "s": [ [1] ] +}"#; + let res: Result<S, _> = serde_json::from_str(from); + assert!(res.is_err()); + let err = res.unwrap_err(); + println!("{:?}", err); + assert!(err.is_data()); +} + +#[test] +fn tuple_list_as_map_vec() { + #[derive(Debug, Deserialize, Serialize, Default)] + struct S { + #[serde(with = "serde_with::rust::tuple_list_as_map")] + s: Vec<(Wrapper<i32>, Wrapper<String>)>, + } + + #[derive(Clone, Debug, Serialize, Deserialize)] + #[serde(transparent)] + struct Wrapper<T>(T); + + let from = r#"{ + "s": { + "1": "Hi", + "2": "Cake", + "99": "Lie" + } +}"#; + let mut expected = S::default(); + expected.s.push((Wrapper(1), Wrapper("Hi".into()))); + expected.s.push((Wrapper(2), Wrapper("Cake".into()))); + expected.s.push((Wrapper(99), Wrapper("Lie".into()))); + + let res: S = serde_json::from_str(from).unwrap(); + for ((exp_k, exp_v), (res_k, res_v)) in expected.s.iter().zip(&res.s) { + assert_eq!(exp_k.0, res_k.0); + assert_eq!(exp_v.0, res_v.0); + } + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": {} +}"#; + let expected = S::default(); + + let res: S = serde_json::from_str(from).unwrap(); + assert!(res.s.is_empty()); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": [] +}"#; + let res: Result<S, _> = serde_json::from_str(from); + let res = res.unwrap_err(); + assert_eq!(Category::Data, res.classify()); + assert_eq!( + "invalid type: sequence, expected a map at line 2 column 7", + res.to_string() + ); + + let from = r#"{ + "s": null +}"#; + let res: Result<S, _> = serde_json::from_str(from); + let res = res.unwrap_err(); + assert_eq!(Category::Data, res.classify()); + assert_eq!( + "invalid type: null, expected a map at line 2 column 11", + res.to_string() + ); +} + +#[test] +fn tuple_list_as_map_linkedlist() { + #[derive(Debug, Deserialize, Serialize, Default)] + struct S { + #[serde(with = "serde_with::rust::tuple_list_as_map")] + s: LinkedList<(Wrapper<i32>, Wrapper<String>)>, + } + + #[derive(Clone, Debug, Serialize, Deserialize)] + #[serde(transparent)] + struct Wrapper<T>(T); + + let from = r#"{ + "s": { + "1": "Hi", + "2": "Cake", + "99": "Lie" + } +}"#; + let mut expected = S::default(); + expected.s.push_back((Wrapper(1), Wrapper("Hi".into()))); + expected.s.push_back((Wrapper(2), Wrapper("Cake".into()))); + expected.s.push_back((Wrapper(99), Wrapper("Lie".into()))); + + let res: S = serde_json::from_str(from).unwrap(); + for ((exp_k, exp_v), (res_k, res_v)) in expected.s.iter().zip(&res.s) { + assert_eq!(exp_k.0, res_k.0); + assert_eq!(exp_v.0, res_v.0); + } + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": {} +}"#; + let expected = S::default(); + + let res: S = serde_json::from_str(from).unwrap(); + assert!(res.s.is_empty()); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); +} + +#[test] +fn tuple_list_as_map_vecdeque() { + #[derive(Debug, Deserialize, Serialize, Default)] + struct S { + #[serde(with = "serde_with::rust::tuple_list_as_map")] + s: VecDeque<(Wrapper<i32>, Wrapper<String>)>, + } + + #[derive(Clone, Debug, Serialize, Deserialize)] + #[serde(transparent)] + struct Wrapper<T>(T); + + let from = r#"{ + "s": { + "1": "Hi", + "2": "Cake", + "99": "Lie" + } +}"#; + let mut expected = S::default(); + expected.s.push_back((Wrapper(1), Wrapper("Hi".into()))); + expected.s.push_back((Wrapper(2), Wrapper("Cake".into()))); + expected.s.push_back((Wrapper(99), Wrapper("Lie".into()))); + + let res: S = serde_json::from_str(from).unwrap(); + for ((exp_k, exp_v), (res_k, res_v)) in expected.s.iter().zip(&res.s) { + assert_eq!(exp_k.0, res_k.0); + assert_eq!(exp_v.0, res_v.0); + } + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); + + let from = r#"{ + "s": {} +}"#; + let expected = S::default(); + + let res: S = serde_json::from_str(from).unwrap(); + assert!(res.s.is_empty()); + assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap()); +} diff --git a/third_party/rust/serde_with/tests/version_numbers.rs b/third_party/rust/serde_with/tests/version_numbers.rs new file mode 100644 index 0000000000..fa24ed060a --- /dev/null +++ b/third_party/rust/serde_with/tests/version_numbers.rs @@ -0,0 +1,20 @@ +extern crate version_sync; + +use version_sync::{ + assert_contains_regex, assert_html_root_url_updated, assert_markdown_deps_updated, +}; + +#[test] +fn test_readme_deps() { + assert_markdown_deps_updated!("README.md"); +} + +#[test] +fn test_readme_deps_in_lib() { + assert_contains_regex!("src/lib.rs", r#"^//! version = "{version}""#); +} + +#[test] +fn test_html_root_url() { + assert_html_root_url_updated!("src/lib.rs"); +} diff --git a/third_party/rust/serde_with/tests/with_prefix.rs b/third_party/rust/serde_with/tests/with_prefix.rs new file mode 100644 index 0000000000..b1113b7cee --- /dev/null +++ b/third_party/rust/serde_with/tests/with_prefix.rs @@ -0,0 +1,130 @@ +extern crate pretty_assertions; +extern crate serde; +extern crate serde_derive; +extern crate serde_json; +extern crate serde_with; + +use pretty_assertions::assert_eq; +use serde_derive::{Deserialize, Serialize}; +use serde_json::json; +use serde_with::with_prefix; +use std::collections::HashMap; + +#[test] +fn test_flatten_with_prefix() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Match { + #[serde(flatten, with = "prefix_player1")] + player1: Player, + #[serde(flatten, with = "prefix_player2")] + player2: Option<Player>, + #[serde(flatten, with = "prefix_player3")] + player3: Option<Player>, + #[serde(flatten, with = "prefix_tag")] + tags: HashMap<String, String>, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Player { + name: String, + votes: u64, + } + + with_prefix!(prefix_player1 "player1_"); + with_prefix!(prefix_player2 "player2_"); + with_prefix!(prefix_player3 "player3_"); + with_prefix!(prefix_tag "tag_"); + + let m = Match { + player1: Player { + name: "name1".to_owned(), + votes: 1, + }, + player2: Some(Player { + name: "name2".to_owned(), + votes: 2, + }), + player3: None, + tags: { + let mut tags = HashMap::new(); + tags.insert("t".to_owned(), "T".to_owned()); + tags + }, + }; + + let expected = json!({ + "player1_name": "name1", + "player1_votes": 1, + "player2_name": "name2", + "player2_votes": 2, + "tag_t": "T" + }); + + let j = serde_json::to_string(&m).unwrap(); + assert_eq!(j, expected.to_string()); + + assert_eq!(m, serde_json::from_str(&j).unwrap()); +} + +#[test] +fn test_plain_with_prefix() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Match { + #[serde(with = "prefix_player1")] + player1: Player, + #[serde(with = "prefix_player2")] + player2: Option<Player>, + #[serde(with = "prefix_player3")] + player3: Option<Player>, + #[serde(with = "prefix_tag")] + tags: HashMap<String, String>, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Player { + name: String, + votes: u64, + } + + with_prefix!(prefix_player1 "player1_"); + with_prefix!(prefix_player2 "player2_"); + with_prefix!(prefix_player3 "player3_"); + with_prefix!(prefix_tag "tag_"); + + let m = Match { + player1: Player { + name: "name1".to_owned(), + votes: 1, + }, + player2: Some(Player { + name: "name2".to_owned(), + votes: 2, + }), + player3: None, + tags: { + let mut tags = HashMap::new(); + tags.insert("t".to_owned(), "T".to_owned()); + tags + }, + }; + + let expected = json!({ + "player1": { + "player1_name": "name1", + "player1_votes": 1, + }, + "player2": { + "player2_name": "name2", + "player2_votes": 2, + }, + "player3": null, + "tags": { + "tag_t": "T" + } + }); + + let j = serde_json::to_string(&m).unwrap(); + assert_eq!(j, expected.to_string()); + + assert_eq!(m, serde_json::from_str(&j).unwrap()); +} diff --git a/third_party/rust/serde_with_macros/.cargo-checksum.json b/third_party/rust/serde_with_macros/.cargo-checksum.json new file mode 100644 index 0000000000..ae7af88657 --- /dev/null +++ b/third_party/rust/serde_with_macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"5c5566da5a308015cfd18afd2d9db716601fd35a8b241beeedf10bb334f5ded4","Cargo.toml":"a5f76263232aa33cd38d1316ab6eb8a764ffd101a7277941330a827ccbcd820b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"dc4c1547049c0d11d544b1347aa67f4d947d761842c373729c2014dbb337e70b","src/lib.rs":"873adbaee30f72ee9c083c57711bbb1256d99fb6fdbe5e45c10e162861dca840","tests/compile-fail/skip-none-always.rs":"cdea0e110bc808f81c61d2ceb1394955b3af2be06261a85904e0e00a1948ff64","tests/compile-fail/skip-none-always.stderr":"cce5c9407f21b0a3eb880fb24cbb97a1e9ec22b21dcbd12963a745695175defd","tests/compile-fail/skip-none-not-struct.rs":"9212996740b302f2bd3b5298f439f8340c8cadddfb84212ddca975d5a78c4e12","tests/compile-fail/skip-none-not-struct.stderr":"0d1258fca42686eb120596c28d031935b1c22376954cebc858b0b7095d098e8e","tests/compiler-messages.rs":"06414ab54f1435839c79dcf649c577ec60c4c935a38967b1da989767c028f4e1","tests/skip_serializing_null.rs":"95c6c854d81f2b90e69455ae88f74b465919594920e34230374c9b8ceebfee77","tests/version_numbers.rs":"dccb4c715e3c4e6c08d9b779ad12122cded81becfde62fb54d2adf50171e5d83"},"package":"4070d2c9b9d258465ad1d82aabb985b84cd9a3afa94da25ece5a9938ba5f1606"}
\ No newline at end of file diff --git a/third_party/rust/serde_with_macros/CHANGELOG.md b/third_party/rust/serde_with_macros/CHANGELOG.md new file mode 100644 index 0000000000..19b09478af --- /dev/null +++ b/third_party/rust/serde_with_macros/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.1.0] + +### Changed + +* Bump minimal Rust version to 1.36.0 to support Rust Edition 2018 +* Improved CI pipeline by running `cargo audit` and `tarpaulin` in all configurations now. + +## [1.0.1] + +### Fixed + +* Features for the `syn` dependency were missing. + This was hidden due to the dev-dependencies whose features leaked into the normal build. + +## [1.0.0] + +Initial Release + +### Added + +* Add `skip_serializing_none` attribute, which adds `#[serde(skip_serializing_if = "Option::is_none")]` for each Option in a struct. + This is helpfull for APIs which have many optional fields. + The effect of can be negated by adding `serialize_always` on those fields, which should always be serialized. + Existing `skip_serializing_if` will never be modified and those fields keep their behavior. diff --git a/third_party/rust/serde_with_macros/Cargo.toml b/third_party/rust/serde_with_macros/Cargo.toml new file mode 100644 index 0000000000..ea8fd8dae5 --- /dev/null +++ b/third_party/rust/serde_with_macros/Cargo.toml @@ -0,0 +1,65 @@ +# 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_with_macros" +version = "1.1.0" +authors = ["jonasbb"] +description = "proc-macro library for serde_with" +documentation = "https://docs.rs/serde_with_macros/" +readme = "README.md" +keywords = ["serde", "utilities", "serialization", "deserialization"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/jonasbb/serde_with/tree/master/serde_with_macros" +[package.metadata.docs.rs] +all-features = true + +[lib] +proc-macro = true +[dependencies.proc-macro2] +version = "1.0.1" + +[dependencies.quote] +version = "1.0.0" + +[dependencies.syn] +version = "1.0.0" +features = ["full"] +[dev-dependencies.pretty_assertions] +version = "0.6.1" + +[dev-dependencies.rustversion] +version = "1.0.0" + +[dev-dependencies.serde] +version = "1.0.75" +features = ["derive"] + +[dev-dependencies.serde_json] +version = "1.0.25" + +[dev-dependencies.trybuild] +version = "1.0.14" + +[dev-dependencies.version-sync] +version = "0.8.1" +[badges.codecov] +branch = "master" +repository = "jonasbb/serde_with" +service = "github" + +[badges.maintenance] +status = "actively-developed" + +[badges.travis-ci] +branch = "master" +repository = "jonasbb/serde_with" diff --git a/third_party/rust/serde_with_macros/LICENSE-APACHE b/third_party/rust/serde_with_macros/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_with_macros/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/serde_with_macros/LICENSE-MIT b/third_party/rust/serde_with_macros/LICENSE-MIT new file mode 100644 index 0000000000..9203baa055 --- /dev/null +++ b/third_party/rust/serde_with_macros/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2015 + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_with_macros/README.md b/third_party/rust/serde_with_macros/README.md new file mode 100644 index 0000000000..ac02301fe9 --- /dev/null +++ b/third_party/rust/serde_with_macros/README.md @@ -0,0 +1,80 @@ +# Custom de/serialization functions for Rust's [serde](https://serde.rs) + +[![docs.rs badge](https://docs.rs/serde_with/badge.svg)](https://docs.rs/serde_with/) +[![crates.io badge](https://img.shields.io/crates/v/serde_with.svg)](https://crates.io/crates/serde_with/) +[![Build Status](https://travis-ci.org/jonasbb/serde_with.svg?branch=master)](https://travis-ci.org/jonasbb/serde_with) +[![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with) + +--- + +This crate provides custom de/serialization helpers to use in combination with [serde's with-annotation][with-annotation]. + +Serde tracks a wishlist of similar helpers at [serde#553]. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies.serde_with] +version = "1.4.0" +features = [ "..." ] +``` + +The crate is divided into different modules. +They contain helpers for external crates and must be enabled with the correspondig feature. + +Annotate your struct or enum to enable the custom de/serializer. + +```rust +#[derive(Deserialize, Serialize)] +struct Foo { + #[serde(with = "serde_with::rust::display_fromstr")] + bar: u8, +} +``` + +Most helpers implement both deserialize and serialize. +If you do not want to derive both, you can simply derive only the necessary parts. +If you want to mix different helpers, you can write your annotations like + +```rust +#[derive(Deserialize, Serialize)] +struct Foo { + #[serde( + deserialize_with = "serde_with::rust::display_fromstr::deserialize", + serialize_with = "serde_with::json::nested::serialize" + )] + bar: u8, +} +``` + +However, this will prohibit you from applying deserialize on the value returned by serializing a struct. + +## Attributes + +The crate comes with custom attributes, which futher extend how serde serialization can be customized. +They are enabled by default, but can be disabled, by removing the default features from this crate. + +The `serde_with` crate re-exports all items from `serde_with_macros`. +This means, if you want to use any proc_macros, import them like `use serde_with::skip_serializing_none`. + +[The documentation for the custom attributes can be found here.](serde_with_macros) + +[with-annotation]: https://serde.rs/field-attrs.html#serdewith--module +[serde#553]: https://github.com/serde-rs/serde/issues/553 + +## License + +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 the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/serde_with_macros/src/lib.rs b/third_party/rust/serde_with_macros/src/lib.rs new file mode 100644 index 0000000000..3975aff6ff --- /dev/null +++ b/third_party/rust/serde_with_macros/src/lib.rs @@ -0,0 +1,282 @@ +#![deny( + missing_debug_implementations, + missing_copy_implementations, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_import_braces, + unused_qualifications, + variant_size_differences +)] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] +#![doc(html_root_url = "https://docs.rs/serde_with_macros/1.1.0")] + +//! proc-macro extensions for [`serde_with`] +//! +//! This crate should not be used alone, but through the [`serde_with`] crate. +//! +//! [`serde_with`]: https://crates.io/crates/serde_with/ + +extern crate proc_macro; +extern crate proc_macro2; +extern crate quote; +extern crate syn; + +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use syn::{ + parse::Parser, Attribute, Error, Field, Fields, ItemEnum, ItemStruct, Meta, NestedMeta, Path, + Type, +}; + +/// Add `skip_serializing_if` annotations to [`Option`] fields. +/// +/// The attribute can be added to structs and enums. +/// +/// Import this attribute with `use serde_with::skip_serializing_none;`. +/// +/// # Example +/// +/// JSON APIs sometimes have many optional values. +/// Missing values should not be serialized, to keep the serialized format smaller. +/// Such a data type might look like: +/// +/// ```rust +/// # extern crate serde; +/// # use serde::Serialize; +/// # +/// #[derive(Serialize)] +/// struct Data { +/// #[serde(skip_serializing_if = "Option::is_none")] +/// a: Option<String>, +/// #[serde(skip_serializing_if = "Option::is_none")] +/// b: Option<u64>, +/// #[serde(skip_serializing_if = "Option::is_none")] +/// c: Option<String>, +/// #[serde(skip_serializing_if = "Option::is_none")] +/// d: Option<bool>, +/// } +/// ``` +/// +/// The `skip_serializing_if` annotation is repetitive and harms readability. +/// Instead the same struct can be written as: +/// +/// ```rust +/// # extern crate serde; +/// # extern crate serde_with_macros; +/// # +/// # use serde::Serialize; +/// # use serde_with_macros::skip_serializing_none; +/// #[skip_serializing_none] +/// #[derive(Serialize)] +/// struct Data { +/// a: Option<String>, +/// b: Option<u64>, +/// c: Option<String>, +/// d: Option<bool>, +/// } +/// ``` +/// +/// Existing `skip_serializing_if` annotations will not be altered. +/// +/// If some values should always be serialized, then the `serialize_always` can be used. +/// +/// # Limitations +/// +/// The `serialize_always` cannot be used together with a manual `skip_serializing_if` annotations, as these conflict in their meaning. +/// A compile error will be generated if this occurs. +/// +/// The `skip_serializing_none` only works if the type is called [`Option`], [`std::option::Option`], or [`core::option::Option`]. +/// Type aliasing an [`Option`] and giving it another name, will cause this field to be ignored. +/// This cannot be supported, as proc-macros run before type checking, thus it is not possible to determine if a type alias refers to an [`Option`]. +/// +/// ```rust,ignore +/// # extern crate serde; +/// # extern crate serde_with_macros; +/// # +/// # use serde::Serialize; +/// # use serde_with_macros::skip_serializing_none; +/// type MyOption<T> = Option<T>; +/// +/// #[skip_serializing_none] +/// #[derive(Serialize)] +/// struct Data { +/// a: MyOption<String>, // This field will not be skipped +/// } +/// ``` +/// +/// Likewise, if you import a type and name it `Option`, the `skip_serializing_if` attributes will be added and compile errors will occur, if `Option::is_none` is not a valid function. +/// Here the function `Vec::is_none` does not exist and therefore the example fails to compile. +/// +/// ```rust,compile_fail +/// # extern crate serde; +/// # extern crate serde_with_macros; +/// # +/// # use serde::Serialize; +/// # use serde_with_macros::skip_serializing_none; +/// use std::vec::Vec as Option; +/// +/// #[skip_serializing_none] +/// #[derive(Serialize)] +/// struct Data { +/// a: Option<String>, +/// } +/// ``` +/// +#[proc_macro_attribute] +pub fn skip_serializing_none(_args: TokenStream, input: TokenStream) -> TokenStream { + let res = match skip_serializing_none_do(input) { + Ok(res) => res, + Err(msg) => { + let span = Span::call_site(); + Error::new(span, msg).to_compile_error() + } + }; + TokenStream::from(res) +} + +fn skip_serializing_none_do(input: TokenStream) -> Result<proc_macro2::TokenStream, String> { + // For each field in the struct given by `input`, add the `skip_serializing_if` attribute, + // if and only if, it is of type `Option` + if let Ok(mut input) = syn::parse::<ItemStruct>(input.clone()) { + skip_serializing_none_handle_fields(&mut input.fields)?; + Ok(quote!(#input)) + } else if let Ok(mut input) = syn::parse::<ItemEnum>(input) { + input + .variants + .iter_mut() + .map(|variant| skip_serializing_none_handle_fields(&mut variant.fields)) + .collect::<Result<(), _>>()?; + Ok(quote!(#input)) + } else { + Err("The attribute can only be applied to struct or enum definitions.".into()) + } +} + +/// Return `true`, if the type path refers to `std::option::Option` +/// +/// Accepts +/// +/// * `Option` +/// * `std::option::Option`, with or without leading `::` +/// * `core::option::Option`, with or without leading `::` +fn is_std_option(path: &Path) -> bool { + (path.leading_colon.is_none() && path.segments.len() == 1 && path.segments[0].ident == "Option") + || (path.segments.len() == 3 + && (path.segments[0].ident == "std" || path.segments[0].ident == "core") + && path.segments[1].ident == "option" + && path.segments[2].ident == "Option") +} + +/// Determine if the `field` has an attribute with given `namespace` and `name` +/// +/// On the example of +/// `#[serde(skip_serializing_if = "Option::is_none")]` +// +/// * `serde` is the outermost path, here namespace +/// * it contains a Meta::List +/// * which contains in another Meta a Meta::NameValue +/// * with the name being `skip_serializing_if` +#[cfg_attr(feature = "cargo-clippy", allow(cmp_owned))] +fn field_has_attribute(field: &Field, namespace: &str, name: &str) -> bool { + // On the example of + // #[serde(skip_serializing_if = "Option::is_none")] + // + // `serde` is the outermost path, here namespace + // it contains a Meta::List + // which contains in another Meta a Meta::NameValue + // with the name being `skip_serializing_if` + + for attr in &field.attrs { + if attr.path.is_ident(namespace) { + // Ignore non parsable attributes, as these are not important for us + if let Ok(expr) = attr.parse_meta() { + if let Meta::List(expr) = expr { + for expr in expr.nested { + if let NestedMeta::Meta(Meta::NameValue(expr)) = expr { + if let Some(ident) = expr.path.get_ident() { + if ident.to_string() == name { + return true; + } + } + } + } + } + } + } + } + false +} + +/// Add the skip_serializing_if annotation to each field of the struct +fn skip_serializing_none_add_attr_to_field<'a>( + fields: impl IntoIterator<Item = &'a mut Field>, +) -> Result<(), String> { + fields.into_iter().map(|field| ->Result<(), String> { + if let Type::Path(path) = &field.ty.clone() { + if is_std_option(&path.path) { + let has_skip_serializing_if = + field_has_attribute(&field, "serde", "skip_serializing_if"); + + // Remove the `serialize_always` attribute + let mut has_always_attr = false; + field.attrs.retain(|attr| { + let has_attr = attr.path.is_ident("serialize_always"); + has_always_attr |= has_attr; + !has_attr + }); + + // Error on conflicting attributes + if has_always_attr && has_skip_serializing_if { + let mut msg = r#"The attributes `serialize_always` and `serde(skip_serializing_if = "...")` cannot be used on the same field"#.to_string(); + if let Some(ident) = &field.ident { + msg += ": `"; + msg += &ident.to_string(); + msg += "`"; + } + msg +="."; + return Err(msg); + } + + // Do nothing if `skip_serializing_if` or `serialize_always` is already present + if has_skip_serializing_if || has_always_attr { + return Ok(()); + } + + // Add the `skip_serializing_if` attribute + let attr_tokens = quote!( + #[serde(skip_serializing_if = "Option::is_none")] + ); + let parser = Attribute::parse_outer; + let attrs = parser + .parse2(attr_tokens) + .expect("Static attr tokens should not panic"); + field.attrs.extend(attrs); + } else { + // Warn on use of `serialize_always` on non-Option fields + let has_attr= field.attrs.iter().any(|attr| { + attr.path.is_ident("serialize_always") + }); + if has_attr { + return Err("`serialize_always` may only be used on fields of type `Option`.".into()); + } + } + } + Ok(()) + }).collect() +} + +/// Handle a single struct or a single enum variant +fn skip_serializing_none_handle_fields(fields: &mut Fields) -> Result<(), String> { + match fields { + // simple, no fields, do nothing + Fields::Unit => Ok(()), + Fields::Named(ref mut fields) => { + skip_serializing_none_add_attr_to_field(fields.named.iter_mut()) + } + Fields::Unnamed(ref mut fields) => { + skip_serializing_none_add_attr_to_field(fields.unnamed.iter_mut()) + } + } +} diff --git a/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-always.rs b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-always.rs new file mode 100644 index 0000000000..b52272439b --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-always.rs @@ -0,0 +1,30 @@ +extern crate serde; +extern crate serde_with_macros; + +use serde::Serialize; +use serde_with_macros::skip_serializing_none; + +#[skip_serializing_none] +#[derive(Serialize)] +struct Data { + #[serialize_always] + #[serde(skip_serializing_if = "Option::is_none")] + a: Option<char>, +} + +#[skip_serializing_none] +#[derive(Serialize)] +struct Data2( + #[serialize_always] + #[serde(skip_serializing_if = "Option::is_none")] + Option<char>, +); + +#[skip_serializing_none] +#[derive(Serialize)] +struct Data3 { + #[serialize_always] + a: char, +} + +fn main() {} diff --git a/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-always.stderr b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-always.stderr new file mode 100644 index 0000000000..226d7b55c8 --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-always.stderr @@ -0,0 +1,17 @@ +error: The attributes `serialize_always` and `serde(skip_serializing_if = "...")` cannot be used on the same field: `a`. + --> $DIR/skip-none-always.rs:7:1 + | +7 | #[skip_serializing_none] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The attributes `serialize_always` and `serde(skip_serializing_if = "...")` cannot be used on the same field. + --> $DIR/skip-none-always.rs:15:1 + | +15 | #[skip_serializing_none] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `serialize_always` may only be used on fields of type `Option`. + --> $DIR/skip-none-always.rs:23:1 + | +23 | #[skip_serializing_none] + | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-not-struct.rs b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-not-struct.rs new file mode 100644 index 0000000000..f6776db778 --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-not-struct.rs @@ -0,0 +1,8 @@ +extern crate serde_with_macros; + +use serde_with_macros::skip_serializing_none; + +#[skip_serializing_none] +fn test() {} + +fn main() {} diff --git a/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-not-struct.stderr b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-not-struct.stderr new file mode 100644 index 0000000000..479fa7ea75 --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/compile-fail/skip-none-not-struct.stderr @@ -0,0 +1,5 @@ +error: The attribute can only be applied to struct or enum definitions. + --> $DIR/skip-none-not-struct.rs:5:1 + | +5 | #[skip_serializing_none] + | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/serde_with_macros/tests/compiler-messages.rs b/third_party/rust/serde_with_macros/tests/compiler-messages.rs new file mode 100644 index 0000000000..01373a3d3b --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/compiler-messages.rs @@ -0,0 +1,15 @@ +extern crate rustversion; +extern crate trybuild; + +// This test fails for older compiler versions since the error messages are different. +#[rustversion::attr(before(1.35), ignore)] +#[test] +fn compile_test() { + // This test does not work under tarpaulin, so skip it if detected + if std::env::var("TARPAULIN") == Ok("1".to_string()) { + return; + } + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/compile-fail/*.rs"); +} diff --git a/third_party/rust/serde_with_macros/tests/skip_serializing_null.rs b/third_party/rust/serde_with_macros/tests/skip_serializing_null.rs new file mode 100644 index 0000000000..7fb43bc923 --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/skip_serializing_null.rs @@ -0,0 +1,154 @@ +extern crate pretty_assertions; +extern crate serde; +extern crate serde_json; +extern crate serde_with_macros; + +use pretty_assertions::assert_eq; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use serde_with_macros::skip_serializing_none; + +macro_rules! test { + ($fn:ident, $struct:ident) => { + #[test] + fn $fn() { + let expected = json!({}); + let data = $struct { + a: None, + b: None, + c: None, + d: None, + }; + let res = serde_json::to_value(&data).unwrap(); + assert_eq!(expected, res); + assert_eq!(data, serde_json::from_value(res).unwrap()); + } + }; +} + +macro_rules! test_tuple { + ($fn:ident, $struct:ident) => { + #[test] + fn $fn() { + let expected = json!([]); + let data = $struct(None, None); + let res = serde_json::to_value(&data).unwrap(); + assert_eq!(expected, res); + } + }; +} + +#[skip_serializing_none] +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] +struct DataBasic { + a: Option<String>, + b: Option<String>, + c: Option<String>, + d: Option<String>, +} +test!(test_basic, DataBasic); + +#[skip_serializing_none] +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] +struct DataFullyQualified { + a: ::std::option::Option<String>, + b: std::option::Option<String>, + c: ::std::option::Option<i64>, + d: core::option::Option<String>, +} +test!(test_fully_qualified, DataFullyQualified); + +fn never<T>(_t: &T) -> bool { + false +} + +#[skip_serializing_none] +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] +struct DataExistingAnnotation { + #[serde(skip_serializing_if = "Option::is_none")] + a: Option<String>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "abc")] + b: Option<String>, + #[serde(default)] + c: Option<String>, + #[serde(skip_serializing_if = "never")] + #[serde(rename = "name")] + d: Option<String>, +} + +#[test] +fn test_existing_annotation() { + let expected = json!({ "name": null }); + let data = DataExistingAnnotation { + a: None, + b: None, + c: None, + d: None, + }; + let res = serde_json::to_value(&data).unwrap(); + assert_eq!(expected, res); + assert_eq!(data, serde_json::from_value(res).unwrap()); +} + +#[skip_serializing_none] +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] +struct DataSerializeAlways { + #[serialize_always] + a: Option<String>, + #[serialize_always] + b: Option<String>, + c: i64, + #[serialize_always] + d: Option<String>, +} + +#[test] +fn test_serialize_always() { + let expected = json!({ + "a": null, + "b": null, + "c": 0, + "d": null + }); + let data = DataSerializeAlways { + a: None, + b: None, + c: 0, + d: None, + }; + let res = serde_json::to_value(&data).unwrap(); + assert_eq!(expected, res); + assert_eq!(data, serde_json::from_value(res).unwrap()); +} + +#[skip_serializing_none] +#[derive(Debug, Eq, PartialEq, Serialize)] +struct DataTuple(Option<String>, std::option::Option<String>); +test_tuple!(test_tuple, DataTuple); + +#[skip_serializing_none] +#[derive(Debug, Eq, PartialEq, Serialize)] +enum DataEnum { + Tuple(Option<i64>, std::option::Option<bool>), + Struct { + a: Option<String>, + b: Option<String>, + }, +} + +#[test] +fn test_enum() { + let expected = json!({ + "Tuple": [] + }); + let data = DataEnum::Tuple(None, None); + let res = serde_json::to_value(&data).unwrap(); + assert_eq!(expected, res); + + let expected = json!({ + "Struct": {} + }); + let data = DataEnum::Struct { a: None, b: None }; + let res = serde_json::to_value(&data).unwrap(); + assert_eq!(expected, res); +} diff --git a/third_party/rust/serde_with_macros/tests/version_numbers.rs b/third_party/rust/serde_with_macros/tests/version_numbers.rs new file mode 100644 index 0000000000..9cbd3b3a5a --- /dev/null +++ b/third_party/rust/serde_with_macros/tests/version_numbers.rs @@ -0,0 +1,6 @@ +extern crate version_sync; + +#[test] +fn test_html_root_url() { + version_sync::assert_html_root_url_updated!("src/lib.rs"); +} diff --git a/third_party/rust/serde_yaml/.cargo-checksum.json b/third_party/rust/serde_yaml/.cargo-checksum.json new file mode 100644 index 0000000000..cbd13f5302 --- /dev/null +++ b/third_party/rust/serde_yaml/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"75bea36047240bd0d97dd59cc9d2160adfb373d479ec11eb0c96abf135586a18","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"50abe9dec9d36b15c09099de2345d502efff6e8e228656471c1ae5cf7141e13e","src/de.rs":"7c5bc01ded815e291078b4c6243d5342d9f4ca7805e3510b41ffd5b956aa25e5","src/error.rs":"854da7bf4af0d9457cc0dc874d15fac2c6d91bb3cbda1a19f0a8d5021030a133","src/lib.rs":"967acc60b53c9238c86005c4ea49708cbe29d4f820ed05980100c65117165ab8","src/mapping.rs":"9170d4d8a9e16ed877f72d2e0468f21867aee52835b2e61cf6d671851d87d348","src/number.rs":"2e3ce953883f443f7069b41dc04a541abebccb98a45873376eb2e1c5463f775d","src/path.rs":"ab4ec285cf3d67aaf0c39b4194aaaa8af4ce81ee7390a47f3a311b23712d9bcc","src/ser.rs":"6b215de0379e60581bfbc5c89ee4da2cc3ea0103759abbadc1c530f5a67a37eb","src/value/de.rs":"cbd3b56f2c3408ea8f0b810ef3a715ac03897b5d31b9b21bdbfe881063655e08","src/value/from.rs":"b32ca53c0f25603f84bb022fc1b03421d94a69276b66c3159b468383bd5af203","src/value/index.rs":"14fe6fd61d677cef7af26a289bbb5233c1cb82fe7afa48dedff642a0c6e5aeb5","src/value/mod.rs":"78cc1cbcd8ab90db30fdf2868df9c50195e698470650633f205d752f849fe6f3","src/value/partial_eq.rs":"c71c5a2a3ab16d1eb906fa98f920675e2794c49ffcdfbb3e9bfe4b7f90de7f8f","src/value/ser.rs":"404b263f9c74c687f6177d9d3292ac58ac281ed44b29c1dde872cc571410b84c","tests/test_de.rs":"6b93f26070088364b841c01a102caa3c9dbaa38d99ed184dbfd7e8b97c3bc6a8","tests/test_error.rs":"ab5858a0b3b7d5fcfbaeed0a96d4928b440d37e3373dfbdee9a7ca55ff7dd469","tests/test_serde.rs":"08f1b4503a13589ec27efecc52814959160bf9ab69f61752dc352d6baac1606f","tests/test_visitor.rs":"fe4ac13ff17297ad2cb77175448f03b21d3cdcc1dd375002a55c33f6ecceccb2","tests/version-numbers.rs":"0d75532e72e9054cb8c8c12b8851e55fad7319ed14482b562f6806872f18dd0f"},"package":"38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582"}
\ No newline at end of file diff --git a/third_party/rust/serde_yaml/Cargo.toml b/third_party/rust/serde_yaml/Cargo.toml new file mode 100644 index 0000000000..7fc40a9209 --- /dev/null +++ b/third_party/rust/serde_yaml/Cargo.toml @@ -0,0 +1,43 @@ +# 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_yaml" +version = "0.8.9" +authors = ["David Tolnay <dtolnay@gmail.com>"] +description = "YAML support for Serde" +documentation = "https://docs.rs/serde_yaml/" +readme = "README.md" +keywords = ["yaml", "serde"] +license = "MIT/Apache-2.0" +repository = "https://github.com/dtolnay/serde-yaml" +[dependencies.dtoa] +version = "0.4" + +[dependencies.linked-hash-map] +version = "0.5" + +[dependencies.serde] +version = "1.0.60" + +[dependencies.yaml-rust] +version = "0.4" +[dev-dependencies.serde_derive] +version = "1.0" + +[dev-dependencies.unindent] +version = "0.1" + +[dev-dependencies.version-sync] +version = "0.5" +[badges.travis-ci] +repository = "dtolnay/serde-yaml" diff --git a/third_party/rust/serde_yaml/LICENSE-APACHE b/third_party/rust/serde_yaml/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/serde_yaml/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/serde_yaml/LICENSE-MIT b/third_party/rust/serde_yaml/LICENSE-MIT new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/third_party/rust/serde_yaml/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/serde_yaml/README.md b/third_party/rust/serde_yaml/README.md new file mode 100644 index 0000000000..fabaac4373 --- /dev/null +++ b/third_party/rust/serde_yaml/README.md @@ -0,0 +1,103 @@ +Serde YAML +========== + +[![Build Status](https://api.travis-ci.org/dtolnay/serde-yaml.svg?branch=master)][travis] +[![Latest Version](https://img.shields.io/crates/v/serde_yaml.svg)][crates.io] +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)][docs.rs] + +[travis]: https://travis-ci.org/dtolnay/serde-yaml +[crates.io]: https://crates.io/crates/serde_yaml +[docs.rs]: https://docs.rs/serde_yaml + +This crate is a Rust library for using the [Serde] serialization framework with +data in [YAML] file format. + +[Serde]: https://github.com/serde-rs/serde +[YAML]: http://yaml.org + +This library does not reimplement a YAML parser; it uses [yaml-rust] which is a +pure Rust YAML 1.2 implementation. + +[yaml-rust]: https://github.com/chyh1990/yaml-rust + +## Dependency + +```toml +[dependencies] +serde = "1.0" +serde_yaml = "0.8" +``` + +Release notes are available under [GitHub releases]. + +[GitHub releases]: https://github.com/dtolnay/serde-yaml/releases + +## Using Serde YAML + +[API documentation is available in rustdoc form][docs.rs] but the general idea +is: + +```rust +use std::collections::BTreeMap; + +fn main() -> Result<(), serde_yaml::Error> { + // You have some type. + let mut map = BTreeMap::new(); + map.insert("x".to_string(), 1.0); + map.insert("y".to_string(), 2.0); + + // Serialize it to a YAML string. + let s = serde_yaml::to_string(&map)?; + assert_eq!(s, "---\nx: 1\ny: 2"); + + // Deserialize it back to a Rust type. + let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?; + assert_eq!(map, deserialized_map); + Ok(()) +} +``` + +It can also be used with Serde's derive macros to handle structs and enums +defined by your program. + +```toml +[dependencies] +serde = { version = "1.0", features = ["derive"] } +serde_yaml = "0.8" +``` + +```rust +use serde::{Serialize, Deserialize}; + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +struct Point { + x: f64, + y: f64, +} + +fn main() -> Result<(), serde_yaml::Error> { + let point = Point { x: 1.0, y: 2.0 }; + + let s = serde_yaml::to_string(&point)?; + assert_eq!(s, "---\nx: 1\ny: 2"); + + let deserialized_point: Point = serde_yaml::from_str(&s)?; + assert_eq!(point, deserialized_point); + Ok(()) +} +``` + +## License + +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 YAML by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/serde_yaml/src/de.rs b/third_party/rust/serde_yaml/src/de.rs new file mode 100644 index 0000000000..959ad302dd --- /dev/null +++ b/third_party/rust/serde_yaml/src/de.rs @@ -0,0 +1,1079 @@ +//! YAML Deserialization +//! +//! This module provides YAML deserialization with the type `Deserializer`. + +use std::collections::BTreeMap; +use std::f64; +use std::fmt; +use std::io; +use std::str; + +use yaml_rust::parser::{Event as YamlEvent, MarkedEventReceiver, Parser}; +use yaml_rust::scanner::{Marker, TScalarStyle, TokenType}; + +use serde::de::IgnoredAny as Ignore; +use serde::de::{ + self, Deserialize, DeserializeOwned, DeserializeSeed, Expected, IntoDeserializer, Unexpected, + Visitor, +}; + +use error::{Error, Result}; +use path::Path; +use private; + +pub struct Loader { + events: Vec<(Event, Marker)>, + /// Map from alias id to index in events. + aliases: BTreeMap<usize, usize>, +} + +impl MarkedEventReceiver for Loader { + fn on_event(&mut self, event: YamlEvent, marker: Marker) { + let event = match event { + YamlEvent::Nothing + | YamlEvent::StreamStart + | YamlEvent::StreamEnd + | YamlEvent::DocumentStart + | YamlEvent::DocumentEnd => return, + + YamlEvent::Alias(id) => Event::Alias(id), + YamlEvent::Scalar(value, style, id, tag) => { + self.aliases.insert(id, self.events.len()); + Event::Scalar(value, style, tag) + } + YamlEvent::SequenceStart(id) => { + self.aliases.insert(id, self.events.len()); + Event::SequenceStart + } + YamlEvent::SequenceEnd => Event::SequenceEnd, + YamlEvent::MappingStart(id) => { + self.aliases.insert(id, self.events.len()); + Event::MappingStart + } + YamlEvent::MappingEnd => Event::MappingEnd, + }; + self.events.push((event, marker)); + } +} + +#[derive(Debug, PartialEq)] +enum Event { + Alias(usize), + Scalar(String, TScalarStyle, Option<TokenType>), + SequenceStart, + SequenceEnd, + MappingStart, + MappingEnd, +} + +struct Deserializer<'a> { + events: &'a [(Event, Marker)], + /// Map from alias id to index in events. + aliases: &'a BTreeMap<usize, usize>, + pos: &'a mut usize, + path: Path<'a>, + remaining_depth: u8, +} + +impl<'a> Deserializer<'a> { + fn peek(&self) -> Result<(&'a Event, Marker)> { + match self.events.get(*self.pos) { + Some(event) => Ok((&event.0, event.1)), + None => Err(private::error_end_of_stream()), + } + } + + fn next(&mut self) -> Result<(&'a Event, Marker)> { + self.opt_next().ok_or_else(private::error_end_of_stream) + } + + fn opt_next(&mut self) -> Option<(&'a Event, Marker)> { + self.events.get(*self.pos).map(|event| { + *self.pos += 1; + (&event.0, event.1) + }) + } + + fn jump(&'a self, pos: &'a mut usize) -> Result<Deserializer<'a>> { + match self.aliases.get(pos) { + Some(&found) => { + *pos = found; + Ok(Deserializer { + events: self.events, + aliases: self.aliases, + pos: pos, + path: Path::Alias { parent: &self.path }, + remaining_depth: self.remaining_depth, + }) + } + None => panic!("unresolved alias: {}", *pos), + } + } + + fn ignore_any(&mut self) -> Result<()> { + enum Nest { + Sequence, + Mapping, + } + + let mut stack = Vec::new(); + + while let Some((event, _)) = self.opt_next() { + match *event { + Event::Alias(_) | Event::Scalar(_, _, _) => {} + Event::SequenceStart => { + stack.push(Nest::Sequence); + } + Event::MappingStart => { + stack.push(Nest::Mapping); + } + Event::SequenceEnd => match stack.pop() { + Some(Nest::Sequence) => {} + None | Some(Nest::Mapping) => { + panic!("unexpected end of sequence"); + } + }, + Event::MappingEnd => match stack.pop() { + Some(Nest::Mapping) => {} + None | Some(Nest::Sequence) => { + panic!("unexpected end of mapping"); + } + }, + } + if stack.is_empty() { + return Ok(()); + } + } + + if !stack.is_empty() { + panic!("missing end event"); + } + + Ok(()) + } + + fn visit_sequence<'de, V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (value, len) = self.recursion_check(|de| { + let mut seq = SeqAccess { de: de, len: 0 }; + let value = visitor.visit_seq(&mut seq)?; + Ok((value, seq.len)) + })?; + self.end_sequence(len)?; + Ok(value) + } + + fn visit_mapping<'de, V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (value, len) = self.recursion_check(|de| { + let mut map = MapAccess { + de: de, + len: 0, + key: None, + }; + let value = visitor.visit_map(&mut map)?; + Ok((value, map.len)) + })?; + self.end_mapping(len)?; + Ok(value) + } + + fn end_sequence(&mut self, len: usize) -> Result<()> { + let total = { + let mut seq = SeqAccess { de: self, len: len }; + while de::SeqAccess::next_element::<Ignore>(&mut seq)?.is_some() {} + seq.len + }; + assert_eq!(Event::SequenceEnd, *self.next()?.0); + if total == len { + Ok(()) + } else { + struct ExpectedSeq(usize); + impl Expected for ExpectedSeq { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.0 == 1 { + write!(formatter, "sequence of 1 element") + } else { + write!(formatter, "sequence of {} elements", self.0) + } + } + } + Err(de::Error::invalid_length(total, &ExpectedSeq(len))) + } + } + + fn end_mapping(&mut self, len: usize) -> Result<()> { + let total = { + let mut map = MapAccess { + de: self, + len: len, + key: None, + }; + while de::MapAccess::next_entry::<Ignore, Ignore>(&mut map)?.is_some() {} + map.len + }; + assert_eq!(Event::MappingEnd, *self.next()?.0); + if total == len { + Ok(()) + } else { + struct ExpectedMap(usize); + impl Expected for ExpectedMap { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.0 == 1 { + write!(formatter, "map containing 1 entry") + } else { + write!(formatter, "map containing {} entries", self.0) + } + } + } + Err(de::Error::invalid_length(total, &ExpectedMap(len))) + } + } + + fn recursion_check<F: FnOnce(&mut Self) -> Result<T>, T>(&mut self, f: F) -> Result<T> { + let previous_depth = self.remaining_depth; + self.remaining_depth = previous_depth + .checked_sub(1) + .ok_or_else(private::error_recursion_limit_exceeded)?; + let result = f(self); + self.remaining_depth = previous_depth; + result + } +} + +fn visit_scalar<'de, V>( + v: &str, + style: TScalarStyle, + tag: &Option<TokenType>, + visitor: V, +) -> Result<V::Value> +where + V: Visitor<'de>, +{ + if style != TScalarStyle::Plain { + visitor.visit_str(v) + } else if let Some(TokenType::Tag(ref handle, ref suffix)) = *tag { + if handle == "!!" { + match suffix.as_ref() { + "bool" => match v.parse::<bool>() { + Ok(v) => visitor.visit_bool(v), + Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"a boolean")), + }, + "int" => match v.parse::<i64>() { + Ok(v) => visitor.visit_i64(v), + Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"an integer")), + }, + "float" => match v.parse::<f64>() { + Ok(v) => visitor.visit_f64(v), + Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"a float")), + }, + "null" => match v { + "~" | "null" => visitor.visit_unit(), + _ => Err(de::Error::invalid_value(Unexpected::Str(v), &"null")), + }, + _ => visitor.visit_str(v), + } + } else { + visitor.visit_str(v) + } + } else { + visit_untagged_str(visitor, v) + } +} + +struct SeqAccess<'a: 'r, 'r> { + de: &'r mut Deserializer<'a>, + len: usize, +} + +impl<'de, 'a, 'r> de::SeqAccess<'de> for SeqAccess<'a, 'r> { + type Error = Error; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> + where + T: DeserializeSeed<'de>, + { + match *self.de.peek()?.0 { + Event::SequenceEnd => Ok(None), + _ => { + let mut element_de = Deserializer { + events: self.de.events, + aliases: self.de.aliases, + pos: self.de.pos, + path: Path::Seq { + parent: &self.de.path, + index: self.len, + }, + remaining_depth: self.de.remaining_depth, + }; + self.len += 1; + seed.deserialize(&mut element_de).map(Some) + } + } + } +} + +struct MapAccess<'a: 'r, 'r> { + de: &'r mut Deserializer<'a>, + len: usize, + key: Option<&'a str>, +} + +impl<'de, 'a, 'r> de::MapAccess<'de> for MapAccess<'a, 'r> { + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>> + where + K: DeserializeSeed<'de>, + { + match *self.de.peek()?.0 { + Event::MappingEnd => Ok(None), + Event::Scalar(ref key, _, _) => { + self.len += 1; + self.key = Some(key); + seed.deserialize(&mut *self.de).map(Some) + } + _ => { + self.len += 1; + self.key = None; + seed.deserialize(&mut *self.de).map(Some) + } + } + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> + where + V: DeserializeSeed<'de>, + { + let mut value_de = Deserializer { + events: self.de.events, + aliases: self.de.aliases, + pos: self.de.pos, + path: if let Some(key) = self.key { + Path::Map { + parent: &self.de.path, + key: key, + } + } else { + Path::Unknown { + parent: &self.de.path, + } + }, + remaining_depth: self.de.remaining_depth, + }; + seed.deserialize(&mut value_de) + } +} + +struct EnumAccess<'a: 'r, 'r> { + de: &'r mut Deserializer<'a>, + name: &'static str, + tag: Option<&'static str>, +} + +impl<'de, 'a, 'r> de::EnumAccess<'de> for EnumAccess<'a, 'r> { + type Error = Error; + type Variant = Deserializer<'r>; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)> + where + V: DeserializeSeed<'de>, + { + #[derive(Debug)] + enum Nope {} + + struct BadKey { + name: &'static str, + } + + impl<'de> Visitor<'de> for BadKey { + type Value = Nope; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "variant of enum `{}`", self.name) + } + } + + let variant = if let Some(tag) = self.tag { + tag + } else { + match *self.de.next()?.0 { + Event::Scalar(ref s, _, _) => &**s, + _ => { + *self.de.pos -= 1; + let bad = BadKey { name: self.name }; + return Err(de::Deserializer::deserialize_any(&mut *self.de, bad).unwrap_err()); + } + } + }; + + let str_de = IntoDeserializer::<Error>::into_deserializer(variant); + let ret = seed.deserialize(str_de)?; + let variant_visitor = Deserializer { + events: self.de.events, + aliases: self.de.aliases, + pos: self.de.pos, + path: Path::Map { + parent: &self.de.path, + key: variant, + }, + remaining_depth: self.de.remaining_depth, + }; + Ok((ret, variant_visitor)) + } +} + +impl<'de, 'a> de::VariantAccess<'de> for Deserializer<'a> { + type Error = Error; + + fn unit_variant(mut self) -> Result<()> { + Deserialize::deserialize(&mut self) + } + + fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value> + where + T: DeserializeSeed<'de>, + { + seed.deserialize(&mut self) + } + + fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + de::Deserializer::deserialize_seq(&mut self, visitor) + } + + fn struct_variant<V>(mut self, fields: &'static [&'static str], visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + de::Deserializer::deserialize_struct(&mut self, "", fields, visitor) + } +} + +struct UnitVariantAccess<'a: 'r, 'r> { + de: &'r mut Deserializer<'a>, +} + +impl<'de, 'a, 'r> de::EnumAccess<'de> for UnitVariantAccess<'a, 'r> { + type Error = Error; + type Variant = Self; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)> + where + V: DeserializeSeed<'de>, + { + Ok((seed.deserialize(&mut *self.de)?, self)) + } +} + +impl<'de, 'a, 'r> de::VariantAccess<'de> for UnitVariantAccess<'a, 'r> { + type Error = Error; + + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value> + where + T: DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } +} + +fn visit_untagged_str<'de, V>(visitor: V, v: &str) -> Result<V::Value> +where + V: Visitor<'de>, +{ + if v == "~" || v == "null" { + return visitor.visit_unit(); + } + if v == "true" { + return visitor.visit_bool(true); + } + if v == "false" { + return visitor.visit_bool(false); + } + if v.starts_with("0x") || v.starts_with("+0x") { + let start = 2 + v.starts_with('+') as usize; + if let Ok(n) = u64::from_str_radix(&v[start..], 16) { + return visitor.visit_u64(n); + } + } + if v.starts_with("-0x") { + let negative = format!("-{}", &v[3..]); + if let Ok(n) = i64::from_str_radix(&negative, 16) { + return visitor.visit_i64(n); + } + } + if v.starts_with("0o") || v.starts_with("+0o") { + let start = 2 + v.starts_with('+') as usize; + if let Ok(n) = u64::from_str_radix(&v[start..], 8) { + return visitor.visit_u64(n); + } + } + if v.starts_with("-0o") { + let negative = format!("-{}", &v[3..]); + if let Ok(n) = i64::from_str_radix(&negative, 8) { + return visitor.visit_i64(n); + } + } + if v.starts_with("0b") || v.starts_with("+0b") { + let start = 2 + v.starts_with('+') as usize; + if let Ok(n) = u64::from_str_radix(&v[start..], 2) { + return visitor.visit_u64(n); + } + } + if v.starts_with("-0b") { + let negative = format!("-{}", &v[3..]); + if let Ok(n) = i64::from_str_radix(&negative, 2) { + return visitor.visit_i64(n); + } + } + if let Ok(n) = v.parse() { + return visitor.visit_u64(n); + } + serde_if_integer128! { + if let Ok(n) = v.parse() { + return visitor.visit_u128(n); + } + } + if let Ok(n) = v.parse() { + return visitor.visit_i64(n); + } + serde_if_integer128! { + if let Ok(n) = v.parse() { + return visitor.visit_i128(n); + } + } + match trim_start_matches(v, '+') { + ".inf" | ".Inf" | ".INF" => return visitor.visit_f64(f64::INFINITY), + _ => (), + } + if v == "-.inf" || v == "-.Inf" || v == "-.INF" { + return visitor.visit_f64(f64::NEG_INFINITY); + } + if v == ".nan" || v == ".NaN" || v == ".NAN" { + return visitor.visit_f64(f64::NAN); + } + if let Ok(n) = v.parse() { + return visitor.visit_f64(n); + } + visitor.visit_str(v) +} + +#[allow(deprecated)] +fn trim_start_matches(s: &str, pat: char) -> &str { + // str::trim_start_matches was added in 1.30, trim_left_matches deprecated + // in 1.33. We currently support rustc back to 1.17 so we need to continue + // to use the deprecated one. + s.trim_left_matches(pat) +} + +fn invalid_type(event: &Event, exp: &Expected) -> Error { + enum Void {} + + struct InvalidType<'a> { + exp: &'a Expected, + } + + impl<'de, 'a> Visitor<'de> for InvalidType<'a> { + type Value = Void; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.exp.fmt(formatter) + } + } + + match *event { + Event::Alias(_) => unreachable!(), + Event::Scalar(ref v, style, ref tag) => { + let get_type = InvalidType { exp: exp }; + match visit_scalar(v, style, tag, get_type) { + Ok(void) => match void {}, + Err(invalid_type) => invalid_type, + } + } + Event::SequenceStart => de::Error::invalid_type(Unexpected::Seq, exp), + Event::MappingStart => de::Error::invalid_type(Unexpected::Map, exp), + Event::SequenceEnd => panic!("unexpected end of sequence"), + Event::MappingEnd => panic!("unexpected end of mapping"), + } +} + +impl<'a> Deserializer<'a> { + fn deserialize_scalar<'de, V>(&mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.next()?; + match *next { + Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_scalar(visitor), + Event::Scalar(ref v, style, ref tag) => visit_scalar(v, style, tag, visitor), + ref other => Err(invalid_type(other, &visitor)), + } + .map_err(|err| private::fix_marker(err, marker, self.path)) + } +} + +impl<'de, 'a, 'r> de::Deserializer<'de> for &'r mut Deserializer<'a> { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.next()?; + match *next { + Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_any(visitor), + Event::Scalar(ref v, style, ref tag) => visit_scalar(v, style, tag, visitor), + Event::SequenceStart => self.visit_sequence(visitor), + Event::MappingStart => self.visit_mapping(visitor), + Event::SequenceEnd => panic!("unexpected end of sequence"), + Event::MappingEnd => panic!("unexpected end of mapping"), + } + // 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. + .map_err(|err| private::fix_marker(err, marker, self.path)) + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + serde_if_integer128! { + fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + serde_if_integer128! { + fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + } + + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.next()?; + match *next { + Event::Scalar(ref v, _, _) => visitor.visit_str(v), + Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_str(visitor), + ref other => Err(invalid_type(other, &visitor)), + } + .map_err(|err: Error| private::fix_marker(err, marker, self.path)) + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_any(visitor) + } + + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + /// Parses `null` as None and any other values as `Some(...)`. + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let is_some = match *self.peek()?.0 { + Event::Alias(mut pos) => { + *self.pos += 1; + return self.jump(&mut pos)?.deserialize_option(visitor); + } + Event::Scalar(ref v, style, ref tag) => { + if style != TScalarStyle::Plain { + true + } else if let Some(TokenType::Tag(ref handle, ref suffix)) = *tag { + if handle == "!!" && suffix == "null" { + if v == "~" || v == "null" { + false + } else { + return Err(de::Error::invalid_value(Unexpected::Str(v), &"null")); + } + } else { + true + } + } else { + v != "~" && v != "null" + } + } + Event::SequenceStart | Event::MappingStart => true, + Event::SequenceEnd => panic!("unexpected end of sequence"), + Event::MappingEnd => panic!("unexpected end of mapping"), + }; + if is_some { + visitor.visit_some(self) + } else { + *self.pos += 1; + visitor.visit_none() + } + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_scalar(visitor) + } + + fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + /// Parses a newtype struct as the underlying value. + fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.next()?; + match *next { + Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_seq(visitor), + Event::SequenceStart => self.visit_sequence(visitor), + ref other => Err(invalid_type(other, &visitor)), + } + .map_err(|err| private::fix_marker(err, marker, self.path)) + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.next()?; + match *next { + Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_map(visitor), + Event::MappingStart => self.visit_mapping(visitor), + ref other => Err(invalid_type(other, &visitor)), + } + .map_err(|err| private::fix_marker(err, marker, self.path)) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.next()?; + match *next { + Event::Alias(mut pos) => self + .jump(&mut pos)? + .deserialize_struct(name, fields, visitor), + Event::SequenceStart => self.visit_sequence(visitor), + Event::MappingStart => self.visit_mapping(visitor), + ref other => Err(invalid_type(other, &visitor)), + } + .map_err(|err| private::fix_marker(err, marker, self.path)) + } + + /// Parses an enum as a single key:value pair where the key identifies the + /// variant and the value gives the content. A String will also parse correctly + /// to a unit enum value. + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + let (next, marker) = self.peek()?; + match *next { + Event::Alias(mut pos) => { + *self.pos += 1; + self.jump(&mut pos)? + .deserialize_enum(name, variants, visitor) + } + Event::Scalar(_, _, ref t) => { + if let Some(TokenType::Tag(ref handle, ref suffix)) = *t { + if handle == "!" { + if let Some(tag) = variants.iter().find(|v| *v == suffix) { + return visitor.visit_enum(EnumAccess { + de: self, + name: name, + tag: Some(tag), + }); + } + } + } + visitor.visit_enum(UnitVariantAccess { de: self }) + } + Event::MappingStart => { + *self.pos += 1; + let value = visitor.visit_enum(EnumAccess { + de: self, + name: name, + tag: None, + })?; + self.end_mapping(1)?; + Ok(value) + } + Event::SequenceStart => { + let err = de::Error::invalid_type(Unexpected::Seq, &"string or singleton map"); + Err(private::fix_marker(err, marker, self.path)) + } + Event::SequenceEnd => panic!("unexpected end of sequence"), + Event::MappingEnd => panic!("unexpected end of mapping"), + } + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.ignore_any()?; + visitor.visit_unit() + } +} + +/// Deserialize an instance of type `T` from a string of YAML text. +/// +/// 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 YAML 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 YAML map or some number is too big to fit in the expected primitive +/// type. +/// +/// YAML currently does not support zero-copy deserialization. +pub fn from_str<T>(s: &str) -> Result<T> +where + T: DeserializeOwned, +{ + let mut parser = Parser::new(s.chars()); + let mut loader = Loader { + events: Vec::new(), + aliases: BTreeMap::new(), + }; + parser + .load(&mut loader, true) + .map_err(private::error_scanner)?; + if loader.events.is_empty() { + Err(private::error_end_of_stream()) + } else { + let mut pos = 0; + let t = Deserialize::deserialize(&mut Deserializer { + events: &loader.events, + aliases: &loader.aliases, + pos: &mut pos, + path: Path::Root, + remaining_depth: 128, + })?; + if pos == loader.events.len() { + Ok(t) + } else { + Err(private::error_more_than_one_document()) + } + } +} + +/// Deserialize an instance of type `T` from an IO stream of YAML. +/// +/// 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 YAML 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 YAML map or some number is too big to fit in the expected primitive +/// type. +pub fn from_reader<R, T>(mut rdr: R) -> Result<T> +where + R: io::Read, + T: DeserializeOwned, +{ + let mut bytes = Vec::new(); + rdr.read_to_end(&mut bytes).map_err(private::error_io)?; + let s = str::from_utf8(&bytes).map_err(private::error_str_utf8)?; + from_str(s) +} + +/// Deserialize an instance of type `T` from bytes of YAML text. +/// +/// 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 YAML 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 YAML map or some number is too big to fit in the expected primitive +/// type. +/// +/// YAML currently does not support zero-copy deserialization. +pub fn from_slice<T>(v: &[u8]) -> Result<T> +where + T: DeserializeOwned, +{ + let s = str::from_utf8(v).map_err(private::error_str_utf8)?; + from_str(s) +} diff --git a/third_party/rust/serde_yaml/src/error.rs b/third_party/rust/serde_yaml/src/error.rs new file mode 100644 index 0000000000..1c8fcf4ed6 --- /dev/null +++ b/third_party/rust/serde_yaml/src/error.rs @@ -0,0 +1,243 @@ +use std::error; +use std::fmt::{self, Debug, Display}; +use std::io; +use std::result; +use std::str; +use std::string; + +use yaml_rust::emitter; +use yaml_rust::scanner::{self, Marker, ScanError}; + +use serde::{de, ser}; + +use path::Path; +use private; + +/// This type represents all possible errors that can occur when serializing or +/// deserializing YAML data. +pub struct Error(Box<ErrorImpl>); + +/// Alias for a `Result` with the error type `serde_yaml::Error`. +pub type Result<T> = result::Result<T, Error>; + +/// This type represents all possible errors that can occur when serializing or +/// deserializing a value using YAML. +#[derive(Debug)] +pub enum ErrorImpl { + Message(String, Option<Pos>), + + Emit(emitter::EmitError), + Scan(scanner::ScanError), + Io(io::Error), + Utf8(str::Utf8Error), + FromUtf8(string::FromUtf8Error), + + EndOfStream, + MoreThanOneDocument, + RecursionLimitExceeded, +} + +#[derive(Debug)] +pub struct Pos { + marker: Marker, + path: String, +} + +/// This type represents the location that an error occured. +#[derive(Debug)] +pub struct Location { + index: usize, + line: usize, + column: usize, +} + +impl Location { + /// The byte index of the error + pub fn index(&self) -> usize { + self.index + } + + /// The line of the error + pub fn line(&self) -> usize { + self.line + } + + /// The column of the error + pub fn column(&self) -> usize { + self.column + } + + // This is to keep decoupled with the yaml crate + #[doc(hidden)] + fn from_marker(marker: &Marker) -> Self { + Location { + // `col` returned from the `yaml` crate is 0-indexed but all error messages add + 1 to this value + column: marker.col() + 1, + index: marker.index(), + line: marker.line(), + } + } +} + +impl Error { + /// Returns the Location from the error if one exists. + /// + /// Not all types of errors have a location so this can return `None`. + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::{Value, Error}; + /// # + /// // The `@` character as the first character makes this invalid yaml + /// let invalid_yaml: Result<Value, Error> = serde_yaml::from_str("@invalid_yaml"); + /// + /// let location = invalid_yaml.unwrap_err().location().unwrap(); + /// + /// assert_eq!(location.line(), 1); + /// assert_eq!(location.column(), 1); + /// ``` + pub fn location(&self) -> Option<Location> { + match *self.0 { + ErrorImpl::Message(_, Some(ref pos)) => Some(Location::from_marker(&pos.marker)), + ErrorImpl::Scan(ref scan) => Some(Location::from_marker(scan.marker())), + _ => None, + } + } +} + +impl private { + pub fn error_end_of_stream() -> Error { + Error(Box::new(ErrorImpl::EndOfStream)) + } + + pub fn error_more_than_one_document() -> Error { + Error(Box::new(ErrorImpl::MoreThanOneDocument)) + } + + pub fn error_io(err: io::Error) -> Error { + Error(Box::new(ErrorImpl::Io(err))) + } + + pub fn error_emitter(err: emitter::EmitError) -> Error { + Error(Box::new(ErrorImpl::Emit(err))) + } + + pub fn error_scanner(err: scanner::ScanError) -> Error { + Error(Box::new(ErrorImpl::Scan(err))) + } + + pub fn error_str_utf8(err: str::Utf8Error) -> Error { + Error(Box::new(ErrorImpl::Utf8(err))) + } + + pub fn error_string_utf8(err: string::FromUtf8Error) -> Error { + Error(Box::new(ErrorImpl::FromUtf8(err))) + } + + pub fn error_recursion_limit_exceeded() -> Error { + Error(Box::new(ErrorImpl::RecursionLimitExceeded)) + } + + pub fn fix_marker(mut error: Error, marker: Marker, path: Path) -> Error { + if let ErrorImpl::Message(_, ref mut none @ None) = *error.0.as_mut() { + *none = Some(Pos { + marker: marker, + path: path.to_string(), + }); + } + error + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + match *self.0 { + ErrorImpl::Message(ref msg, _) => msg, + ErrorImpl::Emit(_) => "emit error", + ErrorImpl::Scan(_) => "scan error", + ErrorImpl::Io(ref err) => err.description(), + ErrorImpl::Utf8(ref err) => err.description(), + ErrorImpl::FromUtf8(ref err) => err.description(), + ErrorImpl::EndOfStream => "EOF while parsing a value", + ErrorImpl::MoreThanOneDocument => { + "deserializing from YAML containing more than one document is not supported" + } + ErrorImpl::RecursionLimitExceeded => "recursion limit exceeded", + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self.0 { + ErrorImpl::Scan(ref err) => Some(err), + ErrorImpl::Io(ref err) => Some(err), + ErrorImpl::Utf8(ref err) => Some(err), + ErrorImpl::FromUtf8(ref err) => Some(err), + _ => None, + } + } +} + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + ErrorImpl::Message(ref msg, None) => Display::fmt(msg, f), + ErrorImpl::Message(ref msg, Some(Pos { marker, ref path })) => { + if path == "." { + write!(f, "{}", ScanError::new(marker, msg)) + } else { + write!(f, "{}: {}", path, ScanError::new(marker, msg)) + } + } + ErrorImpl::Emit(emitter::EmitError::FmtError(_)) => f.write_str("yaml-rust fmt error"), + ErrorImpl::Emit(emitter::EmitError::BadHashmapKey) => f.write_str("bad hash map key"), + ErrorImpl::Scan(ref err) => Display::fmt(err, f), + ErrorImpl::Io(ref err) => Display::fmt(err, f), + ErrorImpl::Utf8(ref err) => Display::fmt(err, f), + ErrorImpl::FromUtf8(ref err) => Display::fmt(err, f), + ErrorImpl::EndOfStream => f.write_str("EOF while parsing a value"), + ErrorImpl::MoreThanOneDocument => f.write_str( + "deserializing from YAML containing more than one document is not supported", + ), + ErrorImpl::RecursionLimitExceeded => f.write_str("recursion limit exceeded"), + } + } +} + +// 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, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + ErrorImpl::Message(ref msg, ref pos) => formatter + .debug_tuple("Message") + .field(msg) + .field(pos) + .finish(), + ErrorImpl::Emit(ref emit) => formatter.debug_tuple("Emit").field(emit).finish(), + ErrorImpl::Scan(ref scan) => formatter.debug_tuple("Scan").field(scan).finish(), + ErrorImpl::Io(ref io) => formatter.debug_tuple("Io").field(io).finish(), + ErrorImpl::Utf8(ref utf8) => formatter.debug_tuple("Utf8").field(utf8).finish(), + ErrorImpl::FromUtf8(ref from_utf8) => { + formatter.debug_tuple("FromUtf8").field(from_utf8).finish() + } + ErrorImpl::EndOfStream => formatter.debug_tuple("EndOfStream").finish(), + ErrorImpl::MoreThanOneDocument => formatter.debug_tuple("MoreThanOneDocument").finish(), + ErrorImpl::RecursionLimitExceeded => { + formatter.debug_tuple("RecursionLimitExceeded").finish() + } + } + } +} + +impl ser::Error for Error { + fn custom<T: Display>(msg: T) -> Self { + Error(Box::new(ErrorImpl::Message(msg.to_string(), None))) + } +} + +impl de::Error for Error { + fn custom<T: Display>(msg: T) -> Self { + Error(Box::new(ErrorImpl::Message(msg.to_string(), None))) + } +} diff --git a/third_party/rust/serde_yaml/src/lib.rs b/third_party/rust/serde_yaml/src/lib.rs new file mode 100644 index 0000000000..42f00431a3 --- /dev/null +++ b/third_party/rust/serde_yaml/src/lib.rs @@ -0,0 +1,109 @@ +//! This crate is a Rust library for using the [Serde] serialization framework +//! with data in [YAML] file format. +//! +//! This library does not reimplement a YAML parser; it uses [yaml-rust] which +//! is a pure Rust YAML 1.2 implementation. +//! +//! [Serde]: https://github.com/serde-rs/serde +//! [YAML]: http://yaml.org +//! [yaml-rust]: https://github.com/chyh1990/yaml-rust +//! +//! # Examples +//! +//! ```edition2018 +//! use std::collections::BTreeMap; +//! +//! fn main() -> Result<(), serde_yaml::Error> { +//! // You have some type. +//! let mut map = BTreeMap::new(); +//! map.insert("x".to_string(), 1.0); +//! map.insert("y".to_string(), 2.0); +//! +//! // Serialize it to a YAML string. +//! let s = serde_yaml::to_string(&map)?; +//! assert_eq!(s, "---\nx: 1.0\ny: 2.0"); +//! +//! // Deserialize it back to a Rust type. +//! let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?; +//! assert_eq!(map, deserialized_map); +//! Ok(()) +//! } +//! ``` +//! +//! ## Using Serde derive +//! +//! It can also be used with Serde's serialization code generator `serde_derive` to +//! handle structs and enums defined in your own program. +//! +//! ```edition2018 +//! # use serde_derive::{Serialize, Deserialize}; +//! use serde::{Serialize, Deserialize}; +//! +//! #[derive(Debug, PartialEq, Serialize, Deserialize)] +//! struct Point { +//! x: f64, +//! y: f64, +//! } +//! +//! fn main() -> Result<(), serde_yaml::Error> { +//! let point = Point { x: 1.0, y: 2.0 }; +//! +//! let s = serde_yaml::to_string(&point)?; +//! assert_eq!(s, "---\nx: 1.0\ny: 2.0"); +//! +//! let deserialized_point: Point = serde_yaml::from_str(&s)?; +//! assert_eq!(point, deserialized_point); +//! Ok(()) +//! } +//! ``` + +#![doc(html_root_url = "https://docs.rs/serde_yaml/0.8.9")] +#![deny(missing_docs)] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] +#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] +// Whitelisted clippy lints +#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))] +// Whitelisted clippy_pedantic lints +#![cfg_attr(feature = "cargo-clippy", allow( + // private Deserializer::next + should_implement_trait, + // things are often more readable this way + cast_lossless, + module_name_repetitions, + single_match_else, + use_self, + // code is acceptable + cast_possible_wrap, + cast_precision_loss, + cast_sign_loss, + // not practical + indexing_slicing, + missing_docs_in_private_items, + // not stable + empty_enum, + // meh, some things won't fail + result_unwrap_used, +))] + +extern crate dtoa; +extern crate linked_hash_map; +#[macro_use] +extern crate serde; +extern crate yaml_rust; + +pub use self::de::{from_reader, from_slice, from_str}; +pub use self::error::{Error, Location, Result}; +pub use self::mapping::Mapping; +pub use self::ser::{to_string, to_vec, to_writer}; +pub use self::value::{from_value, to_value, Index, Number, Sequence, Value}; + +mod de; +mod error; +mod mapping; +mod number; +mod path; +mod ser; +mod value; + +#[allow(non_camel_case_types)] +enum private {} diff --git a/third_party/rust/serde_yaml/src/mapping.rs b/third_party/rust/serde_yaml/src/mapping.rs new file mode 100644 index 0000000000..db1d60d9e5 --- /dev/null +++ b/third_party/rust/serde_yaml/src/mapping.rs @@ -0,0 +1,280 @@ +use std::fmt; +use std::iter::FromIterator; +use std::ops::{Index, IndexMut}; + +use linked_hash_map::{self, LinkedHashMap}; +use serde::{self, Deserialize, Deserializer, Serialize}; + +use value::Value; + +/// A YAML mapping in which the keys and values are both `serde_yaml::Value`. +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd)] +pub struct Mapping { + map: LinkedHashMap<Value, Value>, +} + +impl Mapping { + /// Creates an empty YAML map. + #[inline] + pub fn new() -> Self { + Self::default() + } + + /// Creates an empty YAML map with the given initial capacity. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + Mapping { + map: LinkedHashMap::with_capacity(capacity), + } + } + + /// Reserves capacity for at least `additional` more elements to be inserted + /// into the map. The map may reserve more space to avoid frequent + /// allocations. + /// + /// # Panics + /// + /// Panics if the new allocation size overflows `usize`. + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.map.reserve(additional) + } + + /// Shrinks the capacity of the map as much as possible. It will drop down + /// as much as possible while maintaining the internal rules and possibly + /// leaving some space in accordance with the resize policy. + #[inline] + pub fn shrink_to_fit(&mut self) { + self.map.shrink_to_fit() + } + + /// Inserts a key-value pair into the map. If the key already existed, the + /// old value is returned. + #[inline] + pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> { + self.map.insert(k, v) + } + + /// Checks if the map contains the given key. + #[inline] + pub fn contains_key(&self, k: &Value) -> bool { + self.map.contains_key(k) + } + + /// Returns the value corresponding to the key in the map. + #[inline] + pub fn get(&self, k: &Value) -> Option<&Value> { + self.map.get(k) + } + + /// Returns the mutable reference corresponding to the key in the map. + #[inline] + pub fn get_mut(&mut self, k: &Value) -> Option<&mut Value> { + self.map.get_mut(k) + } + + /// Removes and returns the value corresponding to the key from the map. + #[inline] + pub fn remove(&mut self, k: &Value) -> Option<Value> { + self.map.remove(k) + } + + /// Returns the maximum number of key-value pairs the map can hold without + /// reallocating. + #[inline] + pub fn capacity(&self) -> usize { + self.map.capacity() + } + + /// Returns the number of key-value pairs in the map. + #[inline] + pub fn len(&self) -> usize { + self.map.len() + } + + /// Returns whether the map is currently empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Clears the map of all key-value pairs. + #[inline] + pub fn clear(&mut self) { + self.map.clear() + } + + /// Returns a double-ended iterator visiting all key-value pairs in order of + /// insertion. Iterator element type is `(&'a Value, &'a Value)`. + #[inline] + pub fn iter(&self) -> Iter { + Iter { + iter: self.map.iter(), + } + } + + /// Returns a double-ended iterator visiting all key-value pairs in order of + /// insertion. Iterator element type is `(&'a Value, &'a mut ValuE)`. + #[inline] + pub fn iter_mut(&mut self) -> IterMut { + IterMut { + iter: self.map.iter_mut(), + } + } +} + +impl<'a> Index<&'a Value> for Mapping { + type Output = Value; + #[inline] + fn index(&self, index: &'a Value) -> &Value { + self.map.index(index) + } +} + +impl<'a> IndexMut<&'a Value> for Mapping { + #[inline] + fn index_mut(&mut self, index: &'a Value) -> &mut Value { + self.map.index_mut(index) + } +} + +impl Extend<(Value, Value)> for Mapping { + #[inline] + fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) { + self.map.extend(iter); + } +} + +impl FromIterator<(Value, Value)> for Mapping { + #[inline] + fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self { + Mapping { + map: LinkedHashMap::from_iter(iter), + } + } +} + +macro_rules! delegate_iterator { + (($name:ident $($generics:tt)*) => $item:ty) => { + impl $($generics)* Iterator for $name $($generics)* { + type Item = $item; + #[inline] + fn next(&mut self) -> Option<Self::Item> { + self.iter.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } + } + + impl $($generics)* ExactSizeIterator for $name $($generics)* { + #[inline] + fn len(&self) -> usize { + self.iter.len() + } + } + } +} + +pub struct Iter<'a> { + iter: linked_hash_map::Iter<'a, Value, Value>, +} + +delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value)); + +impl<'a> IntoIterator for &'a Mapping { + type Item = (&'a Value, &'a Value); + type IntoIter = Iter<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + Iter { + iter: self.map.iter(), + } + } +} + +pub struct IterMut<'a> { + iter: linked_hash_map::IterMut<'a, Value, Value>, +} + +delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value)); + +impl<'a> IntoIterator for &'a mut Mapping { + type Item = (&'a Value, &'a mut Value); + type IntoIter = IterMut<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IterMut { + iter: self.map.iter_mut(), + } + } +} + +pub struct IntoIter { + iter: linked_hash_map::IntoIter<Value, Value>, +} + +delegate_iterator!((IntoIter) => (Value, Value)); + +impl IntoIterator for Mapping { + type Item = (Value, Value); + type IntoIter = IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IntoIter { + iter: self.map.into_iter(), + } + } +} + +impl Serialize for Mapping { + #[inline] + fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { + use serde::ser::SerializeMap; + let mut map_serializer = serializer.serialize_map(Some(self.len()))?; + for (k, v) in self { + map_serializer.serialize_entry(k, v)?; + } + map_serializer.end() + } +} + +impl<'de> Deserialize<'de> for Mapping { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct Visitor; + + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = Mapping; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a YAML mapping") + } + + #[inline] + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + Ok(Mapping::new()) + } + + #[inline] + fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> + where + V: serde::de::MapAccess<'de>, + { + let mut values = Mapping::new(); + while let Some((k, v)) = visitor.next_entry()? { + values.insert(k, v); + } + Ok(values) + } + } + + deserializer.deserialize_map(Visitor) + } +} diff --git a/third_party/rust/serde_yaml/src/number.rs b/third_party/rust/serde_yaml/src/number.rs new file mode 100644 index 0000000000..52054f7999 --- /dev/null +++ b/third_party/rust/serde_yaml/src/number.rs @@ -0,0 +1,509 @@ +use error::Error; +use serde::de::{Unexpected, Visitor}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt::{self, Debug, Display}; +use std::hash::{Hash, Hasher}; +use std::i64; +use std::mem; + +use private; + +/// Represents a YAML number, whether integer or floating point. +#[derive(Clone, PartialEq, PartialOrd)] +pub struct Number { + n: N, +} + +// "N" is a prefix of "NegInt"... this is a false positive. +// https://github.com/Manishearth/rust-clippy/issues/1241 +#[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))] +#[derive(Copy, Clone, Debug, PartialOrd)] +enum N { + PosInt(u64), + /// Always less than zero. + NegInt(i64), + /// May be infinite or NaN. + Float(f64), +} + +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. + /// + /// ```edition2018 + /// # use std::i64; + /// # + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let big = i64::MAX as u64 + 10; + /// let v = yaml(r#" + /// a: 64 + /// b: 9223372036854775817 + /// 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] + #[cfg_attr(feature = "cargo-clippy", allow(cast_sign_loss))] + pub fn is_i64(&self) -> bool { + match self.n { + N::PosInt(v) => v <= i64::max_value() as u64, + N::NegInt(_) => true, + N::Float(_) => false, + } + } + + /// 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. + /// + /// ```edition2018 + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let v = yaml(r#" + /// 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 { + match self.n { + N::PosInt(_) => true, + N::NegInt(_) | N::Float(_) => false, + } + } + + /// 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. + /// + /// ```edition2018 + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let v = yaml(r#" + /// --- + /// 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 { + match self.n { + N::Float(_) => true, + N::PosInt(_) | N::NegInt(_) => false, + } + } + + /// If the `Number` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use std::i64; + /// # + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let big = i64::MAX as u64 + 10; + /// let v = yaml(r#" + /// --- + /// a: 64 + /// b: 9223372036854775817 + /// c: 256.0 + /// "#); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// ``` + #[inline] + pub fn as_i64(&self) -> Option<i64> { + 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, + } + } + + /// If the `Number` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let v = yaml(r#" + /// --- + /// a: 64 + /// b: -64 + /// c: 256.0 + /// "#); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// ``` + #[inline] + pub fn as_u64(&self) -> Option<u64> { + match self.n { + N::PosInt(n) => Some(n), + N::NegInt(_) | N::Float(_) => None, + } + } + + /// Represents the number as f64 if possible. Returns None otherwise. + /// + /// ```edition2018 + /// # + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// let v = yaml(r#" + /// --- + /// 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)); + /// ``` + /// + /// ```edition2018 + /// # use std::f64; + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// assert_eq!(yaml("inf").as_f64(), Some(f64::INFINITY)); + /// assert_eq!(yaml("-inf").as_f64(), Some(f64::NEG_INFINITY)); + /// assert!(yaml("NaN").as_f64().unwrap().is_nan()); + /// ``` + #[inline] + pub fn as_f64(&self) -> Option<f64> { + match self.n { + N::PosInt(n) => Some(n as f64), + N::NegInt(n) => Some(n as f64), + N::Float(n) => Some(n), + } + } + + /// Returns true if this value is NaN and false otherwise. + /// + /// ```edition2018 + /// # use std::f64; + /// # + /// # use serde_yaml::Number; + /// # + /// assert!(!Number::from(256.0).is_nan()); + /// + /// assert!(Number::from(f64::NAN).is_nan()); + /// + /// assert!(!Number::from(f64::INFINITY).is_nan()); + /// + /// assert!(!Number::from(f64::NEG_INFINITY).is_nan()); + /// + /// assert!(!Number::from(1).is_nan()); + /// ``` + #[inline] + pub fn is_nan(&self) -> bool { + match self.n { + N::PosInt(_) | N::NegInt(_) => false, + N::Float(f) => f.is_nan(), + } + } + + /// Returns true if this value is positive infinity or negative infinity and + /// false otherwise. + /// + /// ```edition2018 + /// # use std::f64; + /// # + /// # use serde_yaml::Number; + /// # + /// assert!(!Number::from(256.0).is_infinite()); + /// + /// assert!(!Number::from(f64::NAN).is_infinite()); + /// + /// assert!(Number::from(f64::INFINITY).is_infinite()); + /// + /// assert!(Number::from(f64::NEG_INFINITY).is_infinite()); + /// + /// assert!(!Number::from(1).is_infinite()); + /// ``` + #[inline] + pub fn is_infinite(&self) -> bool { + match self.n { + N::PosInt(_) | N::NegInt(_) => false, + N::Float(f) => f.is_infinite(), + } + } + + /// Returns true if this number is neither infinite nor NaN. + /// + /// ```edition2018 + /// # use std::f64; + /// # + /// # use serde_yaml::Number; + /// # + /// assert!(Number::from(256.0).is_finite()); + /// + /// assert!(!Number::from(f64::NAN).is_finite()); + /// + /// assert!(!Number::from(f64::INFINITY).is_finite()); + /// + /// assert!(!Number::from(f64::NEG_INFINITY).is_finite()); + /// + /// assert!(Number::from(1).is_finite()); + /// ``` + #[inline] + pub fn is_finite(&self) -> bool { + match self.n { + N::PosInt(_) | N::NegInt(_) => true, + N::Float(f) => f.is_finite(), + } + } +} + +impl fmt::Display for Number { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.n { + N::PosInt(i) => Display::fmt(&i, formatter), + N::NegInt(i) => Display::fmt(&i, formatter), + N::Float(f) if f.is_nan() => formatter.write_str(".nan"), + N::Float(f) if f.is_infinite() => { + if f.is_sign_negative() { + formatter.write_str("-.inf") + } else { + formatter.write_str(".inf") + } + } + N::Float(f) => Display::fmt(&f, formatter), + } + } +} + +impl Debug for Number { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.n, formatter) + } +} + +impl PartialEq for N { + fn eq(&self, other: &N) -> bool { + match (*self, *other) { + (N::PosInt(a), N::PosInt(b)) => a == b, + (N::NegInt(a), N::NegInt(b)) => a == b, + (N::Float(a), N::Float(b)) => { + if a.is_nan() && b.is_nan() { + // Compare NaN for bitwise equality. + // The unsafe code is equivalent to f64::to_bits which was + // stabilized in 1.20.0. + let a = unsafe { mem::transmute::<f64, u64>(a) }; + let b = unsafe { mem::transmute::<f64, u64>(b) }; + a == b + } else { + a == b + } + } + _ => false, + } + } +} + +impl Serialize for Number { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self.n { + N::PosInt(i) => serializer.serialize_u64(i), + N::NegInt(i) => serializer.serialize_i64(i), + N::Float(f) => serializer.serialize_f64(f), + } + } +} + +impl<'de> Deserialize<'de> for Number { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Number, D::Error> + where + D: Deserializer<'de>, + { + struct NumberVisitor; + + impl<'de> Visitor<'de> for NumberVisitor { + type Value = Number; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a number") + } + + #[inline] + fn visit_i64<E>(self, value: i64) -> Result<Number, E> { + Ok(value.into()) + } + + #[inline] + fn visit_u64<E>(self, value: u64) -> Result<Number, E> { + Ok(value.into()) + } + + #[inline] + fn visit_f64<E>(self, value: f64) -> Result<Number, E> { + Ok(value.into()) + } + } + + deserializer.deserialize_any(NumberVisitor) + } +} + +impl<'de> Deserializer<'de> for Number { + type Error = Error; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self.n { + N::PosInt(i) => visitor.visit_u64(i), + N::NegInt(i) => visitor.visit_i64(i), + N::Float(f) => visitor.visit_f64(f), + } + } + + 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, 'a> Deserializer<'de> for &'a Number { + type Error = Error; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self.n { + N::PosInt(i) => visitor.visit_u64(i), + N::NegInt(i) => visitor.visit_i64(i), + N::Float(f) => visitor.visit_f64(f), + } + } + + 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! from_signed { + ($($signed_ty:ident)*) => { + $( + impl From<$signed_ty> for Number { + #[inline] + #[cfg_attr(feature = "cargo-clippy", allow(cast_sign_loss))] + fn from(i: $signed_ty) -> Self { + if i < 0 { + Number { n: N::NegInt(i as i64) } + } else { + Number { n: N::PosInt(i as u64) } + } + } + } + )* + }; +} + +macro_rules! from_unsigned { + ($($unsigned_ty:ident)*) => { + $( + impl From<$unsigned_ty> for Number { + #[inline] + fn from(u: $unsigned_ty) -> Self { + Number { n: N::PosInt(u as u64) } + } + } + )* + }; +} + +macro_rules! from_float { + ($($float_ty:ident)*) => { + $( + impl From<$float_ty> for Number { + #[inline] + fn from(f: $float_ty) -> Self { + Number { n: N::Float(f as f64) } + } + } + )* + } +} + +from_signed!(i8 i16 i32 i64 isize); +from_unsigned!(u8 u16 u32 u64 usize); +from_float!(f32 f64); + +// This is fine, because we don't _really_ implement hash for floats +// all other hash functions should work as expected +#[cfg_attr(feature = "cargo-clippy", allow(derive_hash_xor_eq))] +impl Hash for Number { + fn hash<H: Hasher>(&self, state: &mut H) { + match self.n { + N::Float(_) => { + // you should feel bad for using f64 as a map key + 3.hash(state) + } + N::PosInt(u) => u.hash(state), + N::NegInt(i) => i.hash(state), + } + } +} + +impl private { + pub fn number_unexpected(number: &Number) -> Unexpected { + match number.n { + N::PosInt(u) => Unexpected::Unsigned(u), + N::NegInt(i) => Unexpected::Signed(i), + N::Float(f) => Unexpected::Float(f), + } + } +} diff --git a/third_party/rust/serde_yaml/src/path.rs b/third_party/rust/serde_yaml/src/path.rs new file mode 100644 index 0000000000..e4450bef3d --- /dev/null +++ b/third_party/rust/serde_yaml/src/path.rs @@ -0,0 +1,34 @@ +use std::fmt::{self, Display}; + +/// Path to the current value in the input, like `dependencies.serde.typo1`. +#[derive(Copy, Clone)] +pub enum Path<'a> { + Root, + Seq { parent: &'a Path<'a>, index: usize }, + Map { parent: &'a Path<'a>, key: &'a str }, + Alias { parent: &'a Path<'a> }, + Unknown { parent: &'a Path<'a> }, +} + +impl<'a> Display for Path<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + struct Parent<'a>(&'a Path<'a>); + + impl<'a> Display for Parent<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self.0 { + Path::Root => Ok(()), + ref path => write!(formatter, "{}.", path), + } + } + } + + match *self { + Path::Root => formatter.write_str("."), + Path::Seq { parent, index } => write!(formatter, "{}[{}]", parent, index), + Path::Map { parent, key } => write!(formatter, "{}{}", Parent(parent), key), + Path::Alias { parent } => write!(formatter, "{}", parent), + Path::Unknown { parent } => write!(formatter, "{}?", Parent(parent)), + } + } +} diff --git a/third_party/rust/serde_yaml/src/ser.rs b/third_party/rust/serde_yaml/src/ser.rs new file mode 100644 index 0000000000..7c08151dcb --- /dev/null +++ b/third_party/rust/serde_yaml/src/ser.rs @@ -0,0 +1,459 @@ +//! YAML Serialization +//! +//! This module provides YAML serialization with the type `Serializer`. + +use std::{fmt, io, num, str}; + +use yaml_rust::{yaml, Yaml, YamlEmitter}; + +use serde::ser; + +use super::error::{Error, Result}; +use private; + +pub struct Serializer; + +impl ser::Serializer for Serializer { + type Ok = Yaml; + type Error = Error; + + type SerializeSeq = SerializeArray; + type SerializeTuple = SerializeArray; + type SerializeTupleStruct = SerializeArray; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeStruct; + type SerializeStructVariant = SerializeStructVariant; + + fn serialize_bool(self, v: bool) -> Result<Yaml> { + Ok(Yaml::Boolean(v)) + } + + fn serialize_i8(self, v: i8) -> Result<Yaml> { + self.serialize_i64(v as i64) + } + + fn serialize_i16(self, v: i16) -> Result<Yaml> { + self.serialize_i64(v as i64) + } + + fn serialize_i32(self, v: i32) -> Result<Yaml> { + self.serialize_i64(v as i64) + } + + fn serialize_i64(self, v: i64) -> Result<Yaml> { + Ok(Yaml::Integer(v)) + } + + serde_if_integer128! { + #[cfg_attr(feature = "cargo-clippy", allow(cast_possible_truncation))] + fn serialize_i128(self, v: i128) -> Result<Yaml> { + if v <= i64::max_value() as i128 && v >= i64::min_value() as i128 { + self.serialize_i64(v as i64) + } else { + Ok(Yaml::Real(v.to_string())) + } + } + } + + fn serialize_u8(self, v: u8) -> Result<Yaml> { + self.serialize_i64(v as i64) + } + + fn serialize_u16(self, v: u16) -> Result<Yaml> { + self.serialize_i64(v as i64) + } + + fn serialize_u32(self, v: u32) -> Result<Yaml> { + self.serialize_i64(v as i64) + } + + fn serialize_u64(self, v: u64) -> Result<Yaml> { + if v <= i64::max_value() as u64 { + self.serialize_i64(v as i64) + } else { + Ok(Yaml::Real(v.to_string())) + } + } + + serde_if_integer128! { + #[cfg_attr(feature = "cargo-clippy", allow(cast_possible_truncation))] + fn serialize_u128(self, v: u128) -> Result<Yaml> { + if v <= i64::max_value() as u128 { + self.serialize_i64(v as i64) + } else { + Ok(Yaml::Real(v.to_string())) + } + } + } + + fn serialize_f32(self, v: f32) -> Result<Yaml> { + self.serialize_f64(v as f64) + } + + fn serialize_f64(self, v: f64) -> Result<Yaml> { + Ok(Yaml::Real(match v.classify() { + num::FpCategory::Infinite if v.is_sign_positive() => ".inf".into(), + num::FpCategory::Infinite => "-.inf".into(), + num::FpCategory::Nan => ".nan".into(), + _ => { + let mut buf = vec![]; + ::dtoa::write(&mut buf, v).unwrap(); + ::std::str::from_utf8(&buf).unwrap().into() + } + })) + } + + fn serialize_char(self, value: char) -> Result<Yaml> { + Ok(Yaml::String(value.to_string())) + } + + fn serialize_str(self, value: &str) -> Result<Yaml> { + Ok(Yaml::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<Yaml> { + let vec = value.iter().map(|&b| Yaml::Integer(b as i64)).collect(); + Ok(Yaml::Array(vec)) + } + + fn serialize_unit(self) -> Result<Yaml> { + Ok(Yaml::Null) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Yaml> { + self.serialize_unit() + } + + fn serialize_unit_variant( + self, + _name: &str, + _variant_index: u32, + variant: &str, + ) -> Result<Yaml> { + Ok(Yaml::String(variant.to_owned())) + } + + fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Yaml> + where + T: ser::Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &str, + _variant_index: u32, + variant: &str, + value: &T, + ) -> Result<Yaml> + where + T: ser::Serialize, + { + Ok(singleton_hash(to_yaml(variant)?, to_yaml(value)?)) + } + + fn serialize_none(self) -> Result<Yaml> { + self.serialize_unit() + } + + fn serialize_some<V: ?Sized>(self, value: &V) -> Result<Yaml> + where + V: ser::Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<SerializeArray> { + let array = match len { + None => yaml::Array::new(), + Some(len) => yaml::Array::with_capacity(len), + }; + Ok(SerializeArray { array: array }) + } + + fn serialize_tuple(self, len: usize) -> Result<SerializeArray> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeArray> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _enum: &'static str, + _idx: u32, + variant: &'static str, + len: usize, + ) -> Result<SerializeTupleVariant> { + Ok(SerializeTupleVariant { + name: variant, + array: yaml::Array::with_capacity(len), + }) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<SerializeMap> { + Ok(SerializeMap { + hash: yaml::Hash::new(), + next_key: None, + }) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<SerializeStruct> { + Ok(SerializeStruct { + hash: yaml::Hash::new(), + }) + } + + fn serialize_struct_variant( + self, + _enum: &'static str, + _idx: u32, + variant: &'static str, + _len: usize, + ) -> Result<SerializeStructVariant> { + Ok(SerializeStructVariant { + name: variant, + hash: yaml::Hash::new(), + }) + } +} + +#[doc(hidden)] +pub struct SerializeArray { + array: yaml::Array, +} + +#[doc(hidden)] +pub struct SerializeTupleVariant { + name: &'static str, + array: yaml::Array, +} + +#[doc(hidden)] +pub struct SerializeMap { + hash: yaml::Hash, + next_key: Option<yaml::Yaml>, +} + +#[doc(hidden)] +pub struct SerializeStruct { + hash: yaml::Hash, +} + +#[doc(hidden)] +pub struct SerializeStructVariant { + name: &'static str, + hash: yaml::Hash, +} + +impl ser::SerializeSeq for SerializeArray { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, elem: &T) -> Result<()> + where + T: ser::Serialize, + { + self.array.push(to_yaml(elem)?); + Ok(()) + } + + fn end(self) -> Result<Yaml> { + Ok(Yaml::Array(self.array)) + } +} + +impl ser::SerializeTuple for SerializeArray { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, elem: &T) -> Result<()> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, elem) + } + + fn end(self) -> Result<Yaml> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleStruct for SerializeArray { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_field<V: ?Sized>(&mut self, value: &V) -> Result<()> + where + V: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Yaml> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_field<V: ?Sized>(&mut self, v: &V) -> Result<()> + where + V: ser::Serialize, + { + self.array.push(to_yaml(v)?); + Ok(()) + } + + fn end(self) -> Result<Yaml> { + Ok(singleton_hash(to_yaml(self.name)?, Yaml::Array(self.array))) + } +} + +impl ser::SerializeMap for SerializeMap { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> + where + T: ser::Serialize, + { + self.next_key = Some(to_yaml(key)?); + Ok(()) + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + match self.next_key.take() { + Some(key) => self.hash.insert(key, to_yaml(value)?), + None => panic!("serialize_value called before serialize_key"), + }; + Ok(()) + } + + fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()> + where + K: ser::Serialize, + V: ser::Serialize, + { + self.hash.insert(to_yaml(key)?, to_yaml(value)?); + Ok(()) + } + + fn end(self) -> Result<Yaml> { + Ok(Yaml::Hash(self.hash)) + } +} + +impl ser::SerializeStruct for SerializeStruct { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_field<V: ?Sized>(&mut self, key: &'static str, value: &V) -> Result<()> + where + V: ser::Serialize, + { + self.hash.insert(to_yaml(key)?, to_yaml(value)?); + Ok(()) + } + + fn end(self) -> Result<Yaml> { + Ok(Yaml::Hash(self.hash)) + } +} + +impl ser::SerializeStructVariant for SerializeStructVariant { + type Ok = yaml::Yaml; + type Error = Error; + + fn serialize_field<V: ?Sized>(&mut self, field: &'static str, v: &V) -> Result<()> + where + V: ser::Serialize, + { + self.hash.insert(to_yaml(field)?, to_yaml(v)?); + Ok(()) + } + + fn end(self) -> Result<Yaml> { + Ok(singleton_hash(to_yaml(self.name)?, Yaml::Hash(self.hash))) + } +} + +/// Serialize the given data structure as YAML into the IO stream. +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// return an error. +pub fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: ser::Serialize, +{ + let doc = to_yaml(value)?; + let mut writer_adapter = FmtToIoWriter { writer: writer }; + YamlEmitter::new(&mut writer_adapter) + .dump(&doc) + .map_err(private::error_emitter)?; + Ok(()) +} + +/// Serialize the given data structure as a YAML byte vector. +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// return an error. +pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>> +where + T: ser::Serialize, +{ + let mut vec = Vec::with_capacity(128); + to_writer(&mut vec, value)?; + Ok(vec) +} + +/// Serialize the given data structure as a String of YAML. +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// return an error. +pub fn to_string<T: ?Sized>(value: &T) -> Result<String> +where + T: ser::Serialize, +{ + Ok(String::from_utf8(to_vec(value)?).map_err(private::error_string_utf8)?) +} + +/// The yaml-rust library uses `fmt::Write` intead of `io::Write` so this is a +/// simple adapter. +struct FmtToIoWriter<W> { + writer: W, +} + +impl<W> fmt::Write for FmtToIoWriter<W> +where + W: io::Write, +{ + fn write_str(&mut self, s: &str) -> fmt::Result { + if self.writer.write(s.as_bytes()).is_err() { + return Err(fmt::Error); + } + Ok(()) + } +} + +fn to_yaml<T>(elem: T) -> Result<Yaml> +where + T: ser::Serialize, +{ + elem.serialize(Serializer) +} + +fn singleton_hash(k: Yaml, v: Yaml) -> Yaml { + let mut hash = yaml::Hash::new(); + hash.insert(k, v); + Yaml::Hash(hash) +} diff --git a/third_party/rust/serde_yaml/src/value/de.rs b/third_party/rust/serde_yaml/src/value/de.rs new file mode 100644 index 0000000000..9fdee7e35f --- /dev/null +++ b/third_party/rust/serde_yaml/src/value/de.rs @@ -0,0 +1,715 @@ +use std::fmt; +use std::vec; + +use serde::de::{ + self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as SError, Expected, + MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor, +}; + +use {private, Error, Mapping, Sequence, Value}; + +impl<'de> Deserialize<'de> for Value { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: 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 YAML value") + } + + fn visit_bool<E>(self, b: bool) -> Result<Value, E> + where + E: SError, + { + Ok(Value::Bool(b)) + } + + fn visit_i64<E>(self, i: i64) -> Result<Value, E> + where + E: SError, + { + Ok(Value::Number(i.into())) + } + + fn visit_u64<E>(self, u: u64) -> Result<Value, E> + where + E: SError, + { + Ok(Value::Number(u.into())) + } + + fn visit_f64<E>(self, f: f64) -> Result<Value, E> + where + E: SError, + { + Ok(Value::Number(f.into())) + } + + fn visit_str<E>(self, s: &str) -> Result<Value, E> + where + E: SError, + { + Ok(Value::String(s.to_owned())) + } + + fn visit_string<E>(self, s: String) -> Result<Value, E> + where + E: SError, + { + Ok(Value::String(s)) + } + + fn visit_unit<E>(self) -> Result<Value, E> + where + E: SError, + { + Ok(Value::Null) + } + + fn visit_none<E>(self) -> Result<Value, E> + where + E: SError, + { + Ok(Value::Null) + } + + fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error> + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error> + where + V: SeqAccess<'de>, + { + let mut vec = Vec::new(); + + while let Some(element) = visitor.next_element()? { + vec.push(element); + } + + Ok(Value::Sequence(vec)) + } + + fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error> + where + V: MapAccess<'de>, + { + let mut values = Mapping::new(); + + while let Some((key, value)) = visitor.next_entry()? { + values.insert(key, value); + } + + Ok(Value::Mapping(values)) + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} + +impl Value { + fn deserialize_number<'de, V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } +} + +fn visit_sequence<'de, V>(sequence: Sequence, visitor: V) -> Result<V::Value, Error> +where + V: Visitor<'de>, +{ + let len = sequence.len(); + let mut deserializer = SeqDeserializer::new(sequence); + let seq = visitor.visit_seq(&mut deserializer)?; + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(Error::invalid_length(len, &"fewer elements in sequence")) + } +} + +fn visit_mapping<'de, V>(mapping: Mapping, visitor: V) -> Result<V::Value, Error> +where + V: Visitor<'de>, +{ + let len = mapping.len(); + let mut deserializer = MapDeserializer::new(mapping); + let map = visitor.visit_map(&mut deserializer)?; + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(Error::invalid_length(len, &"fewer elements in map")) + } +} + +impl<'de> Deserializer<'de> for Value { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + 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::Sequence(v) => visit_sequence(v, visitor), + Value::Mapping(v) => visit_mapping(v, visitor), + } + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + serde_if_integer128! { + fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + serde_if_integer128! { + fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + } + + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_number(visitor) + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_string(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_string(v), + Value::Sequence(v) => visit_sequence(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Sequence(v) => visit_sequence(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Mapping(v) => visit_mapping(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self { + Value::Sequence(v) => visit_sequence(v, visitor), + Value::Mapping(v) => visit_mapping(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + let (variant, value) = match self { + Value::Mapping(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(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(Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + Value::String(variant) => (Value::String(variant), None), + other => { + return Err(Error::invalid_type(other.unexpected(), &"string or map")); + } + }; + + visitor.visit_enum(EnumDeserializer { + variant: variant, + value: value, + }) + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } +} + +struct EnumDeserializer { + variant: Value, + value: Option<Value>, +} + +impl<'de> EnumAccess<'de> for EnumDeserializer { + type Error = Error; + type Variant = VariantDeserializer; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error> + where + V: DeserializeSeed<'de>, + { + let visitor = VariantDeserializer { value: self.value }; + seed.deserialize(self.variant).map(|v| (v, visitor)) + } +} + +struct VariantDeserializer { + value: Option<Value>, +} + +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<T>(self, seed: T) -> Result<T::Value, Error> + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Sequence(v)) => { + Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + } + Some(other) => Err(Error::invalid_type(other.unexpected(), &"tuple variant")), + None => Err(Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Mapping(v)) => { + Deserializer::deserialize_any(MapDeserializer::new(v), visitor) + } + Some(other) => Err(Error::invalid_type(other.unexpected(), &"struct variant")), + _ => Err(Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqDeserializer { + iter: vec::IntoIter<Value>, +} + +impl SeqDeserializer { + fn new(vec: Vec<Value>) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + } + } +} + +impl<'de> Deserializer<'de> for SeqDeserializer { + type Error = Error; + + #[inline] + fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + let len = self.iter.len(); + if len == 0 { + visitor.visit_unit() + } else { + let ret = visitor.visit_seq(&mut self)?; + let remaining = self.iter.len(); + if remaining == 0 { + Ok(ret) + } else { + Err(Error::invalid_length(len, &"fewer elements in sequence")) + } + } + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier + } +} + +impl<'de> SeqAccess<'de> for SeqDeserializer { + type Error = Error; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option<usize> { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapDeserializer { + iter: <Mapping as IntoIterator>::IntoIter, + value: Option<Value>, +} + +impl MapDeserializer { + fn new(map: Mapping) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapDeserializer { + type Error = Error; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + seed.deserialize(key).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Error> + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => panic!("visit_value called before visit_key"), + } + } + + fn size_hint(&self) -> Option<usize> { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +impl<'de> Deserializer<'de> for MapDeserializer { + type Error = Error; + + #[inline] + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + visitor.visit_map(self) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier + } +} + +impl Value { + #[cold] + fn invalid_type<E>(&self, exp: &Expected) -> E + where + E: de::Error, + { + 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) => private::number_unexpected(n), + Value::String(ref s) => Unexpected::Str(s), + Value::Sequence(_) => Unexpected::Seq, + Value::Mapping(_) => Unexpected::Map, + } + } +} diff --git a/third_party/rust/serde_yaml/src/value/from.rs b/third_party/rust/serde_yaml/src/value/from.rs new file mode 100644 index 0000000000..757eea307d --- /dev/null +++ b/third_party/rust/serde_yaml/src/value/from.rs @@ -0,0 +1,181 @@ +use super::Value; +use mapping::Mapping; + +// Implement a bunch of conversion to make it easier to create YAML values +// on the fly. + +macro_rules! from_number { + ($($ty:ident)*) => { + $( + impl From<$ty> for Value { + fn from(n: $ty) -> Self { + Value::Number(n.into()) + } + } + )* + }; +} + +from_number! { + i8 i16 i32 i64 isize + u8 u16 u32 u64 usize + f32 f64 +} + +impl From<bool> for Value { + /// Convert boolean to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// + /// let b = false; + /// let x: Value = b.into(); + /// ``` + fn from(f: bool) -> Self { + Value::Bool(f) + } +} + +impl From<String> for Value { + /// Convert `String` to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::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 + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// + /// let s: &str = "lorem"; + /// let x: Value = s.into(); + /// ``` + fn from(f: &str) -> Self { + Value::String(f.to_string()) + } +} + +use std::borrow::Cow; + +impl<'a> From<Cow<'a, str>> for Value { + /// Convert copy-on-write string to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow<str> = Cow::Borrowed("lorem"); + /// let x: Value = s.into(); + /// ``` + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow<str> = Cow::Owned("lorem".to_string()); + /// let x: Value = s.into(); + /// ``` + fn from(f: Cow<'a, str>) -> Self { + Value::String(f.to_string()) + } +} + +impl From<Mapping> for Value { + /// Convert map (with string keys) to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::{Mapping, Value}; + /// + /// let mut m = Mapping::new(); + /// m.insert("Lorem".into(), "ipsum".into()); + /// let x: Value = m.into(); + /// ``` + fn from(f: Mapping) -> Self { + Value::Mapping(f) + } +} + +impl<T: Into<Value>> From<Vec<T>> for Value { + /// Convert a `Vec` to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// + /// let v = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: Vec<T>) -> Self { + Value::Sequence(f.into_iter().map(Into::into).collect()) + } +} + +impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value { + /// Convert a slice to `Value` + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// + /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: &'a [T]) -> Self { + Value::Sequence(f.iter().cloned().map(Into::into).collect()) + } +} + +use std::iter::FromIterator; + +impl<T: Into<Value>> FromIterator<T> for Value { + /// Convert an iteratable type to a YAML sequence + /// + /// # Examples + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// + /// let v = std::iter::repeat(42).take(5); + /// let x: Value = v.collect(); + /// ``` + /// + /// ```edition2018 + /// use serde_yaml::Value; + /// + /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into_iter().collect(); + /// ``` + /// + /// ```edition2018 + /// use std::iter::FromIterator; + /// use serde_yaml::Value; + /// + /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); + /// ``` + fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { + let vec = iter.into_iter().map(T::into).collect(); + + Value::Sequence(vec) + } +} diff --git a/third_party/rust/serde_yaml/src/value/index.rs b/third_party/rust/serde_yaml/src/value/index.rs new file mode 100644 index 0000000000..18dcc5aad8 --- /dev/null +++ b/third_party/rust/serde_yaml/src/value/index.rs @@ -0,0 +1,262 @@ +use std::fmt; +use std::ops; + +use super::Value; +use mapping::Mapping; + +/// A type that can be used to index into a `serde_yaml::Value`. See the `get` +/// and `get_mut` methods of `Value`. +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_yaml`. +pub trait Index: private::Sealed { + /// Return None if the key is not already in the sequence 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 sequence or object. + #[doc(hidden)] + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; + + /// Panic if sequence 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::Sequence(ref vec) => vec.get(*self), + Value::Mapping(ref vec) => vec.get(&Value::Number((*self).into())), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match *v { + Value::Sequence(ref mut vec) => vec.get_mut(*self), + Value::Mapping(ref mut vec) => vec.get_mut(&Value::Number((*self).into())), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + match *v { + Value::Sequence(ref mut vec) => { + let len = vec.len(); + vec.get_mut(*self).unwrap_or_else(|| { + panic!( + "cannot access index {} of YAML sequence of length {}", + self, len + ) + }) + } + Value::Mapping(ref mut map) => { + let n = Value::Number((*self).into()); + // TODO: use entry() once LinkedHashMap supports entry() + // https://github.com/contain-rs/linked-hash-map/issues/5 + if !map.contains_key(&n) { + map.insert(n.clone(), Value::Null); + } + map.get_mut(&n).unwrap() + } + _ => panic!("cannot access index {} of YAML {}", self, Type(v)), + } + } +} + +impl Index for Value { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match *v { + Value::Mapping(ref map) => map.get(self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match *v { + Value::Mapping(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 { + let mut map = Mapping::new(); + map.insert(self.clone(), Value::Null); + *v = Value::Mapping(map); + } + match *v { + Value::Mapping(ref mut map) => { + // TODO: use entry() once LinkedHashMap supports entry() + // https://github.com/contain-rs/linked-hash-map/issues/5 + if !map.contains_key(self) { + map.insert(self.clone(), Value::Null); + } + map.get_mut(self).unwrap() + } + _ => panic!("cannot access key {:?} in YAML {}", self, Type(v)), + } + } +} + +impl Index for str { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + Value::String(self.into()).index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + Value::String(self.into()).index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + Value::String(self.into()).index_or_insert(v) + } +} + +impl Index for String { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + Value::String(self.clone()).index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + Value::String(self.clone()).index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + Value::String(self.clone()).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 Sealed for super::Value {} + 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::Sequence(_) => formatter.write_str("sequence"), + Value::Mapping(_) => formatter.write_str("mapping"), + } + } +} + +// 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 YAML 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_sequence()` and working with the Vec directly, or matching on +// `Value::Sequence` 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_sequence`, or match. The value of this impl is that it adds a way of +// working with Value that is not well served by the existing approaches: +// concise and careless and sometimes that is exactly what you want. +impl<I> ops::Index<I> for Value +where + I: Index, +{ + type Output = Value; + + /// Index into a `serde_yaml::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 a sequence + /// 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 sequence. + /// + /// For retrieving deeply nested values, you should have a look at the + /// `Value::pointer` method. + /// + /// # Examples + /// + /// ```edition2018 + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let data = yaml(r#"{ x: { y: [z, zz] } }"#); + /// + /// assert_eq!(data["x"]["y"], yaml(r#"["z", "zz"]"#)); + /// assert_eq!(data["x"]["y"][0], yaml(r#""z""#)); + /// + /// assert_eq!(data["a"], yaml(r#"null"#)); // returns null for undefined values + /// assert_eq!(data["a"]["b"], yaml(r#"null"#)); // does not panic + /// ``` + fn index(&self, index: I) -> &Value { + static NULL: Value = Value::Null; + index.index_into(self).unwrap_or(&NULL) + } +} + +impl<I> ops::IndexMut<I> for Value +where + I: Index, +{ + /// Write into a `serde_yaml::Value` using the syntax `value[0] = ...` or + /// `value["k"] = ...`. + /// + /// If the index is a number, the value must be a sequence of length bigger + /// than the index. Indexing into a value that is not a sequence or a + /// sequence 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 + /// + /// ```edition2018 + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let mut data = yaml(r#"{x: 0}"#); + /// + /// // replace an existing key + /// data["x"] = yaml(r#"1"#); + /// + /// // insert a new key + /// data["y"] = yaml(r#"[false, false, false]"#); + /// + /// // replace a value in a sequence + /// data["y"][0] = yaml(r#"true"#); + /// + /// // inserted a deeply nested key + /// data["a"]["b"]["c"]["d"] = yaml(r#"true"#); + /// + /// println!("{:?}", data); + /// ``` + fn index_mut(&mut self, index: I) -> &mut Value { + index.index_or_insert(self) + } +} diff --git a/third_party/rust/serde_yaml/src/value/mod.rs b/third_party/rust/serde_yaml/src/value/mod.rs new file mode 100644 index 0000000000..2f9b80193f --- /dev/null +++ b/third_party/rust/serde_yaml/src/value/mod.rs @@ -0,0 +1,646 @@ +use std::f64; +use std::hash::{Hash, Hasher}; +use std::str::FromStr; + +use serde::de::{Deserialize, DeserializeOwned}; +use serde::Serialize; +use yaml_rust::Yaml; + +use error::Error; +use mapping::Mapping; +use ser::Serializer; + +pub use self::index::Index; +pub use number::Number; + +/// Represents any valid YAML value. +#[derive(Clone, PartialOrd, Debug)] +pub enum Value { + /// Represents a YAML null value. + Null, + /// Represents a YAML boolean. + Bool(bool), + /// Represents a YAML numerical value, whether integer or floating point. + Number(Number), + /// Represents a YAML string. + String(String), + /// Represents a YAML sequence in which the elements are + /// `serde_yaml::Value`. + Sequence(Sequence), + /// Represents a YAML mapping in which the keys and values are both + /// `serde_yaml::Value`. + Mapping(Mapping), +} + +/// The default value is `Value::Null`. +/// +/// This is useful for handling omitted `Value` fields when deserializing. +/// +/// # Examples +/// +/// ```edition2018 +/// # use serde_derive::Deserialize; +/// use serde::Deserialize; +/// use serde_yaml::Value; +/// +/// #[derive(Deserialize)] +/// struct Settings { +/// level: i32, +/// #[serde(default)] +/// extras: Value, +/// } +/// +/// # fn try_main() -> Result<(), serde_yaml::Error> { +/// let data = r#" { "level": 42 } "#; +/// let s: Settings = serde_yaml::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 + } +} + +/// A YAML sequence in which the elements are `serde_yaml::Value`. +pub type Sequence = Vec<Value>; + +/// Convert a `T` into `serde_yaml::Value` which is an enum that can represent +/// any valid YAML data. +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to +/// return an error. +/// +/// ```edition2018 +/// # use serde_yaml::Value; +/// let val = serde_yaml::to_value("s").unwrap(); +/// assert_eq!(val, Value::String("s".to_owned())); +/// ``` +pub fn to_value<T>(value: T) -> Result<Value, Error> +where + T: Serialize, +{ + value.serialize(Serializer).map(yaml_to_value) +} + +/// Interpret a `serde_yaml::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 YAML 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 YAML map or some number is too big to fit in the expected primitive +/// type. +/// +/// ```edition2018 +/// # use serde_yaml::Value; +/// let val = Value::String("foo".to_owned()); +/// let s: String = serde_yaml::from_value(val).unwrap(); +/// assert_eq!("foo", s); +/// ``` +pub fn from_value<T>(value: Value) -> Result<T, Error> +where + T: DeserializeOwned, +{ + Deserialize::deserialize(value) +} + +impl Value { + /// Index into a YAML sequence 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 sequence. + /// + /// 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 a sequence 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 sequence. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// # + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let object: Value = yaml(r#"{ A: 65, B: 66, C: 67 }"#); + /// let x = object.get("A").unwrap(); + /// assert_eq!(x, 65); + /// + /// let sequence: Value = yaml(r#"[ "A", "B", "C" ]"#); + /// let x = sequence.get(2).unwrap(); + /// assert_eq!(x, &Value::String("C".into())); + /// + /// assert_eq!(sequence.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`. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// # + /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() } + /// # + /// let object = yaml(r#" + /// --- + /// A: [a, á, à] + /// B: [b, b́] + /// C: [c, ć, ć̣, ḉ] + /// 42: true + /// "#); + /// assert_eq!(object["B"][0], Value::String("b".into())); + /// + /// assert_eq!(object[Value::String("D".into())], Value::Null); + /// assert_eq!(object["D"], Value::Null); + /// assert_eq!(object[0]["x"]["y"]["z"], Value::Null); + /// + /// assert_eq!(object[42], Value::Bool(true)); + /// ``` + pub fn get<I: Index>(&self, index: I) -> Option<&Value> { + index.index_into(self) + } + + /// Index into a YAML sequence 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 sequence. + /// + /// 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 a sequence 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 sequence. + pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> { + index.index_into_mut(self) + } + + /// 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(())`. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("null").unwrap(); + /// assert!(v.is_null()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert!(!v.is_null()); + /// ``` + pub fn is_null(&self) -> bool { + if let Value::Null = *self { + true + } else { + false + } + } + + /// If the `Value` is a Null, returns (). Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("null").unwrap(); + /// assert_eq!(v.as_null(), Some(())); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_null(), None); + /// ``` + pub fn as_null(&self) -> Option<()> { + match *self { + Value::Null => Some(()), + _ => 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. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("true").unwrap(); + /// assert!(v.is_bool()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("42").unwrap(); + /// assert!(!v.is_bool()); + /// ``` + pub fn is_bool(&self) -> bool { + self.as_bool().is_some() + } + + /// If the `Value` is a Boolean, returns the associated bool. Returns None + /// otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("true").unwrap(); + /// assert_eq!(v.as_bool(), Some(true)); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("42").unwrap(); + /// assert_eq!(v.as_bool(), None); + /// ``` + pub fn as_bool(&self) -> Option<bool> { + match *self { + Value::Bool(b) => Some(b), + _ => None, + } + } + + /// Returns true if the `Value` is a Number. Returns false otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("5").unwrap(); + /// assert!(v.is_number()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("true").unwrap(); + /// assert!(!v.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. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("1337").unwrap(); + /// assert!(v.is_i64()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("null").unwrap(); + /// assert!(!v.is_i64()); + /// ``` + pub fn is_i64(&self) -> bool { + self.as_i64().is_some() + } + + /// If the `Value` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("1337").unwrap(); + /// assert_eq!(v.as_i64(), Some(1337)); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_i64(), None); + /// ``` + pub fn as_i64(&self) -> Option<i64> { + match *self { + Value::Number(ref n) => n.as_i64(), + _ => None, + } + } + + /// Returns true if the `Value` is an integer between `u64::MIN` and + /// `u64::MAX`. + /// + /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("1337").unwrap(); + /// assert!(v.is_u64()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("null").unwrap(); + /// assert!(!v.is_u64()); + /// ``` + pub fn is_u64(&self) -> bool { + self.as_u64().is_some() + } + + /// If the `Value` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("1337").unwrap(); + /// assert_eq!(v.as_u64(), Some(1337)); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_u64(), None); + /// ``` + pub fn as_u64(&self) -> Option<u64> { + match *self { + Value::Number(ref n) => n.as_u64(), + _ => None, + } + } + + /// 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. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("256.01").unwrap(); + /// assert!(v.is_f64()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("true").unwrap(); + /// assert!(!v.is_f64()); + /// ``` + pub fn is_f64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_f64(), + _ => false, + } + } + + /// If the `Value` is a number, represent it as f64 if possible. Returns + /// None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("13.37").unwrap(); + /// assert_eq!(v.as_f64(), Some(13.37)); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_f64(), None); + /// ``` + pub fn as_f64(&self) -> Option<f64> { + match *self { + Value::Number(ref i) => i.as_f64(), + _ => 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. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap(); + /// assert!(v.is_string()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("42").unwrap(); + /// assert!(!v.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. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap(); + /// assert_eq!(v.as_str(), Some("lorem ipsum")); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_str(), None); + /// ``` + pub fn as_str(&self) -> Option<&str> { + match *self { + Value::String(ref s) => Some(s), + _ => None, + } + } + + /// Returns true if the `Value` is a sequence. Returns false otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("[1, 2, 3]").unwrap(); + /// assert!(v.is_sequence()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("true").unwrap(); + /// assert!(!v.is_sequence()); + /// ``` + pub fn is_sequence(&self) -> bool { + self.as_sequence().is_some() + } + + /// If the `Value` is a sequence, return a reference to it if possible. + /// Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::{Value, Number}; + /// let v: Value = serde_yaml::from_str("[1, 2]").unwrap(); + /// assert_eq!(v.as_sequence(), Some(&vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))])); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_sequence(), None); + /// ``` + pub fn as_sequence(&self) -> Option<&Sequence> { + match *self { + Value::Sequence(ref seq) => Some(seq), + _ => None, + } + } + + /// If the `Value` is a sequence, return a mutable reference to it if + /// possible. Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::{Value, Number}; + /// let mut v: Value = serde_yaml::from_str("[1]").unwrap(); + /// let s = v.as_sequence_mut().unwrap(); + /// s.push(Value::Number(Number::from(2))); + /// assert_eq!(s, &vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let mut v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_sequence_mut(), None); + /// ``` + pub fn as_sequence_mut(&mut self) -> Option<&mut Sequence> { + match *self { + Value::Sequence(ref mut seq) => Some(seq), + _ => None, + } + } + + /// Returns true if the `Value` is a mapping. Returns false otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("a: 42").unwrap(); + /// assert!(v.is_mapping()); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("true").unwrap(); + /// assert!(!v.is_mapping()); + /// ``` + pub fn is_mapping(&self) -> bool { + self.as_mapping().is_some() + } + + /// If the `Value` is a mapping, return a reference to it if possible. + /// Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::{Value, Mapping, Number}; + /// let v: Value = serde_yaml::from_str("a: 42").unwrap(); + /// + /// let mut expected = Mapping::new(); + /// expected.insert(Value::String("a".into()),Value::Number(Number::from(42))); + /// + /// assert_eq!(v.as_mapping(), Some(&expected)); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// let v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_mapping(), None); + /// ``` + pub fn as_mapping(&self) -> Option<&Mapping> { + match *self { + Value::Mapping(ref map) => Some(map), + _ => None, + } + } + + /// If the `Value` is a mapping, return a reference to it if possible. + /// Returns None otherwise. + /// + /// ```edition2018 + /// # use serde_yaml::{Value, Mapping, Number}; + /// let mut v: Value = serde_yaml::from_str("a: 42").unwrap(); + /// let m = v.as_mapping_mut().unwrap(); + /// m.insert(Value::String("b".into()),Value::Number(Number::from(21))); + /// + /// let mut expected = Mapping::new(); + /// expected.insert(Value::String("a".into()),Value::Number(Number::from(42))); + /// expected.insert(Value::String("b".into()),Value::Number(Number::from(21))); + /// + /// assert_eq!(m, &expected); + /// ``` + /// + /// ```edition2018 + /// # use serde_yaml::{Value, Mapping}; + /// let mut v: Value = serde_yaml::from_str("false").unwrap(); + /// assert_eq!(v.as_mapping_mut(), None); + /// ``` + pub fn as_mapping_mut(&mut self) -> Option<&mut Mapping> { + match *self { + Value::Mapping(ref mut map) => Some(map), + _ => None, + } + } +} + +fn yaml_to_value(yaml: Yaml) -> Value { + match yaml { + Yaml::Real(f) => { + if f == ".inf" { + Value::Number(f64::INFINITY.into()) + } else if f == "-.inf" { + Value::Number(f64::NEG_INFINITY.into()) + } else if f == ".nan" { + Value::Number(f64::NAN.into()) + } else if let Ok(n) = u64::from_str(&f) { + Value::Number(n.into()) + } else if let Ok(n) = i64::from_str(&f) { + Value::Number(n.into()) + } else if let Ok(n) = f64::from_str(&f) { + Value::Number(n.into()) + } else { + Value::String(f) + } + } + Yaml::Integer(i) => Value::Number(i.into()), + Yaml::String(s) => Value::String(s), + Yaml::Boolean(b) => Value::Bool(b), + Yaml::Array(sequence) => Value::Sequence(sequence.into_iter().map(yaml_to_value).collect()), + Yaml::Hash(hash) => Value::Mapping( + hash.into_iter() + .map(|(k, v)| (yaml_to_value(k), yaml_to_value(v))) + .collect(), + ), + Yaml::Alias(_) => panic!("alias unsupported"), + Yaml::Null => Value::Null, + Yaml::BadValue => panic!("bad value"), + } +} + +impl Eq for Value {} + +impl Hash for Value { + fn hash<H: Hasher>(&self, state: &mut H) { + match *self { + Value::Null => 0.hash(state), + Value::Bool(b) => (1, b).hash(state), + Value::Number(ref i) => (2, i).hash(state), + Value::String(ref s) => (3, s).hash(state), + Value::Sequence(ref seq) => (4, seq).hash(state), + Value::Mapping(ref map) => (5, map).hash(state), + } + } +} + +mod from; +mod index; +mod partial_eq; + +mod de; +mod ser; diff --git a/third_party/rust/serde_yaml/src/value/partial_eq.rs b/third_party/rust/serde_yaml/src/value/partial_eq.rs new file mode 100644 index 0000000000..f0d62a51d5 --- /dev/null +++ b/third_party/rust/serde_yaml/src/value/partial_eq.rs @@ -0,0 +1,135 @@ +use super::Value; + +impl PartialEq for Value { + fn eq(&self, other: &Value) -> bool { + match (self, other) { + (&Value::Null, &Value::Null) => true, + (&Value::Bool(a), &Value::Bool(b)) => a == b, + (&Value::Number(ref a), &Value::Number(ref b)) => a == b, + (&Value::String(ref a), &Value::String(ref b)) => a == b, + (&Value::Sequence(ref a), &Value::Sequence(ref b)) => a == b, + (&Value::Mapping(ref a), &Value::Mapping(ref b)) => a == b, + _ => false, + } + } +} + +impl PartialEq<str> for Value { + /// Compare `str` with YAML value + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// assert!(Value::String("lorem".into()) == *"lorem"); + /// ``` + fn eq(&self, other: &str) -> bool { + self.as_str().map_or(false, |s| s == other) + } +} + +impl<'a> PartialEq<&'a str> for Value { + /// Compare `&str` with YAML value + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// assert!(Value::String("lorem".into()) == "lorem"); + /// ``` + fn eq(&self, other: &&str) -> bool { + self.as_str().map_or(false, |s| s == *other) + } +} + +impl PartialEq<Value> for str { + /// Compare YAML value with `str` + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// assert!(*"lorem" == Value::String("lorem".into())); + /// ``` + fn eq(&self, other: &Value) -> bool { + other.as_str().map_or(false, |s| s == self) + } +} + +impl<'a> PartialEq<Value> for &'a str { + /// Compare `&str` with YAML value + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// assert!("lorem" == Value::String("lorem".into())); + /// ``` + fn eq(&self, other: &Value) -> bool { + other.as_str().map_or(false, |s| s == *self) + } +} + +impl PartialEq<String> for Value { + /// Compare YAML value with String + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// assert!(Value::String("lorem".into()) == "lorem".to_string()); + /// ``` + fn eq(&self, other: &String) -> bool { + self.as_str().map_or(false, |s| s == other) + } +} + +impl PartialEq<Value> for String { + /// Compare `String` with YAML value + /// + /// # Examples + /// + /// ```edition2018 + /// # use serde_yaml::Value; + /// assert!("lorem".to_string() == Value::String("lorem".into())); + /// ``` + fn eq(&self, other: &Value) -> bool { + other.as_str().map_or(false, |s| s == self) + } +} + +macro_rules! partialeq_numeric { + ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => { + $($( + impl PartialEq<$ty> for Value { + fn eq(&self, other: &$ty) -> bool { + self.$conversion().map_or(false, |i| i == (*other as $base)) + } + } + + impl PartialEq<Value> for $ty { + fn eq(&self, other: &Value) -> bool { + other.$conversion().map_or(false, |i| i == (*self as $base)) + } + } + + impl<'a> PartialEq<$ty> for &'a Value { + fn eq(&self, other: &$ty) -> bool { + self.$conversion().map_or(false, |i| i == (*other as $base)) + } + } + + impl<'a> PartialEq<$ty> for &'a mut Value { + fn eq(&self, other: &$ty) -> bool { + self.$conversion().map_or(false, |i| i == (*other as $base)) + } + } + )*)* + } +} + +partialeq_numeric! { + [i8 i16 i32 i64 isize], as_i64, i64 + [u8 u16 u32 usize], as_i64, i64 + [f32 f64], as_f64, f64 +} diff --git a/third_party/rust/serde_yaml/src/value/ser.rs b/third_party/rust/serde_yaml/src/value/ser.rs new file mode 100644 index 0000000000..da467f878e --- /dev/null +++ b/third_party/rust/serde_yaml/src/value/ser.rs @@ -0,0 +1,26 @@ +use serde::{self, Serialize}; + +use super::Value; + +impl Serialize for Value { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + 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::Sequence(ref seq) => seq.serialize(serializer), + Value::Mapping(ref hash) => { + use serde::ser::SerializeMap; + let mut map = serializer.serialize_map(Some(hash.len()))?; + for (k, v) in hash { + map.serialize_entry(k, v)?; + } + map.end() + } + } + } +} diff --git a/third_party/rust/serde_yaml/tests/test_de.rs b/third_party/rust/serde_yaml/tests/test_de.rs new file mode 100644 index 0000000000..6b141ef442 --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_de.rs @@ -0,0 +1,354 @@ +#[macro_use] +extern crate serde_derive; + +#[macro_use] +extern crate serde; + +extern crate serde_yaml; + +extern crate unindent; +use unindent::unindent; + +use std::collections::BTreeMap; +use std::fmt::Debug; + +use serde_yaml::Value; + +fn test_de<T>(yaml: &str, expected: &T) +where + T: serde::de::DeserializeOwned + PartialEq + Debug, +{ + let deserialized: T = serde_yaml::from_str(yaml).unwrap(); + assert_eq!(*expected, deserialized); + + serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap(); + serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap(); +} + +#[test] +fn test_alias() { + let yaml = unindent( + " + --- + first: + &alias + 1 + second: + *alias + third: 3", + ); + let mut expected = BTreeMap::new(); + { + expected.insert(String::from("first"), 1); + expected.insert(String::from("second"), 1); + expected.insert(String::from("third"), 3); + } + test_de(&yaml, &expected); +} + +#[test] +fn test_option() { + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: Option<f64>, + b: Option<String>, + c: Option<bool>, + } + let yaml = unindent( + " + --- + b: + c: true", + ); + let expected = Data { + a: None, + b: None, + c: Some(true), + }; + test_de(&yaml, &expected); +} + +#[test] +fn test_option_alias() { + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: Option<f64>, + b: Option<String>, + c: Option<bool>, + d: Option<f64>, + e: Option<String>, + f: Option<bool>, + } + let yaml = unindent( + " + --- + none_f: + &none_f + ~ + none_s: + &none_s + ~ + none_b: + &none_b + ~ + + some_f: + &some_f + 1.0 + some_s: + &some_s + x + some_b: + &some_b + true + + a: *none_f + b: *none_s + c: *none_b + d: *some_f + e: *some_s + f: *some_b", + ); + let expected = Data { + a: None, + b: None, + c: None, + d: Some(1.0), + e: Some("x".to_owned()), + f: Some(true), + }; + test_de(&yaml, &expected); +} + +#[test] +fn test_enum_alias() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + A, + B(u8, u8), + } + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: E, + b: E, + } + let yaml = unindent( + " + --- + aref: + &aref + A + bref: + &bref + B: + - 1 + - 2 + + a: *aref + b: *bref", + ); + let expected = Data { + a: E::A, + b: E::B(1, 2), + }; + test_de(&yaml, &expected); +} + +#[test] +fn test_enum_tag() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + A(String), + B(String), + } + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: E, + b: E, + } + let yaml = unindent( + " + --- + a: !A foo + b: !B bar", + ); + let expected = Data { + a: E::A("foo".into()), + b: E::B("bar".into()), + }; + test_de(&yaml, &expected); +} + +#[test] +fn test_number_as_string() { + #[derive(Deserialize, PartialEq, Debug)] + struct Num { + value: String, + } + let yaml = unindent( + " + --- + # Cannot be represented as u128 + value: 340282366920938463463374607431768211457", + ); + let expected = Num { + value: "340282366920938463463374607431768211457".to_owned(), + }; + test_de(&yaml, &expected); +} + +serde_if_integer128! { + #[test] + fn test_i128_big() { + let expected: i128 = ::std::i64::MIN as i128 - 1; + let yaml = unindent( + " + --- + -9223372036854775809", + ); + assert_eq!(expected, serde_yaml::from_str::<i128>(&yaml).unwrap()); + } + + #[test] + fn test_u128_big() { + let expected: u128 = ::std::u64::MAX as u128 + 1; + let yaml = unindent( + " + --- + 18446744073709551616", + ); + assert_eq!(expected, serde_yaml::from_str::<u128>(&yaml).unwrap()); + } +} + +#[test] +fn test_number_alias_as_string() { + #[derive(Deserialize, PartialEq, Debug)] + struct Num { + version: String, + value: String, + } + let yaml = unindent( + " + --- + version: &a 1.10 + value: *a", + ); + let expected = Num { + version: "1.10".to_owned(), + value: "1.10".to_owned(), + }; + test_de(&yaml, &expected); +} + +#[test] +fn test_de_mapping() { + #[derive(Debug, Deserialize, PartialEq)] + struct Data { + pub substructure: serde_yaml::Mapping, + } + let yaml = unindent( + " + --- + substructure: + a: 'foo' + b: 'bar'", + ); + + let mut expected = Data { + substructure: serde_yaml::Mapping::new(), + }; + expected.substructure.insert( + serde_yaml::Value::String("a".to_owned()), + serde_yaml::Value::String("foo".to_owned()), + ); + expected.substructure.insert( + serde_yaml::Value::String("b".to_owned()), + serde_yaml::Value::String("bar".to_owned()), + ); + + test_de(&yaml, &expected); +} + +#[test] +fn test_bomb() { + #[derive(Debug, Deserialize, PartialEq)] + struct Data { + expected: String, + } + + // This would deserialize an astronomical number of elements if we were + // vulnerable. + let yaml = unindent( + " + --- + a: &a ~ + b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] + c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] + d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] + e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] + f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] + g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] + h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] + i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] + j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i] + k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j] + l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k] + m: &m [*l,*l,*l,*l,*l,*l,*l,*l,*l] + n: &n [*m,*m,*m,*m,*m,*m,*m,*m,*m] + o: &o [*n,*n,*n,*n,*n,*n,*n,*n,*n] + p: &p [*o,*o,*o,*o,*o,*o,*o,*o,*o] + q: &q [*p,*p,*p,*p,*p,*p,*p,*p,*p] + r: &r [*q,*q,*q,*q,*q,*q,*q,*q,*q] + s: &s [*r,*r,*r,*r,*r,*r,*r,*r,*r] + t: &t [*s,*s,*s,*s,*s,*s,*s,*s,*s] + u: &u [*t,*t,*t,*t,*t,*t,*t,*t,*t] + v: &v [*u,*u,*u,*u,*u,*u,*u,*u,*u] + w: &w [*v,*v,*v,*v,*v,*v,*v,*v,*v] + x: &x [*w,*w,*w,*w,*w,*w,*w,*w,*w] + y: &y [*x,*x,*x,*x,*x,*x,*x,*x,*x] + z: &z [*y,*y,*y,*y,*y,*y,*y,*y,*y] + expected: string", + ); + + let expected = Data { + expected: "string".to_owned(), + }; + + assert_eq!(expected, serde_yaml::from_str::<Data>(&yaml).unwrap()); +} + +#[test] +fn test_numbers() { + let cases = [ + ("0xF0", "240"), + ("+0xF0", "240"), + ("-0xF0", "-240"), + ("0o70", "56"), + ("+0o70", "56"), + ("-0o70", "-56"), + ("0b10", "2"), + ("+0b10", "2"), + ("-0b10", "-2"), + ("127", "127"), + ("+127", "127"), + ("-127", "-127"), + (".inf", ".inf"), + (".Inf", ".inf"), + (".INF", ".inf"), + ("-.inf", "-.inf"), + ("-.Inf", "-.inf"), + ("-.INF", "-.inf"), + (".nan", ".nan"), + (".NaN", ".nan"), + (".NAN", ".nan"), + ("0.1", "0.1"), + ]; + for &(yaml, expected) in &cases { + let value = serde_yaml::from_str::<Value>(yaml).unwrap(); + match value { + Value::Number(number) => assert_eq!(number.to_string(), expected), + _ => panic!("expected number"), + } + } +} diff --git a/third_party/rust/serde_yaml/tests/test_error.rs b/third_party/rust/serde_yaml/tests/test_error.rs new file mode 100644 index 0000000000..d587aebf6c --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_error.rs @@ -0,0 +1,299 @@ +#[macro_use] +extern crate serde_derive; + +extern crate serde; +extern crate serde_yaml; + +extern crate unindent; +use unindent::unindent; + +use std::fmt::Debug; + +fn test_error<T>(yaml: &str, expected: &str) +where + T: serde::de::DeserializeOwned + Debug, +{ + let result = serde_yaml::from_str::<T>(yaml); + assert_eq!(expected, format!("{}", result.unwrap_err())); +} + +#[test] +fn test_incorrect_type() { + let yaml = unindent( + " + --- + str", + ); + let expected = "invalid type: string \"str\", expected i16 at line 2 column 1"; + test_error::<i16>(&yaml, expected); +} + +#[test] +fn test_incorrect_nested_type() { + #[derive(Deserialize, Debug)] + struct A { + b: Vec<B>, + } + #[derive(Deserialize, Debug)] + enum B { + C(C), + } + #[derive(Deserialize, Debug)] + struct C { + d: bool, + } + let yaml = unindent( + " + --- + b: + - C: + d: fase", + ); + let expected = + "b[0].C.d: invalid type: string \"fase\", expected a boolean at line 4 column 10"; + test_error::<A>(&yaml, expected); +} + +#[test] +fn test_empty() { + let expected = "EOF while parsing a value"; + test_error::<String>("", expected); +} + +#[test] +fn test_missing_field() { + #[derive(Deserialize, Debug)] + struct Basic { + v: bool, + w: bool, + } + let yaml = unindent( + " + --- + v: true", + ); + let expected = "missing field `w` at line 2 column 2"; + test_error::<Basic>(&yaml, expected); +} + +#[test] +fn test_unknown_anchor() { + let yaml = unindent( + " + --- + *some", + ); + let expected = "while parsing node, found unknown anchor at line 2 column 1"; + test_error::<String>(&yaml, expected); +} + +#[test] +fn test_ignored_unknown_anchor() { + #[derive(Deserialize, Debug)] + struct Wrapper { + c: (), + } + let yaml = unindent( + " + --- + b: [*a] + c: ~", + ); + let expected = "while parsing node, found unknown anchor at line 2 column 5"; + test_error::<Wrapper>(&yaml, expected); +} + +#[test] +fn test_two_documents() { + let yaml = unindent( + " + --- + 0 + --- + 1", + ); + let expected = "deserializing from YAML containing more than one document is not supported"; + test_error::<usize>(&yaml, expected); +} + +#[test] +fn test_variant_map_wrong_size() { + #[derive(Deserialize, Debug)] + enum E { + V(usize), + } + let yaml = unindent( + r#" + --- + "V": 16 + "other": 32"#, + ); + let expected = "invalid length 2, expected map containing 1 entry"; + test_error::<E>(&yaml, expected); +} + +#[test] +fn test_variant_not_a_map() { + #[derive(Deserialize, Debug)] + enum E { + V(usize), + } + let yaml = unindent( + r#" + --- + - "V""#, + ); + let expected = "invalid type: sequence, expected string or singleton map at line 2 column 1"; + test_error::<E>(&yaml, expected); +} + +#[test] +fn test_variant_not_string() { + #[derive(Deserialize, Debug)] + enum E { + V(bool), + } + let yaml = unindent( + r#" + --- + {}: true"#, + ); + let expected = "invalid type: map, expected variant of enum `E` at line 2 column 1"; + test_error::<E>(&yaml, expected); +} + +#[test] +fn test_bad_bool() { + let yaml = unindent( + " + --- + !!bool str", + ); + let expected = "invalid value: string \"str\", expected a boolean at line 2 column 8"; + test_error::<bool>(&yaml, expected); +} + +#[test] +fn test_bad_int() { + let yaml = unindent( + " + --- + !!int str", + ); + let expected = "invalid value: string \"str\", expected an integer at line 2 column 7"; + test_error::<i64>(&yaml, expected); +} + +#[test] +fn test_bad_float() { + let yaml = unindent( + " + --- + !!float str", + ); + let expected = "invalid value: string \"str\", expected a float at line 2 column 9"; + test_error::<f64>(&yaml, expected); +} + +#[test] +fn test_bad_null() { + let yaml = unindent( + " + --- + !!null str", + ); + let expected = "invalid value: string \"str\", expected null at line 2 column 8"; + test_error::<()>(&yaml, expected); +} + +#[test] +fn test_short_tuple() { + let yaml = unindent( + " + --- + [0, 0]", + ); + let expected = "invalid length 2, expected a tuple of size 3 at line 2 column 1"; + test_error::<(u8, u8, u8)>(&yaml, expected); +} + +#[test] +fn test_long_tuple() { + let yaml = unindent( + " + --- + [0, 0, 0]", + ); + let expected = "invalid length 3, expected sequence of 2 elements at line 2 column 1"; + test_error::<(u8, u8)>(&yaml, expected); +} + +#[test] +fn test_no_location() { + let invalid_utf8: Result<serde_yaml::Value, serde_yaml::Error> = + serde_yaml::from_slice(b"\x80\xae"); + + let utf8_location = invalid_utf8.unwrap_err().location(); + + assert_eq!(utf8_location.is_none(), true); +} + +#[test] +fn test_invalid_scalar_type() { + #[derive(Deserialize, Debug)] + struct S { + x: [(); 1], + } + + let yaml = "x:\n"; + let expected = "x: invalid type: unit value, expected an array of length 1 at line 2 column 1"; + test_error::<S>(yaml, expected); +} + +#[test] +fn test_infinite_recursion_objects() { + #[derive(Deserialize, Debug)] + struct S { + x: Option<Box<S>>, + } + + let yaml = "&a {x: *a}"; + let expected = "recursion limit exceeded"; + test_error::<S>(yaml, expected); +} + +#[test] +fn test_infinite_recursion_arrays() { + #[derive(Deserialize, Debug)] + struct S { + x: Option<Box<S>>, + } + + let yaml = "&a [*a]"; + let expected = "recursion limit exceeded"; + test_error::<S>(yaml, expected); +} + +#[test] +fn test_finite_recursion_objects() { + #[derive(Deserialize, Debug)] + struct S { + x: Option<Box<S>>, + } + + let yaml = "{x:".repeat(1_000) + &"}".repeat(1_000); + let expected = "recursion limit exceeded at line 1 column 766"; + test_error::<i32>(&yaml, expected); +} + +#[test] +fn test_finite_recursion_arrays() { + #[derive(Deserialize, Debug)] + struct S { + x: Option<Box<S>>, + } + + let yaml = "[".repeat(1_000) + &"]".repeat(1_000); + let expected = "recursion limit exceeded at line 1 column 256"; + test_error::<S>(&yaml, expected); +} diff --git a/third_party/rust/serde_yaml/tests/test_serde.rs b/third_party/rust/serde_yaml/tests/test_serde.rs new file mode 100644 index 0000000000..405704abf6 --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_serde.rs @@ -0,0 +1,426 @@ +#![cfg_attr( + feature = "cargo-clippy", + allow(unreadable_literal, decimal_literal_representation) +)] + +#[macro_use] +extern crate serde_derive; + +#[macro_use] +extern crate serde; + +extern crate serde_yaml; + +extern crate unindent; +use unindent::unindent; + +use std::collections::BTreeMap; +use std::f64; +use std::fmt::Debug; + +use serde_yaml::Value; + +fn test_serde<T>(thing: &T, yaml: &str) +where + T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug, +{ + let serialized = serde_yaml::to_string(&thing).unwrap(); + assert_eq!(yaml, serialized); + + let value = serde_yaml::to_value(&thing).unwrap(); + let serialized = serde_yaml::to_string(&value).unwrap(); + assert_eq!(yaml, serialized); + + let deserialized: T = serde_yaml::from_str(yaml).unwrap(); + assert_eq!(*thing, deserialized); + + let value: Value = serde_yaml::from_str(yaml).unwrap(); + let deserialized: T = serde_yaml::from_value(value).unwrap(); + assert_eq!(*thing, deserialized); + + serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap(); +} + +#[test] +fn test_default() { + assert_eq!(Value::default(), Value::Null); +} + +#[test] +fn test_int() { + let thing = 256; + let yaml = unindent( + " + --- + 256", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_int_max_u64() { + let thing = ::std::u64::MAX; + let yaml = unindent( + " + --- + 18446744073709551615", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_int_min_i64() { + let thing = ::std::i64::MIN; + let yaml = unindent( + " + --- + -9223372036854775808", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_int_max_i64() { + let thing = ::std::i64::MAX; + let yaml = unindent( + " + --- + 9223372036854775807", + ); + test_serde(&thing, &yaml); +} + +serde_if_integer128! { + #[test] + fn test_i128_small() { + let thing: i128 = -256; + let yaml = unindent( + " + --- + -256", + ); + test_serde(&thing, &yaml); + } + + #[test] + fn test_u128_small() { + let thing: u128 = 256; + let yaml = unindent( + " + --- + 256", + ); + test_serde(&thing, &yaml); + } +} + +#[test] +fn test_float() { + let thing = 25.6; + let yaml = unindent( + " + --- + 25.6", + ); + test_serde(&thing, &yaml); + + let thing = 25.; + let yaml = unindent( + " + --- + 25.0", + ); + test_serde(&thing, &yaml); + + let thing = f64::INFINITY; + let yaml = unindent( + " + --- + .inf", + ); + test_serde(&thing, &yaml); + + let thing = f64::NEG_INFINITY; + let yaml = unindent( + " + --- + -.inf", + ); + test_serde(&thing, &yaml); + + let float: f64 = serde_yaml::from_str(&unindent( + " + --- + .nan", + )) + .unwrap(); + assert!(float.is_nan()); +} + +#[test] +fn test_vec() { + let thing = vec![1, 2, 3]; + let yaml = unindent( + " + --- + - 1 + - 2 + - 3", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_map() { + let mut thing = BTreeMap::new(); + thing.insert(String::from("x"), 1); + thing.insert(String::from("y"), 2); + let yaml = unindent( + r#" + --- + x: 1 + y: 2"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_basic_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Basic { + x: isize, + y: String, + z: bool, + } + let thing = Basic { + x: -4, + y: String::from("hi\tquoted"), + z: true, + }; + let yaml = unindent( + r#" + --- + x: -4 + y: "hi\tquoted" + z: true"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_nested_vec() { + let thing = vec![vec![1, 2, 3], vec![4, 5, 6]]; + let yaml = unindent( + " + --- + - - 1 + - 2 + - 3 + - - 4 + - 5 + - 6", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_nested_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Outer { + inner: Inner, + } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Inner { + v: u16, + } + let thing = Outer { + inner: Inner { v: 512 }, + }; + let yaml = unindent( + r#" + --- + inner: + v: 512"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_option() { + let thing = vec![Some(1), None, Some(3)]; + let yaml = unindent( + " + --- + - 1 + - ~ + - 3", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_unit() { + let thing = vec![(), ()]; + let yaml = unindent( + " + --- + - ~ + - ~", + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_unit_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + First, + Second, + } + let thing = Variant::First; + let yaml = unindent( + r#" + --- + First"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_newtype_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct OriginalType { + v: u16, + } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct NewType(OriginalType); + let thing = NewType(OriginalType { v: 1 }); + let yaml = unindent( + r#" + --- + v: 1"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_newtype_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + Size(usize), + } + let thing = Variant::Size(127); + let yaml = unindent( + r#" + --- + Size: 127"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_tuple_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + Rgb(u8, u8, u8), + } + let thing = Variant::Rgb(32, 64, 96); + let yaml = unindent( + r#" + --- + Rgb: + - 32 + - 64 + - 96"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_struct_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + Color { r: u8, g: u8, b: u8 }, + } + let thing = Variant::Color { + r: 32, + g: 64, + b: 96, + }; + let yaml = unindent( + r#" + --- + Color: + r: 32 + g: 64 + b: 96"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_value() { + use serde_yaml::{Mapping, Number}; + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + pub struct GenericInstructions { + #[serde(rename = "type")] + pub typ: String, + pub config: Value, + } + let thing = GenericInstructions { + typ: "primary".to_string(), + config: Value::Sequence(vec![ + Value::Null, + Value::Bool(true), + Value::Number(Number::from(65535)), + Value::Number(Number::from(0.54321)), + Value::String("s".into()), + Value::Mapping(Mapping::new()), + ]), + }; + let yaml = unindent( + r#" + --- + type: primary + config: + - ~ + - true + - 65535 + - 0.54321 + - s + - {}"#, + ); + test_serde(&thing, &yaml); +} + +#[test] +fn test_mapping() { + use serde_yaml::Mapping; + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Data { + pub substructure: Mapping, + } + + let mut thing = Data { + substructure: Mapping::new(), + }; + thing.substructure.insert( + Value::String("a".to_owned()), + Value::String("foo".to_owned()), + ); + thing.substructure.insert( + Value::String("b".to_owned()), + Value::String("bar".to_owned()), + ); + + let yaml = unindent( + " + --- + substructure: + a: foo + b: bar", + ); + + test_serde(&thing, &yaml); +} diff --git a/third_party/rust/serde_yaml/tests/test_visitor.rs b/third_party/rust/serde_yaml/tests/test_visitor.rs new file mode 100644 index 0000000000..ca7abd365c --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_visitor.rs @@ -0,0 +1,105 @@ +extern crate serde; +extern crate serde_yaml; + +use std::collections::HashSet; +use std::fmt; + +use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; +use serde::ser::{Serialize, Serializer}; + +#[derive(Debug, Clone, Eq, PartialEq)] +struct Names { + inner: HashSet<String>, +} + +impl Serialize for Names { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut names: Vec<_> = self.inner.iter().collect(); + names.sort(); + names.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Names { + fn deserialize<D>(deserializer: D) -> Result<Names, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(NamesVisitor) + } +} + +struct NamesVisitor; + +impl<'de> Visitor<'de> for NamesVisitor { + type Value = Names; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("names or list of names") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + let mut out = HashSet::new(); + out.insert(v.to_string()); + Ok(Names { inner: out }) + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut out: HashSet<String> = HashSet::new(); + + // FIXME: Change `&str` to String to make the error go away + while let Some(s) = seq.next_element::<&str>()? { + out.insert(s.to_string()); + } + Ok(Names { inner: out }) + } +} + +#[test] +#[ignore] +/// This test is an almost exact replica of the "string or struct" example +/// in the [serde guide](https://serde.rs/string-or-struct.html) +/// +/// FIXME: it currently breaks. If you explicitly select `String` instead +/// of `&str` in the FIXME above, it works. +fn test_visitor() { + let single = r#" +--- +"foo" +"#; + let single_expected = Names { + inner: { + let mut i = HashSet::new(); + i.insert("foo".into()); + i + }, + }; + let multi = r#" +--- +- "foo" +- "bar" +"#; + let multi_expected = Names { + inner: { + let mut i = HashSet::new(); + i.insert("foo".into()); + i.insert("bar".into()); + i + }, + }; + + let result: Names = serde_yaml::from_str(single).expect("didn't deserialize"); + assert_eq!(result, single_expected); + + let result: Names = serde_yaml::from_str(multi).expect("didn't deserialize"); + assert_eq!(result, multi_expected); +} diff --git a/third_party/rust/serde_yaml/tests/version-numbers.rs b/third_party/rust/serde_yaml/tests/version-numbers.rs new file mode 100644 index 0000000000..411eea548e --- /dev/null +++ b/third_party/rust/serde_yaml/tests/version-numbers.rs @@ -0,0 +1,12 @@ +#[macro_use] +extern crate version_sync; + +#[test] +fn test_readme_deps() { + assert_markdown_deps_updated!("README.md"); +} + +#[test] +fn test_html_root_url() { + assert_html_root_url_updated!("src/lib.rs"); +} |