serde_assert-0.8.0/.cargo_vcs_info.json0000644000000001360000000000100135240ustar { "git": { "sha1": "b2b9f4390c59d61d03792542117130ffc202eb1e" }, "path_in_vcs": "" }serde_assert-0.8.0/.github/dependabot.yml000064400000000000000000000004110072674642500165300ustar 00000000000000version: 2 updates: - package-ecosystem: "cargo" directory: "/" schedule: interval: "daily" open-pull-requests-limit: 10 - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" open-pull-requests-limit: 10 serde_assert-0.8.0/.github/workflows/test.yaml000064400000000000000000000047040072674642500176110ustar 00000000000000name: CI on: push: pull_request: permissions: contents: read env: CARGO_TERM_COLOR: always jobs: test: runs-on: ubuntu-latest strategy: matrix: rust: - 1.56.0 - stable - beta - nightly fail-fast: false steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable - run: cargo test no_std: runs-on: ubuntu-latest strategy: matrix: rust: - 1.56.0 - stable - beta - nightly fail-fast: false steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} targets: thumbv6m-none-eabi - run: cargo build --target thumbv6m-none-eabi fmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly with: components: rustfmt - run: cargo fmt -- --check check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly - run: cargo check clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly with: components: clippy - run: cargo clippy -- --deny warnings doc: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly - run: cargo doc --no-deps env: RUSTDOCFLAGS: -D warnings msrv: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly - run: curl -LsSf https://github.com/foresterre/cargo-msrv/releases/latest/download/cargo-msrv_v0.15.1_Linux_x86_64.tar | tar xf - -C ~/.cargo/bin - run: cargo msrv --verify codecov: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly with: components: llvm-tools-preview - run: curl -LsSf https://github.com/taiki-e/cargo-llvm-cov/releases/latest/download/cargo-llvm-cov-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin - run: cargo llvm-cov --all-features --lcov --output-path lcov.info - uses: codecov/codecov-action@v3 with: files: lcov.info fail_ci_if_error: true serde_assert-0.8.0/.gitignore000064400000000000000000000000260072674642500143320ustar 00000000000000/target /Cargo.lock serde_assert-0.8.0/CHANGELOG.md000064400000000000000000000060220072674642500141550ustar 00000000000000# Changelog ## 0.8.0 - 2024-06-27 ### Added - `Deserializer::deserialize_identifier()` now deserializes `Token::Bytes` along with `Token::Str` and `Token::Field`. ## 0.7.1 - 2023-12-26 ### Changed - `PartialEq` implementation for `Tokens` now avoids unnecessary iterator cloning when checking against `Unordered` `Token`s. - Lowered MSRV to `1.56.0`. - Deserializing `Str` and `Bytes` as owned now reuses the existing allocation. ## 0.7.0 - 2023-12-23 ### Added - `Tokens` now implements `IntoIterator`. - The `token` module is now public, containing both `Token` (which is also exposed in the root module) and `Tokens`. - Comparison with nested `Token::Unordered`s is now allowed and correctly handled. - `token::IntoIter` type for iterating over the `Tokens` `struct`. ### Changed - `Deserializer::build()` now takes the tokens as a parameter. These tokens can now be any type that implements `IntoIterator`. - `Tokens` is no longer exposed in the root module, instead being available at `token::Tokens`. - The internals of `Tokens` are no longer public. `Tokens` can no longer be constructed by user code, and is now only returned by the `Serializer`. - Comparison with a `Tokens` can now be done with any type that implements `IntoIterator`. - `de::Builder::build()` now only requires `&self` instead of `&mut self`. - `Error::ExpectedToken` variant has been replaced by `Error::ExpectedSeqEnd`, `Error::ExpectedTupleEnd`, `Error::ExpectedTupleStructEnd`, `Error::ExpectedTupleVariantEnd`, `Error::ExpectedMapEnd`, `Error::ExpectedStructEnd`, and `Error::ExpectedStructVariantEnd` variants. ### Removed - `From` implementation for `serde::de::Unexpected`. - `PartialEq` implementation for `Token`. - `Display` implementation for `Token`. - Dependency on `hashbrown` crate. ## 0.6.0 - 2023-11-19 ### Changed - Increased version of `hashbrown` dependency to `0.14.2`. - Raised MSRV to `1.63.0`. ## 0.5.0 - 2023-05-16 ### Added - `Deserializer` can now be configured to allow (or disallow) zero-copy deserialization. ## 0.4.0 - 2023-04-06 ### Added - `ser::Error` now implements `PartialEq` and `Eq`. ## 0.3.0 - 2023-04-06 ### Changed - `Deserializer` now defaults to setting `self_describing` to `false`. ## 0.2.0 - 2023-01-16 ### Added - `SerializeStructAs` `enum` and accompanying `Builder::serialize_struct_as()` method for specifying whether `struct`s should be serialized as `serde` struct or sequence types. - `SerializeStruct` type to provide a more specialized `serde::SerializeStruct` implementation. ### Changed - `Deserializer::deserialize_struct` can now interpret both `Struct` and `Seq` `Token`s. ### Removed - `CompoundSerializer` no longer implements `serde::SerializeStruct`. ## 0.1.0 - 2023-01-14 ### Added - `Token` and `Tokens` for representing serialized values. - `Serializer`, `ser::Builder`, `ser::Error`, and `ser::CompoundSerializer` for testing serialization. - `Deserializer`, `de::Builder`, and `de::Error` for testing deserialization. serde_assert-0.8.0/Cargo.toml0000644000000025610000000000100115260ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.56.0" name = "serde_assert" version = "0.8.0" authors = ["Anders Evensen"] build = false autobins = false autoexamples = false autotests = false autobenches = false description = "Testing library for serde Serialize and Deserialize implementations." readme = "README.md" keywords = [ "serde", "testing", "serialization", "deserialization", "test", ] categories = [ "development-tools::testing", "encoding", "no-std", ] license = "MIT OR Apache-2.0" repository = "https://github.com/Anders429/serde_assert" [lib] name = "serde_assert" path = "src/lib.rs" [[test]] name = "roundtrip" path = "tests/roundtrip.rs" [dependencies.serde] version = "1.0.152" features = ["alloc"] default-features = false [dev-dependencies.claims] version = "0.7.1" [dev-dependencies.serde_bytes] version = "0.11.8" [dev-dependencies.serde_derive] version = "1.0.152" serde_assert-0.8.0/Cargo.toml.orig000064400000000000000000000012160072674642500152330ustar 00000000000000[package] name = "serde_assert" version = "0.8.0" authors = ["Anders Evensen"] edition = "2021" rust-version = "1.56.0" license = "MIT OR Apache-2.0" readme = "README.md" repository = "https://github.com/Anders429/serde_assert" description = "Testing library for serde Serialize and Deserialize implementations." categories = ["development-tools::testing", "encoding", "no-std"] keywords = ["serde", "testing", "serialization", "deserialization", "test"] [dependencies] serde = {version = "1.0.152", default-features = false, features = ["alloc"]} [dev-dependencies] claims = "0.7.1" serde_bytes = "0.11.8" serde_derive = "1.0.152" serde_assert-0.8.0/LICENSE-APACHE000064400000000000000000000256740072674642500143060ustar 00000000000000 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. serde_assert-0.8.0/LICENSE-MIT000064400000000000000000000021040072674642500137750ustar 00000000000000MIT License Copyright (c) 2023 Anders Evensen 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. serde_assert-0.8.0/README.md000064400000000000000000000126760072674642500136370ustar 00000000000000# serde_assert [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/Anders429/serde_assert/test.yaml?branch=master)](https://github.com/Anders429/serde_assert/actions/workflows/test.yaml) [![codecov.io](https://img.shields.io/codecov/c/gh/Anders429/serde_assert)](https://codecov.io/gh/Anders429/serde_assert) [![crates.io](https://img.shields.io/crates/v/serde_assert)](https://crates.io/crates/serde_assert) [![docs.rs](https://docs.rs/serde_assert/badge.svg)](https://docs.rs/serde_assert) [![MSRV](https://img.shields.io/badge/rustc-1.56.0+-yellow.svg)](#minimum-supported-rust-version) [![License](https://img.shields.io/crates/l/serde_assert)](#license) Testing library for [`serde`](https://crates.io/crates/serde) [`Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html) and [`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html) implementations. This library provides a [`Serializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Serializer.html) and [`Deserializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Deserializer.html) to be used in writing unit tests to assert the behavior of manual [`Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html) and [`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html) implementations, respectively. The implementation behavior can be verified using a sequence of [`Token`](https://docs.rs/serde_assert/latest/serde_assert/struct.Token.html)s representing a generic serialized state. ## Usage The examples below use the [`claims`](https://crates.io/crates/claims) crate for convenient assertions. ### Testing Serialization The [`Serializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Serializer.html) returns a sequence of [`Token`](https://docs.rs/serde_assert/latest/serde_assert/struct.Token.html)s representing the serialization of a value. The returned `Token`s can be checked to be equal to an expected value. ```rust use claims::assert_ok_eq; use serde::Serialize; use serde_assert::{ Serializer, Token, }; let serializer = Serializer::builder().build(); assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); ``` ### Testing Deserialization A [`Deserializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Deserializer.html) is constructed by providing a sequence of [`Token`](https://docs.rs/serde_assert/latest/serde_assert/struct.Token.html)s to be deserialized into a value. ```rust use claims::assert_ok_eq; use serde::Deserialize; use serde_assert::{ Deserializer, Token, }; let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_ok_eq!(bool::deserialize(&mut deserializer), true); ``` ## Comparison with [`serde_test`](https://crates.io/crates/serde_test) This crate provides more flexibility than `serde_test` at the expense of more verbosity. While `serde_test` provides a small API of simple assertion functions, this crate will require you to call [`serialize()`](https://docs.rs/serde/latest/serde/trait.Serialize.html#tymethod.serialize) and [`deserialize()`](https://docs.rs/serde/latest/serde/trait.Deserialize.html#tymethod.deserialize) and assert yourself that the results are as expected. While some users may find that the smaller API of `serde_test` is sufficient for their use-case, others will find that the flexibility of this crate makes testing more complicated `Serailize` and `Deserialize` implementations easier. Among other things, this crate's API provides these advantages: - Direct access to the [`Serializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Serializer.html) and [`Deserializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Deserializer.html), allowing use of all parts of the `serde` `Serializer` and `Deserializer` APIs, such as deserializing types that implement [`DeserializeSeed`](https://docs.rs/serde/latest/serde/de/trait.DeserializeSeed.html). - Customization of [`Serializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Serializer.html)s and [`Deserializer`](https://docs.rs/serde_assert/latest/serde_assert/struct.Deserializer.html)s, allowing configuration of things like human-readability, whether the `Deserializer` should interpret sequences of [`Token`](https://docs.rs/serde_assert/latest/serde_assert/struct.Token.html)s as self-describing, and zero-copy deserialization. - Sophisticated comparison of serialized [`Token`](https://docs.rs/serde_assert/latest/serde_assert/struct.Token.html) sequences, including allowing testing of types whose serialized form can include items in arbitrary order, such as when serializing a [`HashSet`](https://docs.rs/hashbrown/latest/hashbrown/struct.HashSet.html). ## Minimum Supported Rust Version This crate is guaranteed to compile on stable `rustc 1.56.0` and up. ## License This project is licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/Anders429/serde_assert/blob/HEAD/LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](https://github.com/Anders429/serde_assert/blob/HEAD/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. serde_assert-0.8.0/rustfmt.toml000064400000000000000000000002130072674642500147410ustar 00000000000000comment_width = 100 format_code_in_doc_comments = true imports_granularity = "Crate" imports_layout = "Vertical" wrap_comments = true serde_assert-0.8.0/src/de.rs000064400000000000000000005240430072674642500141010ustar 00000000000000//! Testing deserialization implementations. //! //! This module provides a [`Deserializer`] struct for testing deserialization. Construction of //! this struct uses the builder pattern through the [`Builder`] struct, allowing configuration of //! the behavior of the `Deserializer`. //! //! # Example //! ``` rust //! use claims::assert_ok_eq; //! use serde::Deserialize; //! use serde_assert::{ //! Deserializer, //! Token, //! }; //! //! let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); //! //! assert_ok_eq!(bool::deserialize(&mut deserializer), true); //! ``` use crate::{ token, token::{ CanonicalToken, Tokens, UnorderedTokens, }, Token, }; use alloc::{ string::{ String, ToString, }, vec::Vec, }; use core::{ fmt, fmt::Display, mem, }; use serde::{ de, de::{ DeserializeSeed, Error as _, Expected, Unexpected, }, }; /// Deserializer for testing [`Deserialize`] implementations. /// /// A deserializer is constructed from a sequence of [`Token`]s representing the serialized value /// to be deserialized. The value that is output can be compared against an expected value to /// ensure deserialization works correctly. /// /// # Configuration /// The following options can be configured on the [`Builder`]: /// /// - [`is_human_readable()`]: Determines whether the deserializer will interpret the input tokens /// in a readable or compact format. Useful for complicated structs wishing to provide different /// outputs depending on the readability of the serialization type. /// - [`self_describing()`]: Determines whether the deserialization should interpret the input /// tokens as self-describing, meaning the type the tokens should deserialize to can be discerned /// directly from the tokens themselves. If this is set to `false`, calls to [`deserialize_any()`] /// will result in an error. /// - [`zero_copy()`]: Defines whether zero-copy deserialization should be permitted by the /// `Deserializer`, allowing deserializations of strings and byte sequences to avoid allocations. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Deserialize; /// use serde_assert::{ /// Deserializer, /// Token, /// }; /// /// let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); /// /// assert_ok_eq!(bool::deserialize(&mut deserializer), true); /// ``` /// /// [`is_human_readable()`]: Builder::is_human_readable() /// [`Deserialize`]: serde::Deserialize /// [`deserialize_any()`]: #method.deserialize_any /// [`self_describing()`]: Builder::self_describing() /// [`zero_copy()`]: Builder::zero_copy() #[derive(Debug)] pub struct Deserializer<'a> { tokens: token::OwningIter<'a>, revisited_token: Option<&'a mut CanonicalToken>, is_human_readable: bool, self_describing: bool, zero_copy: bool, } impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { if !self.self_describing { return Err(Error::NotSelfDescribing); } let token = self.next_token()?; match token { CanonicalToken::Bool(v) => visitor.visit_bool(*v), CanonicalToken::I8(v) => visitor.visit_i8(*v), CanonicalToken::I16(v) => visitor.visit_i16(*v), CanonicalToken::I32(v) => visitor.visit_i32(*v), CanonicalToken::I64(v) => visitor.visit_i64(*v), CanonicalToken::I128(v) => visitor.visit_i128(*v), CanonicalToken::U8(v) => visitor.visit_u8(*v), CanonicalToken::U16(v) => visitor.visit_u16(*v), CanonicalToken::U32(v) => visitor.visit_u32(*v), CanonicalToken::U64(v) => visitor.visit_u64(*v), CanonicalToken::U128(v) => visitor.visit_u128(*v), CanonicalToken::F32(v) => visitor.visit_f32(*v), CanonicalToken::F64(v) => visitor.visit_f64(*v), CanonicalToken::Char(v) => visitor.visit_char(*v), CanonicalToken::Str(v) => visitor.visit_string(mem::take(v)), CanonicalToken::Bytes(v) => visitor.visit_byte_buf(mem::take(v)), CanonicalToken::None => visitor.visit_none(), CanonicalToken::Some => visitor.visit_some(self), CanonicalToken::Unit | CanonicalToken::UnitStruct { .. } => visitor.visit_unit(), CanonicalToken::UnitVariant { .. } | CanonicalToken::NewtypeVariant { .. } | CanonicalToken::TupleVariant { .. } | CanonicalToken::StructVariant { .. } => { // `EnumDeserializer` takes care of the enum deserialization, which will consume // this token later. self.revisit_token(token); visitor.visit_enum(EnumAccess { deserializer: self }) } CanonicalToken::NewtypeStruct { .. } => visitor.visit_newtype_struct(self), CanonicalToken::Seq { len } => { let mut access = SeqAccess { deserializer: self, len: *len, end_token: EndToken::Seq, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } CanonicalToken::Tuple { len } => { let mut access = SeqAccess { deserializer: self, len: Some(*len), end_token: EndToken::Tuple, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } CanonicalToken::TupleStruct { name: _, len } => { let mut access = SeqAccess { deserializer: self, len: Some(*len), end_token: EndToken::TupleStruct, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } CanonicalToken::Map { len } => { let mut access = MapAccess { deserializer: self, len: *len, end_token: EndToken::Map, ended: false, }; let result = visitor.visit_map(&mut access)?; access.assert_ended()?; Ok(result) } CanonicalToken::Field(v) => visitor.visit_str(v), CanonicalToken::Struct { name: _, len } => { let mut access = MapAccess { deserializer: self, len: Some(*len), end_token: EndToken::Struct, ended: false, }; let result = visitor.visit_map(&mut access)?; access.assert_ended()?; Ok(result) } _ => Err(Self::Error::invalid_type((token).into(), &visitor)), } } fn deserialize_bool(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Bool(v) = token { visitor.visit_bool(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_i8(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::I8(v) = token { visitor.visit_i8(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_i16(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::I16(v) = token { visitor.visit_i16(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_i32(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::I32(v) = token { visitor.visit_i32(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_i64(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::I64(v) = token { visitor.visit_i64(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_i128(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::I128(v) = token { visitor.visit_i128(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_u8(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::U8(v) = token { visitor.visit_u8(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_u16(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::U16(v) = token { visitor.visit_u16(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_u32(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::U32(v) = token { visitor.visit_u32(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_u64(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::U64(v) = token { visitor.visit_u64(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_u128(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::U128(v) = token { visitor.visit_u128(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_f32(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::F32(v) = token { visitor.visit_f32(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_f64(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::F64(v) = token { visitor.visit_f64(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_char(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Char(v) = token { visitor.visit_char(*v) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_str(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Str(v) = token { if self.zero_copy { visitor.visit_borrowed_str(v) } else { visitor.visit_str(v) } } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_string(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Str(v) = token { visitor.visit_string(mem::take(v)) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_bytes(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Bytes(v) = token { if self.zero_copy { visitor.visit_borrowed_bytes(v) } else { visitor.visit_bytes(v) } } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_byte_buf(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Bytes(v) = token { visitor.visit_byte_buf(mem::take(v)) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_option(self, visitor: V) -> Result where V: de::Visitor<'de>, { match self.next_token()? { CanonicalToken::Some => visitor.visit_some(self), CanonicalToken::None => visitor.visit_none(), token => Err(Self::Error::invalid_type((token).into(), &visitor)), } } fn deserialize_unit(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Unit = token { visitor.visit_unit() } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_unit_struct( self, name: &'static str, visitor: V, ) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::UnitStruct { name: struct_name } = token { if name == *struct_name { visitor.visit_unit() } else { Err(Self::Error::invalid_value((token).into(), &visitor)) } } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_newtype_struct( self, name: &'static str, visitor: V, ) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::NewtypeStruct { name: struct_name } = token { if name == *struct_name { visitor.visit_newtype_struct(self) } else { Err(Self::Error::invalid_value((token).into(), &visitor)) } } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_seq(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Seq { len } = token { let mut access = SeqAccess { deserializer: self, len: *len, end_token: EndToken::Seq, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Tuple { len: token_len } = token { if len == *token_len { let mut access = SeqAccess { deserializer: self, len: Some(len), end_token: EndToken::Tuple, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } else { Err(Self::Error::invalid_length(*token_len, &visitor)) } } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_tuple_struct( self, name: &'static str, len: usize, visitor: V, ) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::TupleStruct { name: token_name, len: token_len, } = token { if name != *token_name { Err(Self::Error::invalid_value((token).into(), &visitor)) } else if len != *token_len { Err(Self::Error::invalid_length(*token_len, &visitor)) } else { let mut access = SeqAccess { deserializer: self, len: Some(len), end_token: EndToken::TupleStruct, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_map(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; if let CanonicalToken::Map { len } = token { let mut access = MapAccess { deserializer: self, len: *len, end_token: EndToken::Map, ended: false, }; let result = visitor.visit_map(&mut access)?; access.assert_ended()?; Ok(result) } else { Err(Self::Error::invalid_type((token).into(), &visitor)) } } fn deserialize_struct( self, name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; match token { CanonicalToken::Struct { name: token_name, len, } => { if name == *token_name { let mut access = MapAccess { deserializer: self, len: Some(*len), end_token: EndToken::Struct, ended: false, }; let result = visitor.visit_map(&mut access)?; access.assert_ended()?; Ok(result) } else { Err(Self::Error::invalid_value((token).into(), &visitor)) } } CanonicalToken::Seq { len } => { let mut access = SeqAccess { deserializer: self, len: *len, end_token: EndToken::Seq, ended: false, }; let result = visitor.visit_seq(&mut access)?; access.assert_ended()?; Ok(result) } _ => Err(Self::Error::invalid_type((token).into(), &visitor)), } } fn deserialize_enum( self, name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; match token { CanonicalToken::UnitVariant { name: token_name, .. } | CanonicalToken::NewtypeVariant { name: token_name, .. } | CanonicalToken::TupleVariant { name: token_name, .. } | CanonicalToken::StructVariant { name: token_name, .. } => { if name == *token_name { // `EnumDeserializer` takes care of the enum deserialization, which will consume // this token later. self.revisit_token(token); visitor.visit_enum(EnumAccess { deserializer: self }) } else { Err(Self::Error::invalid_value((token).into(), &visitor)) } } _ => Err(Self::Error::invalid_type((token).into(), &visitor)), } } fn deserialize_identifier(self, visitor: V) -> Result where V: de::Visitor<'de>, { let token = self.next_token()?; match token { CanonicalToken::Str(v) => visitor.visit_str(v), CanonicalToken::Bytes(v) => visitor.visit_bytes(v), CanonicalToken::Field(v) => visitor.visit_str(v), _ => Err(Self::Error::invalid_type((token).into(), &visitor)), } } fn deserialize_ignored_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_any(visitor) } fn is_human_readable(&self) -> bool { self.is_human_readable } } impl<'a> Deserializer<'a> { #[must_use] pub fn builder(tokens: T) -> Builder where T: IntoIterator, { Builder::new(tokens) } fn next_token(&mut self) -> Result<&'a mut CanonicalToken, Error> { loop { let token = self .revisited_token .take() .into_iter() .chain(&mut self.tokens) .next() .ok_or(Error::EndOfTokens)?; if !matches!(token, CanonicalToken::SkippedField(_)) { return Ok(token); } } } fn revisit_token(&mut self, token: &'a mut CanonicalToken) { self.revisited_token = Some(token); } } #[derive(Clone, Copy, Debug)] enum EndToken { Seq, Tuple, TupleStruct, TupleVariant, Map, Struct, StructVariant, } impl PartialEq for CanonicalToken { fn eq(&self, other: &EndToken) -> bool { matches!( (self, other), (Self::SeqEnd, EndToken::Seq) | (Self::TupleEnd, EndToken::Tuple) | (Self::TupleStructEnd, EndToken::TupleStruct) | (Self::TupleVariantEnd, EndToken::TupleVariant) | (Self::MapEnd, EndToken::Map) | (Self::StructEnd, EndToken::Struct) | (Self::StructVariantEnd, EndToken::StructVariant) ) } } struct SeqAccess<'a, 'b> { deserializer: &'a mut Deserializer<'b>, len: Option, end_token: EndToken, ended: bool, } impl<'a, 'de> de::SeqAccess<'de> for SeqAccess<'a, 'de> { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de>, { if self.ended { return Ok(None); } let token = self.deserializer.next_token()?; if *token == self.end_token { self.ended = true; return Ok(None); } self.deserializer.revisit_token(token); seed.deserialize(&mut *self.deserializer).map(Some) } fn size_hint(&self) -> Option { self.len } } impl SeqAccess<'_, '_> { fn assert_ended(&mut self) -> Result<(), Error> { if !self.ended && *self.deserializer.next_token()? != self.end_token { return Err(Error::expected_end_token(self.end_token)); } self.ended = true; Ok(()) } } struct MapAccess<'a, 'b> { deserializer: &'a mut Deserializer<'b>, len: Option, end_token: EndToken, ended: bool, } impl<'a, 'de> de::MapAccess<'de> for MapAccess<'a, 'de> { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: DeserializeSeed<'de>, { if self.ended { return Ok(None); } let token = self.deserializer.next_token()?; if *token == self.end_token { self.ended = true; return Ok(None); } self.deserializer.revisit_token(token); seed.deserialize(&mut *self.deserializer).map(Some) } fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { seed.deserialize(&mut *self.deserializer) } fn size_hint(&self) -> Option { self.len } } impl MapAccess<'_, '_> { fn assert_ended(&mut self) -> Result<(), Error> { if !self.ended && *self.deserializer.next_token()? != self.end_token { return Err(Error::expected_end_token(self.end_token)); } self.ended = true; Ok(()) } } struct EnumAccess<'a, 'b> { deserializer: &'a mut Deserializer<'b>, } impl<'a, 'de> de::EnumAccess<'de> for EnumAccess<'a, 'de> { type Error = Error; type Variant = VariantAccess<'a, 'de>; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: DeserializeSeed<'de>, { let value = seed.deserialize(EnumDeserializer { deserializer: self.deserializer, })?; Ok(( value, VariantAccess { deserializer: self.deserializer, }, )) } } struct VariantAccess<'a, 'b> { deserializer: &'a mut Deserializer<'b>, } impl<'a, 'de> de::VariantAccess<'de> for VariantAccess<'a, 'de> { type Error = Error; fn unit_variant(self) -> Result<(), Self::Error> { Ok(()) } fn newtype_variant_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>, { seed.deserialize(self.deserializer) } fn tuple_variant(self, len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { visitor.visit_seq(SeqAccess { deserializer: self.deserializer, len: Some(len), end_token: EndToken::TupleVariant, ended: false, }) } fn struct_variant( self, _fields: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { visitor.visit_map(MapAccess { deserializer: self.deserializer, len: None, end_token: EndToken::StructVariant, ended: false, }) } } /// Wrapper around `Deserializer` to deserialize enum tokens directly, rather than using /// `EnumAccess`. /// /// This is required to ensure the token can be properly deserialized into a variant. struct EnumDeserializer<'a, 'b> { deserializer: &'a mut Deserializer<'b>, } impl<'a, 'de> de::Deserializer<'de> for EnumDeserializer<'a, 'de> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { match self.deserializer.next_token()? { CanonicalToken::UnitVariant { variant, .. } | CanonicalToken::TupleVariant { variant, .. } | CanonicalToken::NewtypeVariant { variant, .. } | CanonicalToken::StructVariant { variant, .. } => visitor.visit_str(variant), _ => unreachable!(), } } fn deserialize_bool(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_i8(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_i16(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_i32(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_i64(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_i128(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_u8(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_u16(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_u32(self, visitor: V) -> Result where V: de::Visitor<'de>, { match self.deserializer.next_token()? { CanonicalToken::UnitVariant { variant_index, .. } | CanonicalToken::TupleVariant { variant_index, .. } | CanonicalToken::NewtypeVariant { variant_index, .. } | CanonicalToken::StructVariant { variant_index, .. } => { visitor.visit_u32(*variant_index) } _ => unreachable!(), } } fn deserialize_u64(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_u128(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_u32(visitor) } fn deserialize_f32(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_f64(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_char(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_str(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_any(visitor) } fn deserialize_string(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_any(visitor) } fn deserialize_bytes(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_byte_buf(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_option(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_unit(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_unit_struct( self, _name: &'static str, _visitor: V, ) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_newtype_struct( self, _name: &'static str, _visitor: V, ) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_seq(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_tuple(self, _len: usize, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_tuple_struct( self, _name: &'static str, _len: usize, _visitor: V, ) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_map(self, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_struct( self, _name: &'static str, _fields: &'static [&'static str], _visitor: V, ) -> Result where V: de::Visitor<'de>, { Err(Error::UnsupportedEnumDeserializerMethod) } fn deserialize_enum( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { self.deserialize_any(visitor) } fn deserialize_identifier(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_any(visitor) } fn deserialize_ignored_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.deserialize_any(visitor) } fn is_human_readable(&self) -> bool { self.deserializer.is_human_readable() } } /// A builder for a [`Deserializer`]. /// /// Construction of a `Deserializer` follows the builder pattern. Configuration options can be set /// on the `Builder`, and then the actual `Deserializer` is constructed by calling [`build()`]. /// /// # Example /// ``` rust /// use serde_assert::{ /// Deserializer, /// Token, /// }; /// /// let deserializer = Deserializer::builder([Token::Bool(true)]) /// .is_human_readable(false) /// .self_describing(true) /// .build(); /// ``` /// /// [`build()`]: Builder::build() /// [::builder()`]: Builder::tokens() #[derive(Debug)] pub struct Builder { tokens: Tokens, is_human_readable: bool, self_describing: bool, zero_copy: bool, } impl Builder { /// Creates a new `Builder` containing the provided tokens. fn new(tokens: T) -> Self where T: IntoIterator, { fn collect_canonical(tokens: &mut Vec, iter: I) where I: Iterator, { for token in iter { match token.try_into() { Ok(canonical_token) => tokens.push(canonical_token), Err(UnorderedTokens(unordered_tokens)) => { collect_canonical( tokens, unordered_tokens.iter().copied().flatten().cloned(), ); } } } } Self { tokens: { let mut canonical_tokens = Vec::new(); collect_canonical(&mut canonical_tokens, tokens.into_iter()); Tokens(canonical_tokens) }, is_human_readable: true, self_describing: false, zero_copy: true, } } /// Determines whether the deserializer will interpret the input tokens in a readable or compact /// format. /// /// Useful for complicated structs wishing to provide different outputs depending on the /// readability of the serialization type. /// /// If not set, the default value is `true`. /// /// # Example /// ``` rust /// use serde_assert::{ /// Deserializer, /// Token, /// }; /// /// let deserializer = Deserializer::builder([Token::Bool(true)]) /// .is_human_readable(false) /// .build(); /// ``` pub fn is_human_readable(&mut self, is_human_readable: bool) -> &mut Self { self.is_human_readable = is_human_readable; self } /// Determines whether the deserialization should interpret the input tokens as self-describing, /// meaning the type the tokens should deserialize to can be discerned directly from the tokens /// themselves. /// /// If this is set to `false`, calls to [`deserialize_any()`] will result in an error. /// /// If not set, the default value is `false`. /// /// # Example /// ``` rust /// use serde_assert::{ /// Deserializer, /// Token, /// }; /// /// let deserializer = Deserializer::builder([Token::Bool(true)]) /// .self_describing(true) /// .build(); /// ``` /// /// [`deserialize_any()`]: ../struct.Deserializer.html#method.deserialize_any pub fn self_describing(&mut self, self_describing: bool) -> &mut Self { self.self_describing = self_describing; self } /// Defines whether zero-copy deserialization should be permitted by the `Deserializer`, /// allowing deserializations of strings and byte sequences to avoid allocations. /// /// If not set, the default value is `true`. /// /// Some `serde` formats do not permit zero-copy deserialization. Setting this value to `false` /// allows testing `Deserialize` implementations in a similar environment. /// /// # Example /// ``` rust /// use serde_assert::{ /// Deserializer, /// Token, /// }; /// /// let deserializer = Deserializer::builder([Token::Bool(true)]) /// .zero_copy(false) /// .build(); /// ``` pub fn zero_copy(&mut self, zero_copy: bool) -> &mut Self { self.zero_copy = zero_copy; self } /// Build a new [`Deserializer`] using this `Builder`. /// /// Constructs a new `Deserializer` using the configuration options set on this `Builder`. /// /// # Example /// ``` rust /// use serde_assert::{ /// Deserializer, /// Token, /// }; /// /// let deserializer = Deserializer::builder([Token::Bool(true)]) /// .is_human_readable(false) /// .build(); /// ``` #[must_use] pub fn build<'a>(&self) -> Deserializer<'a> { Deserializer { tokens: token::OwningIter::new(self.tokens.clone()), revisited_token: None, is_human_readable: self.is_human_readable, self_describing: self.self_describing, zero_copy: self.zero_copy, } } } /// An error encountered during deserialization. /// /// # Example /// ```rust /// use serde::de::Error as _; /// use serde_assert::de::Error; /// /// assert_eq!( /// format!("{}", Error::missing_field("foo")), /// "missing field foo" /// ); /// ``` #[derive(Debug, PartialEq)] pub enum Error { /// The [`Deserializer`] reached the end of the input [`Token`]s before deserialization was /// completed. EndOfTokens, /// Expected a `Token::SeqEnd`. ExpectedSeqEnd, /// Expected a `Token::TupleEnd`. ExpectedTupleEnd, /// Expected a `Token::TupleStructEnd`. ExpectedTupleStructEnd, /// Expected a `Token::TupleVariantEnd`. ExpectedTupleVariantEnd, /// Expected a `Token::MapEnd`. ExpectedMapEnd, /// Expected a `Token::StructEnd`. ExpectedStructEnd, /// Expected a `Token::StructVariantEnd`. ExpectedStructVariantEnd, /// An unsupported [`serde::Deserializer`] method was called during deserialization of an /// `enum` variant. /// /// If you encounter this error, check what methods you are calling when deserializing your /// `enum` variants. Many standard `serde` types are not supported in this context. UnsupportedEnumDeserializerMethod, /// The [`Deserializer`] was set to be non-self-describing, but the [`Deserialize`] /// implementation made a call to [`deserialize_any()`]. /// /// [`Deserialize`]: serde::Deserialize /// [`deserialize_any()`]: ../struct.Deserializer.html#method.deserialize_any NotSelfDescribing, /// An error created by calling [`custom()`]. /// /// [`custom()`]: Error::custom() Custom(String), /// An error created by calling [`invalid_type()`]. /// /// [`invalid_type()`]: Error::invalid_type() InvalidType(String, String), /// An error created by calling [`invalid_value()`]. /// /// [`invalid_value()`]: Error::invalid_value() InvalidValue(String, String), /// An error created by calling [`invalid_length()`]. /// /// [`invalid_length()`]: Error::invalid_length() InvalidLength(usize, String), /// An error created by calling [`unknown_variant()`]. /// /// [`unknown_variant()`]: Error::unknown_variant() UnknownVariant(String, &'static [&'static str]), /// An error created by calling [`unknown_field()`]. /// /// [`unknown_field()`]: Error::unknown_field() UnknownField(String, &'static [&'static str]), /// An error created by calling [`missing_field()`]. /// /// [`missing_field()`]: Error::missing_field() MissingField(&'static str), /// An error created by calling [`duplicate_field()`]. /// /// [`duplicate_field()`]: Error::duplicate_field() DuplicateField(&'static str), } impl Error { fn expected_end_token(end_token: EndToken) -> Self { match end_token { EndToken::Seq => Self::ExpectedSeqEnd, EndToken::Tuple => Self::ExpectedTupleEnd, EndToken::TupleStruct => Self::ExpectedTupleStructEnd, EndToken::TupleVariant => Self::ExpectedTupleVariantEnd, EndToken::Map => Self::ExpectedMapEnd, EndToken::Struct => Self::ExpectedStructEnd, EndToken::StructVariant => Self::ExpectedStructVariantEnd, } } } impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::EndOfTokens => f.write_str("end of tokens"), Self::ExpectedSeqEnd => f.write_str("expected token SeqEnd"), Self::ExpectedTupleEnd => f.write_str("expected token TupleEnd"), Self::ExpectedTupleStructEnd => f.write_str("expected token TupleStructEnd"), Self::ExpectedTupleVariantEnd => f.write_str("expected token TupleVariantEnd"), Self::ExpectedMapEnd => f.write_str("expected token MapEnd"), Self::ExpectedStructEnd => f.write_str("expected token StructEnd"), Self::ExpectedStructVariantEnd => f.write_str("expected token StructVariantEnd"), Self::UnsupportedEnumDeserializerMethod => f.write_str("use of unsupported enum deserializer method"), Self::NotSelfDescribing => f.write_str("attempted to deserialize as self-describing when deserializer is not set as self-describing"), Self::Custom(s) => f.write_str(s), Self::InvalidType(unexpected, expected) => write!(f, "invalid type: expected {}, found {}", expected, unexpected), Self::InvalidValue(unexpected, expected) => write!(f, "invalid value: expected {}, found {}", expected, unexpected), Self::InvalidLength(length, expected) => write!(f, "invalid length {}, expected {}", length, expected), Self::UnknownVariant(variant, expected) => write!(f, "unknown variant {}, expected one of {:?}", variant, expected), Self::UnknownField(field, expected) => write!(f, "unknown field {}, expected one of {:?}", field, expected), Self::MissingField(field) => write!(f, "missing field {}", field), Self::DuplicateField(field) => write!(f, "duplicate field {}", field), } } } impl de::StdError for Error {} impl de::Error for Error { fn custom(msg: T) -> Self where T: fmt::Display, { Self::Custom(msg.to_string()) } fn invalid_type(unexpected: Unexpected, expected: &dyn Expected) -> Self { Self::InvalidType(unexpected.to_string(), expected.to_string()) } fn invalid_value(unexpected: Unexpected, expected: &dyn Expected) -> Self { Self::InvalidValue(unexpected.to_string(), expected.to_string()) } fn invalid_length(len: usize, expected: &dyn Expected) -> Self { Self::InvalidLength(len, expected.to_string()) } fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { Self::UnknownVariant(variant.to_string(), expected) } fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { Self::UnknownField(field.to_string(), expected) } fn missing_field(field: &'static str) -> Self { Self::MissingField(field) } fn duplicate_field(field: &'static str) -> Self { Self::DuplicateField(field) } } #[cfg(test)] mod tests { use super::{ Deserializer, EnumDeserializer, Error, }; use crate::{ token::CanonicalToken, Token, }; use alloc::{ borrow::ToOwned, fmt, format, string::String, vec, vec::Vec, }; use claims::{ assert_err_eq, assert_ok, assert_ok_eq, }; use serde::{ de, de::{ Deserialize, Error as _, IgnoredAny, Unexpected, VariantAccess, Visitor, }, Deserializer as _, }; use serde_bytes::ByteBuf; use serde_derive::Deserialize; use std::collections::HashMap; #[derive(Debug, PartialEq)] enum Any { Bool(bool), I8(i8), I16(i16), I32(i32), I64(i64), I128(i128), U8(u8), U16(u16), U32(u32), U64(u64), U128(u128), F32(f32), F64(f64), Char(char), Str(String), Bytes(Vec), Option(Option), Unit, UnitVariant, NewtypeStruct(u32), NewtypeVariant(u32), Seq(u32, u32, u32), TupleVariant(u32, u32, u32), Map { foo: u32, bar: bool }, StructVariant { foo: u32, bar: bool }, } impl<'de> Deserialize<'de> for Any { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct AnyVisitor; impl<'de> Visitor<'de> for AnyVisitor { type Value = Any; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct Any") } fn visit_bool(self, v: bool) -> Result where E: serde::de::Error, { Ok(Any::Bool(v)) } fn visit_i8(self, v: i8) -> Result where E: serde::de::Error, { Ok(Any::I8(v)) } fn visit_i16(self, v: i16) -> Result where E: serde::de::Error, { Ok(Any::I16(v)) } fn visit_i32(self, v: i32) -> Result where E: serde::de::Error, { Ok(Any::I32(v)) } fn visit_i64(self, v: i64) -> Result where E: serde::de::Error, { Ok(Any::I64(v)) } fn visit_i128(self, v: i128) -> Result where E: serde::de::Error, { Ok(Any::I128(v)) } fn visit_u8(self, v: u8) -> Result where E: serde::de::Error, { Ok(Any::U8(v)) } fn visit_u16(self, v: u16) -> Result where E: serde::de::Error, { Ok(Any::U16(v)) } fn visit_u32(self, v: u32) -> Result where E: serde::de::Error, { Ok(Any::U32(v)) } fn visit_u64(self, v: u64) -> Result where E: serde::de::Error, { Ok(Any::U64(v)) } fn visit_u128(self, v: u128) -> Result where E: serde::de::Error, { Ok(Any::U128(v)) } fn visit_f32(self, v: f32) -> Result where E: serde::de::Error, { Ok(Any::F32(v)) } fn visit_f64(self, v: f64) -> Result where E: serde::de::Error, { Ok(Any::F64(v)) } fn visit_char(self, v: char) -> Result where E: serde::de::Error, { Ok(Any::Char(v)) } fn visit_str(self, v: &str) -> Result where E: de::Error, { Ok(Any::Str(v.to_owned())) } fn visit_bytes(self, v: &[u8]) -> Result where E: serde::de::Error, { Ok(Any::Bytes(v.to_owned())) } fn visit_some(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { if let Any::U32(v) = deserializer.deserialize_any(self)? { Ok(Any::Option(Some(v))) } else { unreachable!() } } fn visit_none(self) -> Result where E: serde::de::Error, { Ok(Any::Option(None)) } fn visit_unit(self) -> Result where E: serde::de::Error, { Ok(Any::Unit) } fn visit_enum(self, data: A) -> Result where A: serde::de::EnumAccess<'de>, { enum Variant { Unit, Newtype, Tuple, Struct, } impl<'de> Deserialize<'de> for Variant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct VariantVisitor; impl<'de> Visitor<'de> for VariantVisitor { type Value = Variant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("enum Variant") } fn visit_str(self, v: &str) -> Result where E: de::Error, { match v { "unit" => Ok(Variant::Unit), "newtype" => Ok(Variant::Newtype), "tuple" => Ok(Variant::Tuple), "struct" => Ok(Variant::Struct), _ => Err(E::invalid_value(Unexpected::Str(v), &self)), } } } deserializer.deserialize_any(VariantVisitor) } } let (variant, access) = data.variant()?; match variant { Variant::Unit => { access.unit_variant()?; Ok(Any::UnitVariant) } Variant::Newtype => { if let Any::U32(v) = access.newtype_variant()? { Ok(Any::NewtypeVariant(v)) } else { unreachable!() } } Variant::Tuple => { if let Any::Seq(a, b, c) = access.tuple_variant(3, self)? { Ok(Any::TupleVariant(a, b, c)) } else { unreachable!() } } Variant::Struct => { if let Any::Map { foo, bar } = access.struct_variant(&["foo", "bar"], self)? { Ok(Any::StructVariant { foo, bar }) } else { unreachable!() } } } } fn visit_newtype_struct(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { if let Any::U32(v) = deserializer.deserialize_any(self)? { Ok(Any::NewtypeStruct(v)) } else { unreachable!() } } fn visit_seq(self, mut seq: A) -> Result where A: serde::de::SeqAccess<'de>, { Ok(Any::Seq( seq.next_element()? .ok_or(A::Error::invalid_length(0, &self))?, seq.next_element()? .ok_or(A::Error::invalid_length(1, &self))?, seq.next_element()? .ok_or(A::Error::invalid_length(2, &self))?, )) } fn visit_map(self, mut map: A) -> Result where A: serde::de::MapAccess<'de>, { enum Field { Foo, Bar, } impl<'de> Deserialize<'de> for Field { fn deserialize(deserializer: D) -> Result where D: serde::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("`foo` or `bar`") } fn visit_str(self, value: &str) -> Result where E: de::Error, { match value { "foo" => Ok(Field::Foo), "bar" => Ok(Field::Bar), _ => Err(E::unknown_field(value, &["foo", "bar"])), } } } deserializer.deserialize_identifier(FieldVisitor) } } let mut foo = None; let mut bar = None; while let Some(key) = map.next_key()? { match key { Field::Foo => { if foo.is_some() { return Err(A::Error::duplicate_field("foo")); } foo = Some(map.next_value()?); } Field::Bar => { if bar.is_some() { return Err(A::Error::duplicate_field("bar")); } bar = Some(map.next_value()?); } } } if foo.is_none() { return Err(A::Error::missing_field("foo")); } if bar.is_none() { return Err(A::Error::missing_field("bar")); } Ok(Any::Map { foo: foo.unwrap(), bar: bar.unwrap(), }) } } deserializer.deserialize_any(AnyVisitor) } } #[test] fn deserialize_any_bool() { let mut deserializer = Deserializer::builder([Token::Bool(true)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Bool(true)); } #[test] fn deserialize_any_i8() { let mut deserializer = Deserializer::builder([Token::I8(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::I8(42)); } #[test] fn deserialize_any_i16() { let mut deserializer = Deserializer::builder([Token::I16(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::I16(42)); } #[test] fn deserialize_any_i32() { let mut deserializer = Deserializer::builder([Token::I32(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::I32(42)); } #[test] fn deserialize_any_i64() { let mut deserializer = Deserializer::builder([Token::I64(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::I64(42)); } #[test] fn deserialize_any_i128() { let mut deserializer = Deserializer::builder([Token::I128(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::I128(42)); } #[test] fn deserialize_any_u8() { let mut deserializer = Deserializer::builder([Token::U8(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::U8(42)); } #[test] fn deserialize_any_u16() { let mut deserializer = Deserializer::builder([Token::U16(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::U16(42)); } #[test] fn deserialize_any_u32() { let mut deserializer = Deserializer::builder([Token::U32(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::U32(42)); } #[test] fn deserialize_any_u64() { let mut deserializer = Deserializer::builder([Token::U64(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::U64(42)); } #[test] fn deserialize_any_u128() { let mut deserializer = Deserializer::builder([Token::U128(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::U128(42)); } #[test] fn deserialize_any_f32() { let mut deserializer = Deserializer::builder([Token::F32(42.)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::F32(42.)); } #[test] fn deserialize_any_f64() { let mut deserializer = Deserializer::builder([Token::F64(42.)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::F64(42.)); } #[test] fn deserialize_any_char() { let mut deserializer = Deserializer::builder([Token::Char('a')]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Char('a')); } #[test] fn deserialize_any_str() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::Str("foo".to_owned()) ); } #[test] fn deserialize_any_bytes() { let mut deserializer = Deserializer::builder([Token::Bytes(b"foo".to_vec())]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::Bytes(b"foo".to_vec()) ); } #[test] fn deserialize_any_some() { let mut deserializer = Deserializer::builder([Token::Some, Token::U32(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Option(Some(42)),); } #[test] fn deserialize_any_none() { let mut deserializer = Deserializer::builder([Token::None]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Option(None),); } #[test] fn deserialize_any_unit() { let mut deserializer = Deserializer::builder([Token::Unit]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Unit,); } #[test] fn deserialize_any_unit_struct() { let mut deserializer = Deserializer::builder([Token::UnitStruct { name: "foo" }]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Unit,); } #[test] fn deserialize_any_unit_variant() { let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "foo", variant_index: 0, variant: "unit", }]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::UnitVariant,); } #[test] fn deserialize_any_newtype_struct() { let mut deserializer = Deserializer::builder([Token::NewtypeStruct { name: "foo" }, Token::U32(42)]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::NewtypeStruct(42),); } #[test] fn deserialize_any_newtype_variant() { let mut deserializer = Deserializer::builder([ Token::NewtypeVariant { name: "foo", variant_index: 0, variant: "newtype", }, Token::U32(42), ]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::NewtypeVariant(42),); } #[test] fn deserialize_any_seq() { let mut deserializer = Deserializer::builder([ Token::Seq { len: None }, Token::U32(1), Token::U32(2), Token::U32(3), Token::SeqEnd, ]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Seq(1, 2, 3),); } #[test] fn deserialize_any_tuple() { let mut deserializer = Deserializer::builder([ Token::Tuple { len: 3 }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleEnd, ]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Seq(1, 2, 3),); } #[test] fn deserialize_any_tuple_struct() { let mut deserializer = Deserializer::builder([ Token::TupleStruct { name: "foo", len: 3, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleStructEnd, ]) .self_describing(true) .build(); assert_ok_eq!(Any::deserialize(&mut deserializer), Any::Seq(1, 2, 3),); } #[test] fn deserialize_any_tuple_variant() { let mut deserializer = Deserializer::builder([ Token::TupleVariant { name: "foo", variant_index: 0, variant: "tuple", len: 3, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleVariantEnd, ]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::TupleVariant(1, 2, 3), ); } #[test] fn deserialize_any_map() { let mut deserializer = Deserializer::builder([ Token::Map { len: Some(3) }, Token::Str("foo".to_owned()), Token::U32(42), Token::Str("bar".to_owned()), Token::Bool(false), Token::MapEnd, ]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::Map { foo: 42, bar: false }, ); } #[test] fn deserialize_any_field() { let mut deserializer = Deserializer::builder([Token::Field("foo")]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::Str("foo".to_owned()), ); } #[test] fn deserialize_any_struct() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "foo", len: 3, }, Token::Field("foo"), Token::U32(42), Token::Field("bar"), Token::Bool(false), Token::StructEnd, ]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::Map { foo: 42, bar: false }, ); } #[test] fn deserialize_any_struct_variant() { let mut deserializer = Deserializer::builder([ Token::StructVariant { name: "foo", variant_index: 0, variant: "struct", len: 3, }, Token::Field("foo"), Token::U32(42), Token::Field("bar"), Token::Bool(false), Token::StructVariantEnd, ]) .self_describing(true) .build(); assert_ok_eq!( Any::deserialize(&mut deserializer), Any::StructVariant { foo: 42, bar: false }, ); } #[test] fn deserialize_any_seq_end_fails() { let mut deserializer = Deserializer::builder([Token::SeqEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::SeqEnd).into(), &"struct Any"), ); } #[test] fn deserialize_any_tuple_end_fails() { let mut deserializer = Deserializer::builder([Token::TupleEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::TupleEnd).into(), &"struct Any"), ); } #[test] fn deserialize_any_tuple_struct_end_fails() { let mut deserializer = Deserializer::builder([Token::TupleStructEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::TupleStructEnd).into(), &"struct Any"), ); } #[test] fn deserialize_any_tuple_variant_end_fails() { let mut deserializer = Deserializer::builder([Token::TupleVariantEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::TupleVariantEnd).into(), &"struct Any"), ); } #[test] fn deserialize_any_map_end_fails() { let mut deserializer = Deserializer::builder([Token::MapEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::MapEnd).into(), &"struct Any"), ); } #[test] fn deserialize_any_struct_end_fails() { let mut deserializer = Deserializer::builder([Token::StructEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::StructEnd).into(), &"struct Any"), ); } #[test] fn deserialize_any_struct_variant_end_fails() { let mut deserializer = Deserializer::builder([Token::StructVariantEnd]) .self_describing(true) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::invalid_type( (&mut CanonicalToken::StructVariantEnd).into(), &"struct Any" ), ); } #[test] fn deserialize_any_default_not_self_describing() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::NotSelfDescribing ); } #[test] fn deserialize_any_not_self_describing() { let mut deserializer = Deserializer::builder([Token::Bool(true)]) .self_describing(false) .build(); assert_err_eq!( Any::deserialize(&mut deserializer), Error::NotSelfDescribing ); } #[test] fn deserialize_bool() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_ok_eq!(bool::deserialize(&mut deserializer), true); } #[test] fn deserialize_bool_error() { let mut deserializer = Deserializer::builder([Token::I8(42)]).build(); assert_err_eq!( bool::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::I8(42)).into(), &"a boolean") ); } #[test] fn deserialize_i8() { let mut deserializer = Deserializer::builder([Token::I8(42)]).build(); assert_ok_eq!(i8::deserialize(&mut deserializer), 42); } #[test] fn deserialize_i8_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( i8::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"i8") ); } #[test] fn deserialize_i16() { let mut deserializer = Deserializer::builder([Token::I16(42)]).build(); assert_ok_eq!(i16::deserialize(&mut deserializer), 42); } #[test] fn deserialize_i16_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( i16::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"i16") ); } #[test] fn deserialize_i32() { let mut deserializer = Deserializer::builder([Token::I32(42)]).build(); assert_ok_eq!(i32::deserialize(&mut deserializer), 42); } #[test] fn deserialize_i32_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( i32::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"i32") ); } #[test] fn deserialize_i64() { let mut deserializer = Deserializer::builder([Token::I64(42)]).build(); assert_ok_eq!(i64::deserialize(&mut deserializer), 42); } #[test] fn deserialize_i64_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( i64::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"i64") ); } #[test] fn deserialize_i128() { let mut deserializer = Deserializer::builder([Token::I128(42)]).build(); assert_ok_eq!(i128::deserialize(&mut deserializer), 42); } #[test] fn deserialize_i128_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( i128::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"i128") ); } #[test] fn deserialize_u8() { let mut deserializer = Deserializer::builder([Token::U8(42)]).build(); assert_ok_eq!(u8::deserialize(&mut deserializer), 42); } #[test] fn deserialize_u8_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( u8::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"u8") ); } #[test] fn deserialize_u16() { let mut deserializer = Deserializer::builder([Token::U16(42)]).build(); assert_ok_eq!(u16::deserialize(&mut deserializer), 42); } #[test] fn deserialize_u16_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( u16::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"u16") ); } #[test] fn deserialize_u32() { let mut deserializer = Deserializer::builder([Token::U32(42)]).build(); assert_ok_eq!(u32::deserialize(&mut deserializer), 42); } #[test] fn deserialize_u32_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( u32::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"u32") ); } #[test] fn deserialize_u64() { let mut deserializer = Deserializer::builder([Token::U64(42)]).build(); assert_ok_eq!(u64::deserialize(&mut deserializer), 42); } #[test] fn deserialize_u64_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( u64::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"u64") ); } #[test] fn deserialize_u128() { let mut deserializer = Deserializer::builder([Token::U128(42)]).build(); assert_ok_eq!(u128::deserialize(&mut deserializer), 42); } #[test] fn deserialize_u128_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( u128::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"u128") ); } #[test] fn deserialize_f32() { let mut deserializer = Deserializer::builder([Token::F32(42.)]).build(); assert_ok_eq!(f32::deserialize(&mut deserializer), 42.); } #[test] fn deserialize_f32_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( f32::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"f32") ); } #[test] fn deserialize_f64() { let mut deserializer = Deserializer::builder([Token::F64(42.)]).build(); assert_ok_eq!(f64::deserialize(&mut deserializer), 42.); } #[test] fn deserialize_f64_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( f64::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"f64") ); } #[test] fn deserialize_char() { let mut deserializer = Deserializer::builder([Token::Char('a')]).build(); assert_ok_eq!(char::deserialize(&mut deserializer), 'a'); } #[test] fn deserialize_char_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( char::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"a character") ); } #[derive(Debug, PartialEq)] struct Str(String); impl<'de> Deserialize<'de> for Str { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct StrVisitor; impl<'de> Visitor<'de> for StrVisitor { type Value = Str; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("str") } fn visit_str(self, v: &str) -> Result where E: de::Error, { Ok(Str(v.to_owned())) } } deserializer.deserialize_str(StrVisitor) } } #[test] fn deserialize_str() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]).build(); assert_ok_eq!(Str::deserialize(&mut deserializer), Str("foo".to_owned())); } #[test] fn deserialize_str_zero_copy_disabled() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]) .zero_copy(false) .build(); assert_ok_eq!(Str::deserialize(&mut deserializer), Str("foo".to_owned())); } #[test] fn deserialize_str_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Str::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"str") ); } #[derive(Debug, Eq, PartialEq)] struct BorrowedStr<'a>(&'a str); impl<'de> Deserialize<'de> for BorrowedStr<'de> { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct BorrowedStrVisitor; impl<'de> Visitor<'de> for BorrowedStrVisitor { type Value = BorrowedStr<'de>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a borrowed str") } fn visit_borrowed_str(self, v: &'de str) -> Result where E: de::Error, { Ok(BorrowedStr(v)) } } deserializer.deserialize_str(BorrowedStrVisitor) } } #[test] fn deserialize_borrowed_str() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]).build(); assert_ok_eq!( BorrowedStr::deserialize(&mut deserializer), BorrowedStr("foo") ); } #[test] fn deserialize_borrowed_str_zero_copy_disabled_error() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]) .zero_copy(false) .build(); assert_err_eq!( BorrowedStr::deserialize(&mut deserializer), Error::invalid_type( (&mut CanonicalToken::Str("foo".to_owned())).into(), &"a borrowed str" ) ); } #[test] fn deserialize_string() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]).build(); assert_ok_eq!(String::deserialize(&mut deserializer), "foo".to_owned()); } #[test] fn deserialize_string_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( String::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"a string") ); } #[derive(Debug, PartialEq)] struct Bytes(Vec); impl<'de> Deserialize<'de> for Bytes { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct BytesVisitor; impl<'de> Visitor<'de> for BytesVisitor { type Value = Bytes; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("bytes") } fn visit_bytes(self, v: &[u8]) -> Result where E: de::Error, { Ok(Bytes(v.to_vec())) } } deserializer.deserialize_bytes(BytesVisitor) } } #[test] fn deserialize_bytes() { let mut deserializer = Deserializer::builder([Token::Bytes(b"foo".to_vec())]).build(); assert_ok_eq!( Bytes::deserialize(&mut deserializer), Bytes(b"foo".to_vec()) ); } #[test] fn deserialize_bytes_zero_copy_disabled() { let mut deserializer = Deserializer::builder([Token::Bytes(b"foo".to_vec())]) .zero_copy(false) .build(); assert_ok_eq!( Bytes::deserialize(&mut deserializer), Bytes(b"foo".to_vec()) ); } #[test] fn deserialize_bytes_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Bytes::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"bytes") ); } #[derive(Debug, Eq, PartialEq)] struct BorrowedBytes<'a>(&'a [u8]); impl<'de> Deserialize<'de> for BorrowedBytes<'de> { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct BorrowedBytesVisitor; impl<'de> Visitor<'de> for BorrowedBytesVisitor { type Value = BorrowedBytes<'de>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("borrowed bytes") } fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: de::Error, { Ok(BorrowedBytes(v)) } } deserializer.deserialize_bytes(BorrowedBytesVisitor) } } #[test] fn deserialize_borrowed_bytes() { let mut deserializer = Deserializer::builder([Token::Bytes(b"foo".to_vec())]).build(); assert_ok_eq!( BorrowedBytes::deserialize(&mut deserializer), BorrowedBytes(b"foo") ); } #[test] fn deserialize_borrowed_bytes_zero_copy_disabled_error() { let mut deserializer = Deserializer::builder([Token::Bytes(b"foo".to_vec())]) .zero_copy(false) .build(); assert_err_eq!( BorrowedBytes::deserialize(&mut deserializer), Error::invalid_type( (&mut CanonicalToken::Bytes(b"foo".to_vec())).into(), &"borrowed bytes" ) ); } #[test] fn deserialize_byte_buf() { let mut deserializer = Deserializer::builder([Token::Bytes(b"foo".to_vec())]).build(); assert_ok_eq!( ByteBuf::deserialize(&mut deserializer), ByteBuf::from(b"foo".to_vec()) ); } #[test] fn deserialize_byte_buf_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( ByteBuf::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"byte array") ); } #[test] fn deserialize_option_some() { let mut deserializer = Deserializer::builder([Token::Some, Token::U32(42)]).build(); assert_ok_eq!(Option::::deserialize(&mut deserializer), Some(42)); } #[test] fn deserialize_option_none() { let mut deserializer = Deserializer::builder([Token::None]).build(); assert_ok_eq!(Option::::deserialize(&mut deserializer), None); } #[test] fn deserialize_option_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Option::::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"option") ); } #[test] fn deserialize_unit() { let mut deserializer = Deserializer::builder([Token::Unit]).build(); assert_ok_eq!(<()>::deserialize(&mut deserializer), ()); } #[test] fn deserialize_unit_error() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( <()>::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"unit") ); } #[derive(Debug, PartialEq)] struct Unit; impl<'de> Deserialize<'de> for Unit { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct UnitVisitor; impl<'de> Visitor<'de> for UnitVisitor { type Value = Unit; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("unit struct") } fn visit_unit(self) -> Result where E: de::Error, { Ok(Unit) } } deserializer.deserialize_unit_struct("Unit", UnitVisitor) } } #[test] fn deserialize_unit_struct() { let mut deserializer = Deserializer::builder([Token::UnitStruct { name: "Unit" }]).build(); assert_ok_eq!(Unit::deserialize(&mut deserializer), Unit); } #[test] fn deserialize_unit_struct_error_invalid_name() { let mut deserializer = Deserializer::builder([Token::UnitStruct { name: "Not Unit" }]).build(); assert_err_eq!( Unit::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::UnitStruct { name: "Not Unit" }).into(), &"unit struct" ) ); } #[test] fn deserialize_unit_struct_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Unit::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"unit struct") ); } #[derive(Debug, PartialEq)] struct Newtype(u32); impl<'de> Deserialize<'de> for Newtype { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct NewtypeVisitor; impl<'de> Visitor<'de> for NewtypeVisitor { type Value = Newtype; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("newtype struct") } fn visit_newtype_struct(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { Ok(Newtype(u32::deserialize(deserializer)?)) } } deserializer.deserialize_newtype_struct("Newtype", NewtypeVisitor) } } #[test] fn deserialize_newtype_struct() { let mut deserializer = Deserializer::builder([Token::NewtypeStruct { name: "Newtype" }, Token::U32(42)]) .build(); assert_ok_eq!(Newtype::deserialize(&mut deserializer), Newtype(42)); } #[test] fn deserialize_newtype_struct_error_invalid_name() { let mut deserializer = Deserializer::builder([ Token::NewtypeStruct { name: "Not Newtype", }, Token::U32(42), ]) .build(); assert_err_eq!( Newtype::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::NewtypeStruct { name: "Not Newtype" }) .into(), &"newtype struct" ) ); } #[test] fn deserialize_newtype_struct_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Newtype::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"newtype struct") ); } #[test] fn deserialize_seq() { let mut deserializer = Deserializer::builder([ Token::Seq { len: Some(3) }, Token::U32(1), Token::U32(2), Token::U32(3), Token::SeqEnd, ]) .build(); assert_ok_eq!(Vec::::deserialize(&mut deserializer), vec![1, 2, 3]); } #[test] fn deserialize_seq_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Vec::::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"a sequence") ); } #[test] fn deserialize_seq_after_ended() { #[derive(Debug, PartialEq)] struct Seq; impl<'de> Deserialize<'de> for Seq { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct SeqVisitor; impl<'de> Visitor<'de> for SeqVisitor { type Value = Seq; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Seq") } fn visit_seq(self, mut seq: A) -> Result where A: de::SeqAccess<'de>, { for _ in 0..2 { if seq.next_element::<()>()?.is_some() { return Err(A::Error::custom( "found element when no element was expected", )); } } Ok(Seq) } } deserializer.deserialize_seq(SeqVisitor) } } let mut deserializer = Deserializer::builder([Token::Seq { len: Some(0) }, Token::SeqEnd]).build(); assert_ok_eq!(Seq::deserialize(&mut deserializer), Seq); } #[test] fn deserialize_tuple() { let mut deserializer = Deserializer::builder([ Token::Tuple { len: 3 }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleEnd, ]) .build(); assert_ok_eq!(<(u32, u32, u32)>::deserialize(&mut deserializer), (1, 2, 3)); } #[test] fn deserialize_tuple_error_len() { let mut deserializer = Deserializer::builder([ Token::Tuple { len: 1 }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleEnd, ]) .build(); assert_err_eq!( <(u32, u32, u32)>::deserialize(&mut deserializer), Error::invalid_length(1, &"a tuple of size 3") ); } #[test] fn deserialize_tuple_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( <(u32, u32, u32)>::deserialize(&mut deserializer), Error::invalid_type( (&mut CanonicalToken::Bool(true)).into(), &"a tuple of size 3" ) ); } #[test] fn deserialize_tuple_error_too_many_elements() { let mut deserializer = Deserializer::builder([ Token::Tuple { len: 3 }, Token::U32(1), Token::U32(2), Token::U32(3), Token::U32(4), Token::TupleEnd, ]) .build(); assert_err_eq!( <(u32, u32, u32)>::deserialize(&mut deserializer), Error::ExpectedTupleEnd ); } #[derive(Debug, PartialEq)] struct TupleStruct(u32, u32, u32); impl<'de> Deserialize<'de> for TupleStruct { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct TupleStructVisitor; impl<'de> Visitor<'de> for TupleStructVisitor { type Value = TupleStruct; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("TupleStruct") } fn visit_seq(self, mut seq: A) -> Result where A: de::SeqAccess<'de>, { Ok(TupleStruct( seq.next_element()? .ok_or(A::Error::invalid_length(0, &self))?, seq.next_element()? .ok_or(A::Error::invalid_length(1, &self))?, seq.next_element()? .ok_or(A::Error::invalid_length(2, &self))?, )) } } deserializer.deserialize_tuple_struct("TupleStruct", 3, TupleStructVisitor) } } #[test] fn deserialize_tuple_struct() { let mut deserializer = Deserializer::builder([ Token::TupleStruct { name: "TupleStruct", len: 3, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleStructEnd, ]) .build(); assert_ok_eq!( TupleStruct::deserialize(&mut deserializer), TupleStruct(1, 2, 3) ); } #[test] fn deserialize_tuple_struct_error_name() { let mut deserializer = Deserializer::builder([ Token::TupleStruct { name: "Not TupleStruct", len: 3, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleStructEnd, ]) .build(); assert_err_eq!( TupleStruct::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::TupleStruct { name: "Not TupleStruct", len: 3 }) .into(), &"TupleStruct" ) ); } #[test] fn deserialize_tuple_struct_error_len() { let mut deserializer = Deserializer::builder([ Token::TupleStruct { name: "TupleStruct", len: 1, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleStructEnd, ]) .build(); assert_err_eq!( TupleStruct::deserialize(&mut deserializer), Error::invalid_length(1, &"TupleStruct") ); } #[test] fn deserialize_tuple_struct_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( TupleStruct::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"TupleStruct") ); } #[test] fn deserialize_map() { let mut deserializer = Deserializer::builder([ Token::Map { len: Some(3) }, Token::Char('a'), Token::U32(1), Token::Char('b'), Token::U32(2), Token::Char('c'), Token::U32(3), Token::MapEnd, ]) .build(); assert_ok_eq!(HashMap::::deserialize(&mut deserializer), { let mut map = HashMap::new(); map.insert('a', 1); map.insert('b', 2); map.insert('c', 3); map }); } #[test] fn deserialize_map_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( HashMap::::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"a map") ); } #[derive(Debug, Deserialize, PartialEq)] struct Struct { foo: u32, bar: bool, } #[test] fn deserialize_struct() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "Struct", len: 2, }, Token::Field("foo"), Token::U32(42), Token::Field("bar"), Token::Bool(false), Token::StructEnd, ]) .build(); assert_ok_eq!( Struct::deserialize(&mut deserializer), Struct { foo: 42, bar: false, } ); } #[test] fn deserialize_struct_string_fields() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "Struct", len: 2, }, Token::Str("foo".to_owned()), Token::U32(42), Token::Str("bar".to_owned()), Token::Bool(false), Token::StructEnd, ]) .build(); assert_ok_eq!( Struct::deserialize(&mut deserializer), Struct { foo: 42, bar: false, } ); } #[test] fn deserialize_struct_byte_fields() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "Struct", len: 2, }, Token::Bytes(b"foo".to_vec()), Token::U32(42), Token::Bytes(b"bar".to_vec()), Token::Bool(false), Token::StructEnd, ]) .build(); assert_ok_eq!( Struct::deserialize(&mut deserializer), Struct { foo: 42, bar: false, } ); } #[test] fn deserialize_struct_error_name() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "Not Struct", len: 2, }, Token::Field("foo"), Token::U32(42), Token::Field("bar"), Token::Bool(false), Token::StructEnd, ]) .build(); assert_err_eq!( Struct::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::Struct { name: "Not Struct", len: 2 }) .into(), &"struct Struct" ) ); } #[test] fn deserialize_struct_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Struct::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"struct Struct") ); } #[derive(Debug, PartialEq)] struct EmptyStruct; impl<'de> Deserialize<'de> for EmptyStruct { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EmptyStructVisitor; impl<'de> Visitor<'de> for EmptyStructVisitor { type Value = EmptyStruct; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EmptyStruct") } fn visit_map(self, _map: A) -> Result where A: de::MapAccess<'de>, { Ok(EmptyStruct) } } deserializer.deserialize_struct("EmptyStruct", &[], EmptyStructVisitor) } } #[test] fn deserialize_struct_error_end_token_assertion_succeeds() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "EmptyStruct", len: 0, }, Token::StructEnd, ]) .build(); assert_ok_eq!(EmptyStruct::deserialize(&mut deserializer), EmptyStruct,); } #[test] fn deserialize_struct_error_end_token_assertion_failed() { let mut deserializer = Deserializer::builder([ Token::Struct { name: "EmptyStruct", len: 0, }, Token::MapEnd, ]) .build(); assert_err_eq!( EmptyStruct::deserialize(&mut deserializer), Error::ExpectedStructEnd, ); } #[test] fn deserialize_struct_after_ended() { #[derive(Debug, PartialEq)] struct Struct; impl<'de> Deserialize<'de> for Struct { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct StructVisitor; impl<'de> Visitor<'de> for StructVisitor { type Value = Struct; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Struct") } fn visit_map(self, mut map: A) -> Result where A: de::MapAccess<'de>, { for _ in 0..2 { if map.next_key::<()>()?.is_some() { return Err(A::Error::custom( "found element when no element was expected", )); } } Ok(Struct) } } deserializer.deserialize_struct("Struct", &[], StructVisitor) } } let mut deserializer = Deserializer::builder([ Token::Struct { name: "Struct", len: 0, }, Token::StructEnd, ]) .build(); assert_ok_eq!(Struct::deserialize(&mut deserializer), Struct); } #[test] fn deserialize_struct_from_seq() { #[derive(Debug, Deserialize, PartialEq)] struct Struct { foo: bool, bar: u32, } let mut deserializer = Deserializer::builder([ Token::Seq { len: Some(2) }, Token::Bool(true), Token::U32(42), Token::SeqEnd, ]) .build(); assert_ok_eq!( Struct::deserialize(&mut deserializer), Struct { foo: true, bar: 42 } ); } #[derive(Debug, Deserialize, PartialEq)] enum Enum { Unit, Newtype(u32), Tuple(u32, u32, u32), Struct { foo: u32, bar: bool }, } #[test] fn deserialize_unit_variant() { let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "Enum", variant_index: 0, variant: "Unit", }]) .build(); assert_ok_eq!(Enum::deserialize(&mut deserializer), Enum::Unit,); } #[test] fn deserialize_unit_variant_error_name() { let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "Not Enum", variant_index: 0, variant: "Unit", }]) .build(); assert_err_eq!( Enum::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::UnitVariant { name: "Not Enum", variant_index: 0, variant: "Unit", }) .into(), &"enum Enum" ) ); } #[test] fn deserialize_newtype_variant() { let mut deserializer = Deserializer::builder([ Token::NewtypeVariant { name: "Enum", variant_index: 1, variant: "Newtype", }, Token::U32(42), ]) .build(); assert_ok_eq!(Enum::deserialize(&mut deserializer), Enum::Newtype(42),); } #[test] fn deserialize_newtype_variant_error_name() { let mut deserializer = Deserializer::builder([ Token::NewtypeVariant { name: "Not Enum", variant_index: 1, variant: "Newtype", }, Token::U32(42), ]) .build(); assert_err_eq!( Enum::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::NewtypeVariant { name: "Not Enum", variant_index: 1, variant: "Newtype", }) .into(), &"enum Enum" ) ); } #[test] fn deserialize_tuple_variant() { let mut deserializer = Deserializer::builder([ Token::TupleVariant { name: "Enum", variant_index: 2, variant: "Tuple", len: 3, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleVariantEnd, ]) .build(); assert_ok_eq!(Enum::deserialize(&mut deserializer), Enum::Tuple(1, 2, 3),); } #[test] fn deserialize_tuple_variant_error_name() { let mut deserializer = Deserializer::builder([ Token::TupleVariant { name: "Not Enum", variant_index: 2, variant: "Tuple", len: 3, }, Token::U32(1), Token::U32(2), Token::U32(3), Token::TupleVariantEnd, ]) .build(); assert_err_eq!( Enum::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::TupleVariant { name: "Not Enum", variant_index: 2, variant: "Tuple", len: 3, }) .into(), &"enum Enum" ) ); } #[test] fn deserialize_struct_variant() { let mut deserializer = Deserializer::builder([ Token::StructVariant { name: "Enum", variant_index: 3, variant: "Struct", len: 2, }, Token::Field("foo"), Token::U32(42), Token::Field("bar"), Token::Bool(false), Token::StructVariantEnd, ]) .build(); assert_ok_eq!( Enum::deserialize(&mut deserializer), Enum::Struct { foo: 42, bar: false, }, ); } #[test] fn deserialize_struct_variant_error_name() { let mut deserializer = Deserializer::builder([ Token::StructVariant { name: "Not Enum", variant_index: 3, variant: "Struct", len: 2, }, Token::Field("foo"), Token::U32(42), Token::Field("bar"), Token::Bool(false), Token::StructVariantEnd, ]) .build(); assert_err_eq!( Enum::deserialize(&mut deserializer), Error::invalid_value( (&mut CanonicalToken::StructVariant { name: "Not Enum", variant_index: 3, variant: "Struct", len: 2, }) .into(), &"enum Enum" ) ); } #[test] fn deserialize_enum_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( Enum::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"enum Enum"), ); } #[derive(Debug, PartialEq)] struct Identifier(String); impl<'de> Deserialize<'de> for Identifier { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct IdentifierVisitor; impl<'de> Visitor<'de> for IdentifierVisitor { type Value = Identifier; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("identifier") } fn visit_str(self, v: &str) -> Result where E: de::Error, { Ok(Identifier(v.to_owned())) } } deserializer.deserialize_identifier(IdentifierVisitor) } } #[test] fn deserialize_identifier_str() { let mut deserializer = Deserializer::builder([Token::Str("foo".to_owned())]).build(); assert_ok_eq!( Identifier::deserialize(&mut deserializer), Identifier("foo".to_owned()) ); } #[test] fn deserialize_identifier_field() { let mut deserializer = Deserializer::builder([Token::Field("foo")]).build(); assert_ok_eq!( Identifier::deserialize(&mut deserializer), Identifier("foo".to_owned()) ); } #[test] fn deserialize_identifier_error_token() { let mut deserializer = Deserializer::builder([Token::Bool(false)]).build(); assert_err_eq!( Identifier::deserialize(&mut deserializer), Error::invalid_type((&mut CanonicalToken::Bool(false)).into(), &"identifier") ); } #[test] fn deserialize_ignored_any() { let mut deserializer = Deserializer::builder([Token::Bool(true)]) .self_describing(true) .build(); assert_ok!(IgnoredAny::deserialize(&mut deserializer)); } #[test] fn deserialize_ignored_any_default_not_self_describing() { let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); assert_err_eq!( IgnoredAny::deserialize(&mut deserializer), Error::NotSelfDescribing ); } #[test] fn deserialize_ignored_any_not_self_describing() { let mut deserializer = Deserializer::builder([Token::Bool(true)]) .self_describing(false) .build(); assert_err_eq!( IgnoredAny::deserialize(&mut deserializer), Error::NotSelfDescribing ); } #[test] fn deserialize_skips_skipped_field() { let mut deserializer = Deserializer::builder([Token::SkippedField("foo"), Token::Bool(true)]).build(); assert_ok_eq!(bool::deserialize(&mut deserializer), true); } #[test] fn deserialize_from_unordered_tokens() { let mut deserializer = Deserializer::builder([Token::Unordered(&[&[Token::Bool(true)]])]).build(); assert_ok_eq!(bool::deserialize(&mut deserializer), true); } #[test] fn is_human_readable_default() { let mut deserializer = Deserializer::builder([]).build(); assert!((&mut deserializer).is_human_readable()); } #[test] fn is_human_readable_true() { let mut deserializer = Deserializer::builder([]).is_human_readable(true).build(); assert!((&mut deserializer).is_human_readable()); } #[test] fn is_human_readable_false() { let mut deserializer = Deserializer::builder([]).is_human_readable(false).build(); assert!(!(&mut deserializer).is_human_readable()); } #[derive(Debug, PartialEq)] enum EnumVariant { Unit, Newtype, Tuple, Struct, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_str(self, v: &str) -> Result where E: de::Error, { match v { "Unit" => Ok(EnumVariant::Unit), "Newtype" => Ok(EnumVariant::Newtype), "Tuple" => Ok(EnumVariant::Tuple), "Struct" => Ok(EnumVariant::Struct), _ => Err(E::invalid_value(Unexpected::Str(v), &self)), } } } deserializer.deserialize_any(EnumVariantVisitor) } } #[test] fn enum_deserializer_deserialize_any_unit() { let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Unit", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Unit ); } #[test] fn enum_deserializer_deserialize_any_newtype() { let mut deserializer = Deserializer::builder([Token::NewtypeVariant { name: "EnumVariant", variant_index: 1, variant: "Newtype", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Newtype ); } #[test] fn enum_deserializer_deserialize_any_tuple() { let mut deserializer = Deserializer::builder([ Token::TupleVariant { name: "EnumVariant", variant_index: 2, variant: "Tuple", len: 0, }, Token::TupleVariantEnd, ]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Tuple ); } #[test] fn enum_deserializer_deserialize_any_struct() { let mut deserializer = Deserializer::builder([ Token::StructVariant { name: "EnumVariant", variant_index: 3, variant: "Struct", len: 0, }, Token::StructVariantEnd, ]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Struct ); } #[test] #[should_panic(expected = "internal error: entered unreachable code")] fn enum_deserializer_deserialize_any_invalid_token() { let mut deserializer = Deserializer::builder([Token::Bool(false)]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; #[allow(unused_must_use)] { // This should panic, so it doesn't matter what value it returns. EnumVariant::deserialize(enum_deserializer); } } #[test] fn enum_deserializer_deserialize_bool() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_bool(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_i8() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_i8(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_i16() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_i16(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_i32() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_i32(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_i64() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_i64(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_i128() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_i128(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_u8() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_u8(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_u16() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_u16(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[derive(Debug, PartialEq)] enum U32EnumVariant { Unit, Newtype, Tuple, Struct, } impl<'de> Deserialize<'de> for U32EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct U32EnumVariantVisitor; impl<'de> Visitor<'de> for U32EnumVariantVisitor { type Value = U32EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("U32EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { match v { 0 => Ok(U32EnumVariant::Unit), 1 => Ok(U32EnumVariant::Newtype), 2 => Ok(U32EnumVariant::Tuple), 3 => Ok(U32EnumVariant::Struct), _ => Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)), } } } deserializer.deserialize_u32(U32EnumVariantVisitor) } } #[test] fn enum_deserializer_deserialize_u32_unit() { let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Unit", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( U32EnumVariant::deserialize(enum_deserializer), U32EnumVariant::Unit, ); } #[test] fn enum_deserializer_deserialize_u32_newtype() { let mut deserializer = Deserializer::builder([Token::NewtypeVariant { name: "EnumVariant", variant_index: 1, variant: "Newtype", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( U32EnumVariant::deserialize(enum_deserializer), U32EnumVariant::Newtype, ); } #[test] fn enum_deserializer_deserialize_u32_tuple() { let mut deserializer = Deserializer::builder([ Token::TupleVariant { name: "EnumVariant", variant_index: 2, variant: "Tuple", len: 0, }, Token::TupleVariantEnd, ]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( U32EnumVariant::deserialize(enum_deserializer), U32EnumVariant::Tuple, ); } #[test] fn enum_deserializer_deserialize_u32_struct() { let mut deserializer = Deserializer::builder([ Token::StructVariant { name: "EnumVariant", variant_index: 3, variant: "Struct", len: 0, }, Token::StructVariantEnd, ]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( U32EnumVariant::deserialize(enum_deserializer), U32EnumVariant::Struct, ); } #[test] #[should_panic(expected = "internal error: entered unreachable code")] fn enum_deserializer_deserialize_u32_invalid_token() { let mut deserializer = Deserializer::builder([Token::Bool(false)]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; #[allow(unused_must_use)] { // This should panic, so it doesn't matter what value it returns. U32EnumVariant::deserialize(enum_deserializer); } } #[test] fn enum_deserializer_deserialize_u64() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_u64(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_u128() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_u32(self, v: u32) -> Result where E: de::Error, { if v == 0 { Ok(EnumVariant::Foo) } else { Err(E::invalid_value(Unexpected::Unsigned(v.into()), &self)) } } } deserializer.deserialize_u128(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_f32() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_f32(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_f64() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_f64(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_char() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_char(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_str() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_str(self, v: &str) -> Result where E: de::Error, { match v { "Foo" => Ok(EnumVariant::Foo), _ => Err(E::invalid_value(Unexpected::Str(v), &self)), } } } deserializer.deserialize_str(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_string() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_str(self, v: &str) -> Result where E: de::Error, { match v { "Foo" => Ok(EnumVariant::Foo), _ => Err(E::invalid_value(Unexpected::Str(v), &self)), } } } deserializer.deserialize_string(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_bytes() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_bytes(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_byte_buf() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_byte_buf(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_option() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_option(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_unit() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_unit(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_unit_struct() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_unit_struct("EnumVariant", EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_newtype_struct() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_newtype_struct("EnumVariant", EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_seq() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_seq(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_tuple() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_tuple(0, EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_tuple_struct() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_tuple_struct("EnumVariant", 0, EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_map() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_map(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_struct() { #[derive(Debug)] enum EnumVariant {} impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } } deserializer.deserialize_struct("EnumVariant", &[], EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_err_eq!( EnumVariant::deserialize(enum_deserializer), Error::UnsupportedEnumDeserializerMethod ); } #[test] fn enum_deserializer_deserialize_enum() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_str(self, v: &str) -> Result where E: de::Error, { match v { "Foo" => Ok(EnumVariant::Foo), _ => Err(E::invalid_value(Unexpected::Str(v), &self)), } } } deserializer.deserialize_enum("EnumVariant", &[], EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_deserialize_ignored_any() { #[derive(Debug, PartialEq)] enum EnumVariant { Foo, } impl<'de> Deserialize<'de> for EnumVariant { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct EnumVariantVisitor; impl<'de> Visitor<'de> for EnumVariantVisitor { type Value = EnumVariant; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("EnumVariant") } fn visit_str(self, v: &str) -> Result where E: de::Error, { match v { "Foo" => Ok(EnumVariant::Foo), _ => Err(E::invalid_value(Unexpected::Str(v), &self)), } } } deserializer.deserialize_ignored_any(EnumVariantVisitor) } } let mut deserializer = Deserializer::builder([Token::UnitVariant { name: "EnumVariant", variant_index: 0, variant: "Foo", }]) .self_describing(true) .build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert_ok_eq!( EnumVariant::deserialize(enum_deserializer), EnumVariant::Foo, ); } #[test] fn enum_deserializer_is_human_readable_default() { let mut deserializer = Deserializer::builder([]).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert!(enum_deserializer.is_human_readable()) } #[test] fn enum_deserializer_is_human_readable_true() { let mut deserializer = Deserializer::builder([]).is_human_readable(true).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert!(enum_deserializer.is_human_readable()) } #[test] fn enum_deserializer_is_human_readable_false() { let mut deserializer = Deserializer::builder([]).is_human_readable(false).build(); let enum_deserializer = EnumDeserializer { deserializer: &mut deserializer, }; assert!(!enum_deserializer.is_human_readable()) } #[test] fn display_error_end_of_tokens() { assert_eq!(format!("{}", Error::EndOfTokens), "end of tokens"); } #[test] fn display_error_expected_seq_end() { assert_eq!( format!("{}", Error::ExpectedSeqEnd), "expected token SeqEnd" ); } #[test] fn display_error_expected_tuple_end() { assert_eq!( format!("{}", Error::ExpectedTupleEnd), "expected token TupleEnd" ); } #[test] fn display_error_expected_tuple_struct_end() { assert_eq!( format!("{}", Error::ExpectedTupleStructEnd), "expected token TupleStructEnd" ); } #[test] fn display_error_expected_tuple_variant_end() { assert_eq!( format!("{}", Error::ExpectedTupleVariantEnd), "expected token TupleVariantEnd" ); } #[test] fn display_error_expected_map_end() { assert_eq!( format!("{}", Error::ExpectedMapEnd), "expected token MapEnd" ); } #[test] fn display_error_expected_struct_end() { assert_eq!( format!("{}", Error::ExpectedStructEnd), "expected token StructEnd" ); } #[test] fn display_error_expected_struct_variant_end() { assert_eq!( format!("{}", Error::ExpectedStructVariantEnd), "expected token StructVariantEnd" ); } #[test] fn display_error_unsupported_enum_deserializer_method() { assert_eq!( format!("{}", Error::UnsupportedEnumDeserializerMethod), "use of unsupported enum deserializer method" ); } #[test] fn display_error_not_self_describing() { assert_eq!(format!("{}", Error::NotSelfDescribing), "attempted to deserialize as self-describing when deserializer is not set as self-describing"); } #[test] fn display_error_custom() { assert_eq!(format!("{}", Error::custom("foo")), "foo"); } #[test] fn display_error_invalid_type() { assert_eq!( format!( "{}", Error::invalid_type((&mut CanonicalToken::Bool(true)).into(), &"foo") ), "invalid type: expected foo, found boolean `true`" ); } #[test] fn display_error_invalid_value() { assert_eq!( format!( "{}", Error::invalid_value((&mut CanonicalToken::Bool(true)).into(), &"foo") ), "invalid value: expected foo, found boolean `true`" ); } #[test] fn display_error_invalid_length() { assert_eq!( format!("{}", Error::invalid_length(42, &"foo")), "invalid length 42, expected foo" ); } #[test] fn display_error_unknown_variant() { assert_eq!( format!("{}", Error::unknown_variant("foo", &["bar", "baz"])), "unknown variant foo, expected one of [\"bar\", \"baz\"]" ); } #[test] fn display_error_unknown_field() { assert_eq!( format!("{}", Error::unknown_field("foo", &["bar", "baz"])), "unknown field foo, expected one of [\"bar\", \"baz\"]" ); } #[test] fn display_error_missing_field() { assert_eq!( format!("{}", Error::missing_field("foo")), "missing field foo" ); } #[test] fn display_error_duplicate_field() { assert_eq!( format!("{}", Error::duplicate_field("foo")), "duplicate field foo" ); } #[test] fn error_expected_end_token_seq() { assert_eq!( Error::expected_end_token(crate::de::EndToken::Seq), Error::ExpectedSeqEnd ); } #[test] fn error_expected_end_token_tuple() { assert_eq!( Error::expected_end_token(crate::de::EndToken::Tuple), Error::ExpectedTupleEnd ); } #[test] fn error_expected_end_token_tuple_struct() { assert_eq!( Error::expected_end_token(crate::de::EndToken::TupleStruct), Error::ExpectedTupleStructEnd ); } #[test] fn error_expected_end_token_tuple_variant() { assert_eq!( Error::expected_end_token(crate::de::EndToken::TupleVariant), Error::ExpectedTupleVariantEnd ); } #[test] fn error_expected_end_token_map() { assert_eq!( Error::expected_end_token(crate::de::EndToken::Map), Error::ExpectedMapEnd ); } #[test] fn error_expected_end_token_struct() { assert_eq!( Error::expected_end_token(crate::de::EndToken::Struct), Error::ExpectedStructEnd ); } #[test] fn error_expected_end_token_struct_variant() { assert_eq!( Error::expected_end_token(crate::de::EndToken::StructVariant), Error::ExpectedStructVariantEnd ); } } serde_assert-0.8.0/src/lib.rs000064400000000000000000000072720072674642500142570ustar 00000000000000//! Testing library for [`serde`] [`Serialize`] and [`Deserialize`] implementations. //! //! This library provides a [`Serializer`] and [`Deserializer`] to be used in writing unit tests to //! assert the behavior of manual [`Serialize`] and [`Deserialize`] implementations, respectively. //! The implementation behavior can be verified by using a sequence of [`Token`]s representing an //! arbitrary serialized state. //! //! # Testing Serialization //! The [`Serializer`] returns a sequence of [`Token`]s representing the serialization of a value. //! The returned `Token`s can be checked to be equal to an expected value. Since //! [`Serialize::serialize()`] returns a `Result`, it is recommended to use the //! [`claims`] crate to check that the returned value is both `Ok` and equal to the expected //! sequence of `Token`s. //! //! ``` //! use claims::assert_ok_eq; //! use serde::Serialize; //! use serde_assert::{ //! Serializer, //! Token, //! }; //! //! let serializer = Serializer::builder().build(); //! //! assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); //! ``` //! //! ## Arbitrary Ordering //! In cases where the ordering of [`Token`]s does not matter, such as when serializing a //! [`HashSet`], [`Token::Unordered`] can be used to specify that tokens can be in an arbitrary //! order. //! //! ``` //! use claims::assert_ok_eq; //! use serde::Serialize; //! use serde_assert::{ //! Serializer, //! Token, //! }; //! use std::collections::HashSet; //! //! let serializer = Serializer::builder().build(); //! //! let mut set = HashSet::::new(); //! set.insert(1); //! set.insert(2); //! set.insert(3); //! //! assert_ok_eq!( //! set.serialize(&serializer), //! [ //! Token::Seq { len: Some(3) }, //! Token::Unordered(&[&[Token::U32(1)], &[Token::U32(2)], &[Token::U32(3)],]), //! Token::SeqEnd //! ] //! ); //! ``` //! //! # Testing Deserialization //! A [`Deserializer`] is constructed by providing a sequence of [`Token`]s to be deserialized into //! a value. During testing, the [`claims`] crate can be used to assert that deserialization //! succeeds and returns the expected value. //! //! ``` //! use claims::assert_ok_eq; //! use serde::Deserialize; //! use serde_assert::{ //! Deserializer, //! Token, //! }; //! //! let mut deserializer = Deserializer::builder([Token::Bool(true)]).build(); //! //! assert_ok_eq!(bool::deserialize(&mut deserializer), true); //! ``` //! //! # Testing Roundtrip //! To assert that a value remains the same when serialized and then deserialized again, the output //! of the [`Serializer`] can be used as input to the [`Deserializer`]. //! //! ``` //! use claims::{ //! assert_ok, //! assert_ok_eq, //! }; //! use serde::{ //! Deserialize, //! Serialize, //! }; //! use serde_assert::{ //! Deserializer, //! Serializer, //! }; //! //! let value = true; //! //! let serializer = Serializer::builder().build(); //! let mut deserializer = Deserializer::builder(assert_ok!(value.serialize(&serializer))).build(); //! //! assert_ok_eq!(bool::deserialize(&mut deserializer), value); //! ``` //! //! [`claims`]: https://docs.rs/claims/ //! [`Deserialize`]: serde::Deserialize //! [`HashSet`]: std::collections::HashSet //! [`Serialize`]: serde::Serialize //! [`Serialize::serialize()`]: serde::Serialize::serialize() #![no_std] #![warn(clippy::pedantic)] extern crate alloc; #[cfg(any(test, doc))] extern crate std; pub mod de; pub mod ser; pub mod token; #[doc(inline)] pub use de::Deserializer; #[doc(inline)] pub use ser::Serializer; #[doc(inline)] pub use token::Token; serde_assert-0.8.0/src/ser.rs000064400000000000000000001032700072674642500142750ustar 00000000000000//! Testing serialization implementations. //! //! This module provides a [`Serializer`] struct for testing serialization. Construction of this //! struct uses the builder pattern through the [`Builder`] struct, allowing configuration of the //! behavior of the `Serializer`. //! //! # Example //! //! ``` rust //! use claims::assert_ok_eq; //! use serde::Serialize; //! use serde_assert::{ //! Serializer, //! Token, //! }; //! //! let serializer = Serializer::builder().build(); //! //! assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); //! ``` use crate::token::{ CanonicalToken, Tokens, }; use alloc::{ borrow::ToOwned, string::{ String, ToString, }, vec, }; use core::{ fmt, fmt::Display, }; use serde::{ ser, ser::{ SerializeMap, SerializeSeq, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, }, Serialize, }; /// Configuration for serializing `struct`s. /// /// Can be passed to a [`Builder`] to determine how `struct`s should be serialized by the /// [`Serializer`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// ser::SerializeStructAs, /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// struct Struct { /// foo: bool, /// bar: u32, /// } /// /// let some_struct = Struct { /// foo: false, /// bar: 42, /// }; /// let serializer = Serializer::builder() /// .serialize_struct_as(SerializeStructAs::Seq) /// .build(); /// /// assert_ok_eq!( /// some_struct.serialize(&serializer), /// [ /// Token::Seq { len: Some(2) }, /// Token::Bool(false), /// Token::U32(42), /// Token::SeqEnd, /// ] /// ); /// ``` #[derive(Clone, Copy, Debug)] pub enum SerializeStructAs { /// Serialize structs using [`Token::Struct`]. /// /// [`Token::Struct`]: crate::Token::Struct Struct, /// Serialize structs using [`Token::Seq`]. /// /// This type of serialization is often done by compact serialization formats. Using this /// setting simulates those serializers. /// /// [`Token::Seq`]: crate::Token::Seq Seq, } /// Serializer for testing [`Serialize`] implementations. /// /// This serializer outputs [`Tokens`] representing the serialized value. The `Tokens` can be /// compared against an expected sequence of [`Token`]s to ensure the serialization is correct. /// /// # Configuration /// The following options can be configured on the [`Builder`]: /// /// - [`is_human_readable()`]: Determines whether the serializer will serialize values in a readable /// format or a compact format. Useful for complicated structs wishing to provide different /// outputs depending on the readability of the serialization type. /// - [`serialize_struct_as()`]: Specifies how the serializer should serialize structs. Compact /// formats often serialize structs as sequences. By enabling this setting, tokens can be produced /// in this format, and can then be deserialized to ensure structs deserialized as sequences are /// deserialized correctly. /// /// # Example /// /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); /// ``` /// /// [`is_human_readable()`]: Builder::is_human_readable() /// [`serialize_struct_as()`]: Builder::serialize_struct_as() /// [`Serialize`]: serde::Serialize /// [`Token`]: crate::Token #[derive(Debug)] pub struct Serializer { is_human_readable: bool, serialize_struct_as: SerializeStructAs, } impl<'a> ser::Serializer for &'a Serializer { type Ok = Tokens; type Error = Error; type SerializeSeq = CompoundSerializer<'a>; type SerializeTuple = CompoundSerializer<'a>; type SerializeTupleStruct = CompoundSerializer<'a>; type SerializeTupleVariant = CompoundSerializer<'a>; type SerializeMap = CompoundSerializer<'a>; type SerializeStruct = SerializeStruct<'a>; type SerializeStructVariant = CompoundSerializer<'a>; fn serialize_bool(self, v: bool) -> Result { Ok(Tokens(vec![CanonicalToken::Bool(v)])) } fn serialize_i8(self, v: i8) -> Result { Ok(Tokens(vec![CanonicalToken::I8(v)])) } fn serialize_i16(self, v: i16) -> Result { Ok(Tokens(vec![CanonicalToken::I16(v)])) } fn serialize_i32(self, v: i32) -> Result { Ok(Tokens(vec![CanonicalToken::I32(v)])) } fn serialize_i64(self, v: i64) -> Result { Ok(Tokens(vec![CanonicalToken::I64(v)])) } fn serialize_i128(self, v: i128) -> Result { Ok(Tokens(vec![CanonicalToken::I128(v)])) } fn serialize_u8(self, v: u8) -> Result { Ok(Tokens(vec![CanonicalToken::U8(v)])) } fn serialize_u16(self, v: u16) -> Result { Ok(Tokens(vec![CanonicalToken::U16(v)])) } fn serialize_u32(self, v: u32) -> Result { Ok(Tokens(vec![CanonicalToken::U32(v)])) } fn serialize_u64(self, v: u64) -> Result { Ok(Tokens(vec![CanonicalToken::U64(v)])) } fn serialize_u128(self, v: u128) -> Result { Ok(Tokens(vec![CanonicalToken::U128(v)])) } fn serialize_f32(self, v: f32) -> Result { Ok(Tokens(vec![CanonicalToken::F32(v)])) } fn serialize_f64(self, v: f64) -> Result { Ok(Tokens(vec![CanonicalToken::F64(v)])) } fn serialize_char(self, v: char) -> Result { Ok(Tokens(vec![CanonicalToken::Char(v)])) } fn serialize_str(self, v: &str) -> Result { Ok(Tokens(vec![CanonicalToken::Str(v.to_owned())])) } fn serialize_bytes(self, v: &[u8]) -> Result { Ok(Tokens(vec![CanonicalToken::Bytes(v.to_owned())])) } fn serialize_none(self) -> Result { Ok(Tokens(vec![CanonicalToken::None])) } fn serialize_some(self, value: &T) -> Result where T: Serialize + ?Sized, { let mut tokens = Tokens(vec![CanonicalToken::Some]); tokens.0.extend(value.serialize(self)?.0); Ok(tokens) } fn serialize_unit(self) -> Result { Ok(Tokens(vec![CanonicalToken::Unit])) } fn serialize_unit_struct(self, name: &'static str) -> Result { Ok(Tokens(vec![CanonicalToken::UnitStruct { name }])) } fn serialize_unit_variant( self, name: &'static str, variant_index: u32, variant: &'static str, ) -> Result { Ok(Tokens(vec![CanonicalToken::UnitVariant { name, variant_index, variant, }])) } fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result where T: Serialize + ?Sized, { let mut tokens = Tokens(vec![CanonicalToken::NewtypeStruct { name }]); tokens.0.extend(value.serialize(self)?.0); Ok(tokens) } fn serialize_newtype_variant( self, name: &'static str, variant_index: u32, variant: &'static str, value: &T, ) -> Result where T: Serialize + ?Sized, { let mut tokens = Tokens(vec![CanonicalToken::NewtypeVariant { name, variant_index, variant, }]); tokens.0.extend(value.serialize(self)?.0); Ok(tokens) } fn serialize_seq(self, len: Option) -> Result, Error> { Ok(CompoundSerializer { tokens: Tokens(vec![CanonicalToken::Seq { len }]), serializer: self, }) } fn serialize_tuple(self, len: usize) -> Result, Error> { Ok(CompoundSerializer { tokens: Tokens(vec![CanonicalToken::Tuple { len }]), serializer: self, }) } fn serialize_tuple_struct( self, name: &'static str, len: usize, ) -> Result, Error> { Ok(CompoundSerializer { tokens: Tokens(vec![CanonicalToken::TupleStruct { name, len }]), serializer: self, }) } fn serialize_tuple_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result, Error> { Ok(CompoundSerializer { tokens: Tokens(vec![CanonicalToken::TupleVariant { name, variant_index, variant, len, }]), serializer: self, }) } fn serialize_map(self, len: Option) -> Result, Error> { Ok(CompoundSerializer { tokens: Tokens(vec![CanonicalToken::Map { len }]), serializer: self, }) } fn serialize_struct( self, name: &'static str, len: usize, ) -> Result, Error> { match self.serialize_struct_as { SerializeStructAs::Struct => Ok(SerializeStruct { tokens: Tokens(vec![CanonicalToken::Struct { name, len }]), serializer: self, serialize_struct_as: self.serialize_struct_as, }), SerializeStructAs::Seq => Ok(SerializeStruct { tokens: Tokens(vec![CanonicalToken::Seq { len: Some(len) }]), serializer: self, serialize_struct_as: self.serialize_struct_as, }), } } fn serialize_struct_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result, Error> { Ok(CompoundSerializer { tokens: Tokens(vec![CanonicalToken::StructVariant { name, variant_index, variant, len, }]), serializer: self, }) } fn collect_str(self, value: &T) -> Result where T: Display + ?Sized, { Ok(Tokens(vec![CanonicalToken::Str(value.to_string())])) } fn is_human_readable(&self) -> bool { self.is_human_readable } } impl Serializer { /// Returns a [`Builder`] for a [`Serializer`]. /// /// # Example /// ``` rust /// use serde_assert::Serializer; /// /// let serializer = Serializer::builder().is_human_readable(false).build(); /// ``` #[must_use] pub fn builder() -> Builder { Builder::default() } } /// A builder for a [`Serializer`]. /// /// Construction of a `Serializer` follows the builder pattern. Configuration options can be set on /// the `Builder`, and then the actual `Serializer` is constructed by calling [`build()`]. /// /// # Example /// ``` rust /// use serde_assert::Serializer; /// /// let serializer = Serializer::builder().is_human_readable(false).build(); /// ``` /// /// [`build()`]: Builder::build() #[derive(Debug)] pub struct Builder { is_human_readable: bool, serialize_struct_as: SerializeStructAs, } impl Builder { /// Determines whether the serializer will serialize values in a readable format or a compact /// format. /// /// Useful for complicated structs wishing to provide different outputs depending on /// the readability of the serialization type. /// /// If not set, the default value is `true`. /// /// # Example /// ``` rust /// use serde_assert::Serializer; /// /// let serializer = Serializer::builder().is_human_readable(false).build(); /// ``` pub fn is_human_readable(&mut self, is_human_readable: bool) -> &mut Self { self.is_human_readable = is_human_readable; self } /// Specifies how the serializer should serialize structs. /// /// Compact formats often serialize structs as sequences. By enabling this setting, tokens can /// be produced in this format, and can then be deserialized to ensure structs deserialized as /// sequences are deserialized correctly. /// /// If not set, the default value is [`SerializeStructAs::Struct`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// ser::SerializeStructAs, /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// struct Struct { /// foo: bool, /// bar: u32, /// } /// /// let some_struct = Struct { /// foo: false, /// bar: 42, /// }; /// let serializer = Serializer::builder() /// .serialize_struct_as(SerializeStructAs::Seq) /// .build(); /// /// assert_ok_eq!( /// some_struct.serialize(&serializer), /// [ /// Token::Seq { len: Some(2) }, /// Token::Bool(false), /// Token::U32(42), /// Token::SeqEnd, /// ] /// ); /// ``` pub fn serialize_struct_as(&mut self, serialize_struct_as: SerializeStructAs) -> &mut Self { self.serialize_struct_as = serialize_struct_as; self } /// Build a new [`Serializer`] using this `Builder`. /// /// Constructs a new `Serializer` using the configuration options set on this `Builder`. /// /// # Example /// ``` rust /// use serde_assert::Serializer; /// /// let serializer = Serializer::builder().is_human_readable(false).build(); /// ``` pub fn build(&mut self) -> Serializer { Serializer { is_human_readable: self.is_human_readable, serialize_struct_as: self.serialize_struct_as, } } } impl Default for Builder { fn default() -> Self { Self { is_human_readable: true, serialize_struct_as: SerializeStructAs::Struct, } } } /// Serializer for serializing compound types. /// /// This type implements [`SerializeSeq`], [`SerializeTuple`], [`SerializeTupleStruct`], /// [`SerializeTupleVariant`], [`SerializeMap`], [`SerializeStruct`], and /// [`SerializeStructVariant`], and is used by [`Serializer`] for serialization of each of those /// compound data types. /// /// Users normally will not need to interact with this type directly. It is primarily used by /// [`Serialize`] implementations through the various traits it implements. #[derive(Debug)] pub struct CompoundSerializer<'a> { tokens: Tokens, serializer: &'a Serializer, } impl SerializeSeq for CompoundSerializer<'_> { type Ok = Tokens; type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(CanonicalToken::SeqEnd); Ok(self.tokens) } } impl SerializeTuple for CompoundSerializer<'_> { type Ok = Tokens; type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(CanonicalToken::TupleEnd); Ok(self.tokens) } } impl SerializeTupleStruct for CompoundSerializer<'_> { type Ok = Tokens; type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(CanonicalToken::TupleStructEnd); Ok(self.tokens) } } impl SerializeTupleVariant for CompoundSerializer<'_> { type Ok = Tokens; type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(CanonicalToken::TupleVariantEnd); Ok(self.tokens) } } impl SerializeMap for CompoundSerializer<'_> { type Ok = Tokens; type Error = Error; fn serialize_key(&mut self, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn serialize_value(&mut self, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(CanonicalToken::MapEnd); Ok(self.tokens) } } impl SerializeStructVariant for CompoundSerializer<'_> { type Ok = Tokens; type Error = Error; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { self.tokens.0.push(CanonicalToken::Field(key)); self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn skip_field(&mut self, key: &'static str) -> Result<(), Error> { self.tokens.0.push(CanonicalToken::SkippedField(key)); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(CanonicalToken::StructVariantEnd); Ok(self.tokens) } } /// Serializer for serializing `struct`s. /// /// Users normally will not need to interact with this type directly. It is primarily used by /// [`Serialize`] implementations through the [`serde::ser::SerializeStruct`] trait it implements. pub struct SerializeStruct<'a> { tokens: Tokens, serializer: &'a Serializer, serialize_struct_as: SerializeStructAs, } impl ser::SerializeStruct for SerializeStruct<'_> { type Ok = Tokens; type Error = Error; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> where T: Serialize + ?Sized, { if matches!(self.serialize_struct_as, SerializeStructAs::Struct) { self.tokens.0.push(CanonicalToken::Field(key)); } self.tokens.0.extend(value.serialize(self.serializer)?.0); Ok(()) } fn skip_field(&mut self, key: &'static str) -> Result<(), Error> { self.tokens.0.push(CanonicalToken::SkippedField(key)); Ok(()) } fn end(mut self) -> Result { self.tokens.0.push(match self.serialize_struct_as { SerializeStructAs::Struct => CanonicalToken::StructEnd, SerializeStructAs::Seq => CanonicalToken::SeqEnd, }); Ok(self.tokens) } } /// An error encountered during serialization. /// /// # Example /// ```rust /// use serde::ser::Error as _; /// use serde_assert::ser::Error; /// /// assert_eq!(format!("{}", Error::custom("foo")), "foo"); /// ``` #[derive(Debug, Eq, PartialEq)] pub struct Error(pub String); impl Display for Error { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(formatter) } } impl ser::StdError for Error {} impl ser::Error for Error { fn custom(msg: T) -> Self where T: Display, { Self(msg.to_string()) } } #[cfg(test)] mod tests { use super::{ Error, SerializeStructAs, Serializer, }; use crate::Token; use alloc::{ borrow::ToOwned, format, string::String, vec, }; use claims::assert_ok_eq; use serde::ser::{ Error as _, Serialize, Serializer as _, }; use serde_bytes::Bytes; use serde_derive::Serialize; use std::collections::{ HashMap, HashSet, }; #[test] fn serialize_bool() { let serializer = Serializer::builder().build(); assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); } #[test] fn serialize_i8() { let serializer = Serializer::builder().build(); assert_ok_eq!(42i8.serialize(&serializer), [Token::I8(42)]); } #[test] fn serialize_i16() { let serializer = Serializer::builder().build(); assert_ok_eq!(42i16.serialize(&serializer), [Token::I16(42)]); } #[test] fn serialize_i32() { let serializer = Serializer::builder().build(); assert_ok_eq!(42i32.serialize(&serializer), [Token::I32(42)]); } #[test] fn serialize_i64() { let serializer = Serializer::builder().build(); assert_ok_eq!(42i64.serialize(&serializer), [Token::I64(42)]); } #[test] fn serialize_i128() { let serializer = Serializer::builder().build(); assert_ok_eq!(42i128.serialize(&serializer), [Token::I128(42)]); } #[test] fn serialize_u8() { let serializer = Serializer::builder().build(); assert_ok_eq!(42u8.serialize(&serializer), [Token::U8(42)]); } #[test] fn serialize_u16() { let serializer = Serializer::builder().build(); assert_ok_eq!(42u16.serialize(&serializer), [Token::U16(42)]); } #[test] fn serialize_u32() { let serializer = Serializer::builder().build(); assert_ok_eq!(42u32.serialize(&serializer), [Token::U32(42)]); } #[test] fn serialize_u64() { let serializer = Serializer::builder().build(); assert_ok_eq!(42u64.serialize(&serializer), [Token::U64(42)]); } #[test] fn serialize_u128() { let serializer = Serializer::builder().build(); assert_ok_eq!(42u128.serialize(&serializer), [Token::U128(42)]); } #[test] fn serialize_f32() { let serializer = Serializer::builder().build(); assert_ok_eq!(42f32.serialize(&serializer), [Token::F32(42.)]); } #[test] fn serialize_f64() { let serializer = Serializer::builder().build(); assert_ok_eq!(42f64.serialize(&serializer), [Token::F64(42.)]); } #[test] fn serialize_char() { let serializer = Serializer::builder().build(); assert_ok_eq!('a'.serialize(&serializer), [Token::Char('a')]); } #[test] fn serialize_str() { let serializer = Serializer::builder().build(); assert_ok_eq!("a".serialize(&serializer), [Token::Str("a".to_owned())]); } #[test] fn serialize_bytes() { let serializer = Serializer::builder().build(); assert_ok_eq!( Bytes::new(b"a").serialize(&serializer), [Token::Bytes(b"a".to_vec())] ); } #[test] fn serialize_none() { let serializer = Serializer::builder().build(); assert_ok_eq!(Option::<()>::None.serialize(&serializer), [Token::None]); } #[test] fn serialize_some() { let serializer = Serializer::builder().build(); assert_ok_eq!( Some(true).serialize(&serializer), [Token::Some, Token::Bool(true)] ); } #[test] fn serialize_unit() { let serializer = Serializer::builder().build(); assert_ok_eq!(().serialize(&serializer), [Token::Unit]); } #[test] fn serialize_unit_struct() { #[derive(Serialize)] struct Unit; let serializer = Serializer::builder().build(); assert_ok_eq!( Unit.serialize(&serializer), [Token::UnitStruct { name: "Unit" }] ); } #[test] fn serialize_unit_variant() { #[derive(Serialize)] enum Unit { Variant, } let serializer = Serializer::builder().build(); assert_ok_eq!( Unit::Variant.serialize(&serializer), [Token::UnitVariant { name: "Unit", variant_index: 0, variant: "Variant" }] ); } #[test] fn serialize_newtype_struct() { #[derive(Serialize)] struct Newtype(bool); let serializer = Serializer::builder().build(); assert_ok_eq!( Newtype(false).serialize(&serializer), [Token::NewtypeStruct { name: "Newtype" }, Token::Bool(false)] ); } #[test] fn serialize_newtype_variant() { #[derive(Serialize)] enum Newtype { Variant(bool), } let serializer = Serializer::builder().build(); assert_ok_eq!( Newtype::Variant(false).serialize(&serializer), [ Token::NewtypeVariant { name: "Newtype", variant_index: 0, variant: "Variant" }, Token::Bool(false) ] ); } #[test] fn serialize_seq() { let serializer = Serializer::builder().build(); assert_ok_eq!( vec![1i8, 2i8, 3i8].serialize(&serializer), [ Token::Seq { len: Some(3) }, Token::I8(1), Token::I8(2), Token::I8(3), Token::SeqEnd ], ); } #[test] fn serialize_seq_unordered() { let serializer = Serializer::builder().build(); let mut set = HashSet::new(); set.insert('a'); set.insert('b'); set.insert('c'); assert_ok_eq!( set.serialize(&serializer), [ Token::Seq { len: Some(3) }, Token::Unordered(&[ &[Token::Char('a')], &[Token::Char('b')], &[Token::Char('c')], ]), Token::SeqEnd, ] ); } #[test] fn serialize_tuple() { let serializer = Serializer::builder().build(); assert_ok_eq!( (1i8, 2i16, 3i32).serialize(&serializer), [ Token::Tuple { len: 3 }, Token::I8(1), Token::I16(2), Token::I32(3), Token::TupleEnd ], ); } #[test] fn serialize_tuple_struct() { #[derive(Serialize)] struct TupleStruct(i8, i16, i32); let serializer = Serializer::builder().build(); assert_ok_eq!( TupleStruct(1i8, 2i16, 3i32).serialize(&serializer), [ Token::TupleStruct { name: "TupleStruct", len: 3 }, Token::I8(1), Token::I16(2), Token::I32(3), Token::TupleStructEnd ], ); } #[test] fn serialize_tuple_variant() { #[derive(Serialize)] enum Tuple { Variant(i8, i16, i32), } let serializer = Serializer::builder().build(); assert_ok_eq!( Tuple::Variant(1i8, 2i16, 3i32).serialize(&serializer), [ Token::TupleVariant { name: "Tuple", variant_index: 0, variant: "Variant", len: 3 }, Token::I8(1), Token::I16(2), Token::I32(3), Token::TupleVariantEnd ], ); } #[test] fn serialize_map() { let serializer = Serializer::builder().build(); let mut map = HashMap::new(); map.insert(1i8, 'a'); map.insert(2i8, 'b'); map.insert(3i8, 'c'); assert_ok_eq!( map.serialize(&serializer), [ Token::Map { len: Some(3) }, Token::Unordered(&[ &[Token::I8(1), Token::Char('a')], &[Token::I8(2), Token::Char('b')], &[Token::I8(3), Token::Char('c')], ]), Token::MapEnd, ] ); } #[test] fn serialize_struct() { #[derive(Serialize)] struct Struct { a: bool, b: u16, c: String, } let serializer = Serializer::builder().build(); assert_ok_eq!( Struct { a: true, b: 42, c: "foo".to_owned(), } .serialize(&serializer), [ Token::Struct { name: "Struct", len: 3, }, Token::Field("a"), Token::Bool(true), Token::Field("b"), Token::U16(42), Token::Field("c"), Token::Str("foo".to_owned()), Token::StructEnd, ] ); } #[test] fn serialize_struct_skipped_field() { fn skip(_: &T) -> bool { true } #[derive(Serialize)] struct Struct { a: bool, #[serde(skip_serializing_if = "skip")] b: u16, c: String, } let serializer = Serializer::builder().build(); assert_ok_eq!( Struct { a: true, b: 42, c: "foo".to_owned(), } .serialize(&serializer), [ Token::Struct { name: "Struct", len: 2, }, Token::Field("a"), Token::Bool(true), Token::SkippedField("b"), Token::Field("c"), Token::Str("foo".to_owned()), Token::StructEnd, ] ); } #[test] fn serialize_struct_as_seq() { #[derive(Serialize)] struct Struct { foo: bool, bar: u32, } let some_struct = Struct { foo: false, bar: 42, }; let serializer = Serializer::builder() .serialize_struct_as(SerializeStructAs::Seq) .build(); assert_ok_eq!( some_struct.serialize(&serializer), [ Token::Seq { len: Some(2) }, Token::Bool(false), Token::U32(42), Token::SeqEnd, ] ); } #[test] fn serialize_struct_variant() { #[derive(Serialize)] enum Struct { Variant { a: bool, b: u16, c: String }, } let serializer = Serializer::builder().build(); assert_ok_eq!( Struct::Variant { a: true, b: 42, c: "foo".to_owned(), } .serialize(&serializer), [ Token::StructVariant { name: "Struct", variant_index: 0, variant: "Variant", len: 3, }, Token::Field("a"), Token::Bool(true), Token::Field("b"), Token::U16(42), Token::Field("c"), Token::Str("foo".to_owned()), Token::StructVariantEnd, ] ); } #[test] fn serialize_struct_variant_skipped_field() { fn skip(_: &T) -> bool { true } #[derive(Serialize)] enum Struct { Variant { a: bool, #[serde(skip_serializing_if = "skip")] b: u16, c: String, }, } let serializer = Serializer::builder().build(); assert_ok_eq!( Struct::Variant { a: true, b: 42, c: "foo".to_owned(), } .serialize(&serializer), [ Token::StructVariant { name: "Struct", variant_index: 0, variant: "Variant", len: 2, }, Token::Field("a"), Token::Bool(true), Token::SkippedField("b"), Token::Field("c"), Token::Str("foo".to_owned()), Token::StructVariantEnd, ] ); } #[test] fn collect_str() { struct CollectedString(String); impl Serialize for CollectedString { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { serializer.collect_str(&self.0) } } let serializer = Serializer::builder().build(); assert_ok_eq!( CollectedString("foo".to_owned()).serialize(&serializer), [Token::Str("foo".to_owned())] ); } #[test] fn is_human_readable_default() { let serializer = Serializer::builder().build(); assert!((&serializer).is_human_readable()); } #[test] fn is_human_readable_false() { let serializer = Serializer::builder().is_human_readable(false).build(); assert!(!(&serializer).is_human_readable()); } #[test] fn is_human_readable_true() { let serializer = Serializer::builder().is_human_readable(true).build(); assert!((&serializer).is_human_readable()); } #[test] fn custom_error() { let error = Error::custom("foo"); assert_eq!(error.0, "foo"); } #[test] fn display_error() { let formatted = format!("{}", Error::custom("foo")); assert_eq!(formatted, "foo"); } } serde_assert-0.8.0/src/token.rs000064400000000000000000002153510072674642500146300ustar 00000000000000//! Tokens representing a serialized object. //! //! This module provides a [`Token`] type for representing a serialized value, as well as a //! [`Tokens`] type containing a set of `Token`s. `Tokens` are returned by a [`Serializer`] and can //! be compared against a sequence of `Token`s to verify equality, which is useful for asserting //! whether serialized `Tokens` are as expected. //! //! [`Serializer`]: crate::Serializer use alloc::{ boxed::Box, slice, string::String, vec, vec::Vec, }; use core::{ fmt, fmt::Debug, marker::PhantomData, mem::ManuallyDrop, ptr::NonNull, }; use serde::de::Unexpected; /// A single serialized value. /// /// A `Token` is a single serialization output produced by the [`Serializer`]. The one exception to /// this is the [`Unordered`] variant, which contains multiple sets of tokens that can be in any /// order. This is never produced by the `Serializer`, and is for use when comparing equality of /// sequences of [`Token`]s. /// /// Normally, a sequence of `Token`s are used to either compare against the output of a /// [`Serializer`] or to be used as input to a [`Deserializer`]. /// /// [`Deserializer`]: crate::Deserializer /// [`Serializer`]: crate::Serializer /// [`Unordered`]: Token::Unordered #[derive(Clone, Debug)] pub enum Token { /// A [`bool`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); /// ``` Bool(bool), /// An [`i8`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42i8.serialize(&serializer), [Token::I8(42)]); /// ``` I8(i8), /// An [`i16`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42i16.serialize(&serializer), [Token::I16(42)]); /// ``` I16(i16), /// An [`i32`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42i32.serialize(&serializer), [Token::I32(42)]); /// ``` I32(i32), /// An [`i64`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42i64.serialize(&serializer), [Token::I64(42)]); /// ``` I64(i64), /// An [`i128`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42i128.serialize(&serializer), [Token::I128(42)]); /// ``` I128(i128), /// A [`u8`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42u8.serialize(&serializer), [Token::U8(42)]); /// ``` U8(u8), /// A [`u16`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42u16.serialize(&serializer), [Token::U16(42)]); /// ``` U16(u16), /// A [`u32`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42u32.serialize(&serializer), [Token::U32(42)]); /// ``` U32(u32), /// A [`u64`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42u64.serialize(&serializer), [Token::U64(42)]); /// ``` U64(u64), /// A [`u128`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42u128.serialize(&serializer), [Token::U128(42)]); /// ``` U128(u128), /// A [`f32`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42.0f32.serialize(&serializer), [Token::F32(42.0)]); /// ``` F32(f32), /// A [`f64`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(42.0f64.serialize(&serializer), [Token::F64(42.0)]); /// ``` F64(f64), /// A [`char`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!('a'.serialize(&serializer), [Token::Char('a')]); /// ``` Char(char), /// A string. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!("foo".serialize(&serializer), [Token::Str("foo".to_owned())]); /// ``` Str(String), /// Bytes. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// use serde_bytes::Bytes; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// Bytes::new(b"foo").serialize(&serializer), /// [Token::Bytes(b"foo".to_vec())] /// ); /// ``` Bytes(Vec), /// An [`Option::None`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(Option::<()>::None.serialize(&serializer), [Token::None]); /// ``` None, /// An [`Option::Some`]. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(Some(()).serialize(&serializer), [Token::Some, Token::Unit]); /// ``` Some, /// A unit. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(().serialize(&serializer), [Token::Unit]); /// ``` Unit, /// A unit struct. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// struct UnitStruct; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// UnitStruct.serialize(&serializer), /// [Token::UnitStruct { name: "UnitStruct" }] /// ); /// ``` UnitStruct { name: &'static str }, /// A unit variant on an `enum`. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// enum Enum { /// Unit, /// } /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// Enum::Unit.serialize(&serializer), /// [Token::UnitVariant { /// name: "Enum", /// variant_index: 0, /// variant: "Unit" /// }] /// ); /// ``` UnitVariant { name: &'static str, variant_index: u32, variant: &'static str, }, /// A newtype struct. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// struct NewtypeStruct(u32); /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// NewtypeStruct(42).serialize(&serializer), /// [ /// Token::NewtypeStruct { /// name: "NewtypeStruct" /// }, /// Token::U32(42) /// ] /// ); /// ``` NewtypeStruct { name: &'static str }, /// A newtype variant on an `enum`. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// enum Enum { /// Newtype(u32), /// } /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// Enum::Newtype(42).serialize(&serializer), /// [ /// Token::NewtypeVariant { /// name: "Enum", /// variant_index: 0, /// variant: "Newtype" /// }, /// Token::U32(42) /// ] /// ); /// ``` NewtypeVariant { name: &'static str, variant_index: u32, variant: &'static str, }, /// A sequence. /// /// Must be followed by a [`SeqEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// vec![1u32, 2u32, 3u32].serialize(&serializer), /// [ /// Token::Seq { len: Some(3) }, /// Token::U32(1), /// Token::U32(2), /// Token::U32(3), /// Token::SeqEnd /// ] /// ); /// ``` /// /// [`SeqEnd`]: Token::SeqEnd Seq { len: Option }, /// The end of a sequence. /// /// This token must follow a [`Seq`] token. /// /// [`Seq`]: Token::Seq SeqEnd, /// A tuple. /// /// Must be followed by a [`TupleEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// (42u32, true).serialize(&serializer), /// [ /// Token::Tuple { len: 2 }, /// Token::U32(42), /// Token::Bool(true), /// Token::TupleEnd /// ] /// ); /// ``` /// /// [`TupleEnd`]: Token::TupleEnd Tuple { len: usize }, /// The end of a tuple. /// /// This token must follow a [`Tuple`] token. /// /// [`Tuple`]: Token::Tuple TupleEnd, /// A tuple struct. /// /// Must be followed by a [`TupleStructEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// struct TupleStruct(u32, bool); /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// TupleStruct(42u32, true).serialize(&serializer), /// [ /// Token::TupleStruct { /// name: "TupleStruct", /// len: 2 /// }, /// Token::U32(42), /// Token::Bool(true), /// Token::TupleStructEnd /// ] /// ); /// ``` /// /// [`TupleStructEnd`]: Token::TupleStructEnd TupleStruct { name: &'static str, len: usize }, /// The end of a tuple struct. /// /// This token must follow a [`TupleStruct`] token. /// /// [`TupleStruct`]: Token::TupleStruct TupleStructEnd, /// A tuple variant on an `enum`. /// /// Must be followed by a [`TupleVariantEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// enum Enum { /// Tuple(u32, bool), /// } /// struct TupleStruct(u32, bool); /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// Enum::Tuple(42u32, true).serialize(&serializer), /// [ /// Token::TupleVariant { /// name: "Enum", /// variant_index: 0, /// variant: "Tuple", /// len: 2 /// }, /// Token::U32(42), /// Token::Bool(true), /// Token::TupleVariantEnd /// ] /// ); /// ``` /// /// [`TupleVariantEnd`]: Token::TupleVariantEnd TupleVariant { name: &'static str, variant_index: u32, variant: &'static str, len: usize, }, /// The end of a tuple variant. /// /// This token must follow a [`TupleVariant`] token. /// /// [`TupleVariant`]: Token::TupleVariant TupleVariantEnd, /// A map. /// /// Must be followed by a [`MapEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// use std::collections::HashMap; /// /// let serializer = Serializer::builder().build(); /// /// let mut map = HashMap::new(); /// map.insert("foo", 42u32); /// /// assert_ok_eq!( /// map.serialize(&serializer), /// [ /// Token::Map { len: Some(1) }, /// Token::Str("foo".to_owned()), /// Token::U32(42), /// Token::MapEnd /// ] /// ); /// ``` /// /// [`MapEnd`]: Token::MapEnd Map { len: Option }, /// The end of a map. /// /// This token must follow a [`Map`] token. /// /// [`Map`]: Token::Map MapEnd, /// A field within a [`Struct`]. /// /// [`Struct`]: Token::Struct Field(&'static str), /// A field within a [`Struct`], skipped during serialization. /// /// This token is emitted when the [`SerializeStruct::skip_field()`] method is called during /// serialization. /// /// [`SerializeStruct::skip_field()`]: serde::ser::SerializeStruct::skip_field() /// [`Struct`]: Token::Struct SkippedField(&'static str), /// A struct. /// /// Must be followed by a [`StructEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// struct Struct { /// foo: u32, /// bar: bool, /// } /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// Struct { /// foo: 42u32, /// bar: true /// } /// .serialize(&serializer), /// [ /// Token::Struct { /// name: "Struct", /// len: 2 /// }, /// Token::Field("foo"), /// Token::U32(42), /// Token::Field("bar"), /// Token::Bool(true), /// Token::StructEnd /// ] /// ); /// ``` /// /// [`StructEnd`]: Token::StructEnd Struct { name: &'static str, len: usize }, /// The end of a struct. /// /// This token must follow a [`Struct`] token. /// /// [`Struct`]: Token::Struct StructEnd, /// A struct variant on an `enum`. /// /// Must be followed by a [`StructVariantEnd`] token. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// # use serde_derive::Serialize; /// /// #[derive(Serialize)] /// enum Enum { /// Struct { foo: u32, bar: bool }, /// } /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!( /// Enum::Struct { /// foo: 42u32, /// bar: true /// } /// .serialize(&serializer), /// [ /// Token::StructVariant { /// name: "Enum", /// variant_index: 0, /// variant: "Struct", /// len: 2 /// }, /// Token::Field("foo"), /// Token::U32(42), /// Token::Field("bar"), /// Token::Bool(true), /// Token::StructVariantEnd /// ] /// ); /// ``` /// /// [`StructVariantEnd`]: Token::StructVariantEnd StructVariant { name: &'static str, variant_index: u32, variant: &'static str, len: usize, }, /// The end of a struct variant. /// /// This token must follow a [`StructVariant`] token. /// /// [`StructVariant`]: Token::StructVariant StructVariantEnd, /// Unordered sets of tokens. /// /// This token is primarily used for evaluating output from a [`Serializer`] for containers or /// other types whose internal ordering is not defined (such as a [`HashSet`]). /// /// This is a set of groups of tokens, where the groups may appear in any order when comparing /// equality of [`Tokens`]. In other words, the outer slice is unordered, while the inner /// slices are all ordered. /// /// # Example /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// use std::collections::HashMap; /// /// let serializer = Serializer::builder().build(); /// /// let mut map = HashMap::::new(); /// map.insert('a', 1); /// map.insert('b', 2); /// map.insert('c', 3); /// /// assert_ok_eq!( /// map.serialize(&serializer), /// [ /// Token::Map { len: Some(3) }, /// Token::Unordered(&[ /// &[Token::Char('a'), Token::U32(1)], /// &[Token::Char('b'), Token::U32(2)], /// &[Token::Char('c'), Token::U32(3)] /// ]), /// Token::MapEnd /// ] /// ); /// ``` /// /// [`HashSet`]: std::collections::HashSet /// [`Serializer`]: crate::Serializer Unordered(&'static [&'static [Token]]), } /// An enumeration of all tokens that can be emitted by the [`Serializer`]. /// /// [`Serializer`]: crate::Serializer #[derive(Clone, Debug, PartialEq)] pub(crate) enum CanonicalToken { Bool(bool), I8(i8), I16(i16), I32(i32), I64(i64), I128(i128), U8(u8), U16(u16), U32(u32), U64(u64), U128(u128), F32(f32), F64(f64), Char(char), Str(String), Bytes(Vec), None, Some, Unit, UnitStruct { name: &'static str, }, UnitVariant { name: &'static str, variant_index: u32, variant: &'static str, }, NewtypeStruct { name: &'static str, }, NewtypeVariant { name: &'static str, variant_index: u32, variant: &'static str, }, Seq { len: Option, }, SeqEnd, Tuple { len: usize, }, TupleEnd, TupleStruct { name: &'static str, len: usize, }, TupleStructEnd, TupleVariant { name: &'static str, variant_index: u32, variant: &'static str, len: usize, }, TupleVariantEnd, Map { len: Option, }, MapEnd, Field(&'static str), SkippedField(&'static str), Struct { name: &'static str, len: usize, }, StructEnd, StructVariant { name: &'static str, variant_index: u32, variant: &'static str, len: usize, }, StructVariantEnd, } pub(crate) struct UnorderedTokens(pub(crate) &'static [&'static [Token]]); impl TryFrom for CanonicalToken { type Error = UnorderedTokens; fn try_from(token: Token) -> Result { match token { Token::Bool(value) => Ok(CanonicalToken::Bool(value)), Token::I8(value) => Ok(CanonicalToken::I8(value)), Token::I16(value) => Ok(CanonicalToken::I16(value)), Token::I32(value) => Ok(CanonicalToken::I32(value)), Token::I64(value) => Ok(CanonicalToken::I64(value)), Token::I128(value) => Ok(CanonicalToken::I128(value)), Token::U8(value) => Ok(CanonicalToken::U8(value)), Token::U16(value) => Ok(CanonicalToken::U16(value)), Token::U32(value) => Ok(CanonicalToken::U32(value)), Token::U64(value) => Ok(CanonicalToken::U64(value)), Token::U128(value) => Ok(CanonicalToken::U128(value)), Token::F32(value) => Ok(CanonicalToken::F32(value)), Token::F64(value) => Ok(CanonicalToken::F64(value)), Token::Char(value) => Ok(CanonicalToken::Char(value)), Token::Str(value) => Ok(CanonicalToken::Str(value)), Token::Bytes(value) => Ok(CanonicalToken::Bytes(value)), Token::None => Ok(CanonicalToken::None), Token::Some => Ok(CanonicalToken::Some), Token::Unit => Ok(CanonicalToken::Unit), Token::UnitStruct { name } => Ok(CanonicalToken::UnitStruct { name }), Token::UnitVariant { name, variant_index, variant, } => Ok(CanonicalToken::UnitVariant { name, variant_index, variant, }), Token::NewtypeStruct { name } => Ok(CanonicalToken::NewtypeStruct { name }), Token::NewtypeVariant { name, variant_index, variant, } => Ok(CanonicalToken::NewtypeVariant { name, variant_index, variant, }), Token::Seq { len } => Ok(CanonicalToken::Seq { len }), Token::SeqEnd => Ok(CanonicalToken::SeqEnd), Token::Tuple { len } => Ok(CanonicalToken::Tuple { len }), Token::TupleEnd => Ok(CanonicalToken::TupleEnd), Token::TupleStruct { name, len } => Ok(CanonicalToken::TupleStruct { name, len }), Token::TupleStructEnd => Ok(CanonicalToken::TupleStructEnd), Token::TupleVariant { name, variant_index, variant, len, } => Ok(CanonicalToken::TupleVariant { name, variant_index, variant, len, }), Token::TupleVariantEnd => Ok(CanonicalToken::TupleVariantEnd), Token::Map { len } => Ok(CanonicalToken::Map { len }), Token::MapEnd => Ok(CanonicalToken::MapEnd), Token::Field(value) => Ok(CanonicalToken::Field(value)), Token::SkippedField(value) => Ok(CanonicalToken::SkippedField(value)), Token::Struct { name, len } => Ok(CanonicalToken::Struct { name, len }), Token::StructEnd => Ok(CanonicalToken::StructEnd), Token::StructVariant { name, variant_index, variant, len, } => Ok(CanonicalToken::StructVariant { name, variant_index, variant, len, }), Token::StructVariantEnd => Ok(CanonicalToken::StructVariantEnd), Token::Unordered(tokens) => Err(UnorderedTokens(tokens)), } } } impl From for Token { fn from(token: CanonicalToken) -> Self { match token { CanonicalToken::Bool(value) => Token::Bool(value), CanonicalToken::I8(value) => Token::I8(value), CanonicalToken::I16(value) => Token::I16(value), CanonicalToken::I32(value) => Token::I32(value), CanonicalToken::I64(value) => Token::I64(value), CanonicalToken::I128(value) => Token::I128(value), CanonicalToken::U8(value) => Token::U8(value), CanonicalToken::U16(value) => Token::U16(value), CanonicalToken::U32(value) => Token::U32(value), CanonicalToken::U64(value) => Token::U64(value), CanonicalToken::U128(value) => Token::U128(value), CanonicalToken::F32(value) => Token::F32(value), CanonicalToken::F64(value) => Token::F64(value), CanonicalToken::Char(value) => Token::Char(value), CanonicalToken::Str(value) => Token::Str(value), CanonicalToken::Bytes(value) => Token::Bytes(value), CanonicalToken::None => Token::None, CanonicalToken::Some => Token::Some, CanonicalToken::Unit => Token::Unit, CanonicalToken::UnitStruct { name } => Token::UnitStruct { name }, CanonicalToken::UnitVariant { name, variant_index, variant, } => Token::UnitVariant { name, variant_index, variant, }, CanonicalToken::NewtypeStruct { name } => Token::NewtypeStruct { name }, CanonicalToken::NewtypeVariant { name, variant_index, variant, } => Token::NewtypeVariant { name, variant_index, variant, }, CanonicalToken::Seq { len } => Token::Seq { len }, CanonicalToken::SeqEnd => Token::SeqEnd, CanonicalToken::Tuple { len } => Token::Tuple { len }, CanonicalToken::TupleEnd => Token::TupleEnd, CanonicalToken::TupleStruct { name, len } => Token::TupleStruct { name, len }, CanonicalToken::TupleStructEnd => Token::TupleStructEnd, CanonicalToken::TupleVariant { name, variant_index, variant, len, } => Token::TupleVariant { name, variant_index, variant, len, }, CanonicalToken::TupleVariantEnd => Token::TupleVariantEnd, CanonicalToken::Map { len } => Token::Map { len }, CanonicalToken::MapEnd => Token::MapEnd, CanonicalToken::Field(value) => Token::Field(value), CanonicalToken::SkippedField(value) => Token::SkippedField(value), CanonicalToken::Struct { name, len } => Token::Struct { name, len }, CanonicalToken::StructEnd => Token::StructEnd, CanonicalToken::StructVariant { name, variant_index, variant, len, } => Token::StructVariant { name, variant_index, variant, len, }, CanonicalToken::StructVariantEnd => Token::StructVariantEnd, } } } impl<'a> From<&'a mut CanonicalToken> for Unexpected<'a> { fn from(token: &'a mut CanonicalToken) -> Self { match token { CanonicalToken::Bool(v) => Unexpected::Bool(*v), CanonicalToken::I8(v) => Unexpected::Signed((*v).into()), CanonicalToken::I16(v) => Unexpected::Signed((*v).into()), CanonicalToken::I32(v) => Unexpected::Signed((*v).into()), CanonicalToken::I64(v) => Unexpected::Signed(*v), CanonicalToken::I128(..) => Unexpected::Other("i128"), CanonicalToken::U8(v) => Unexpected::Unsigned((*v).into()), CanonicalToken::U16(v) => Unexpected::Unsigned((*v).into()), CanonicalToken::U32(v) => Unexpected::Unsigned((*v).into()), CanonicalToken::U64(v) => Unexpected::Unsigned(*v), CanonicalToken::U128(..) => Unexpected::Other("u128"), CanonicalToken::F32(v) => Unexpected::Float((*v).into()), CanonicalToken::F64(v) => Unexpected::Float(*v), CanonicalToken::Char(v) => Unexpected::Char(*v), CanonicalToken::Str(v) => Unexpected::Str(v), CanonicalToken::Bytes(v) => Unexpected::Bytes(v), CanonicalToken::Some | CanonicalToken::None => Unexpected::Option, CanonicalToken::Unit | CanonicalToken::UnitStruct { .. } => Unexpected::Unit, CanonicalToken::UnitVariant { .. } => Unexpected::UnitVariant, CanonicalToken::NewtypeStruct { .. } => Unexpected::NewtypeStruct, CanonicalToken::NewtypeVariant { .. } => Unexpected::NewtypeVariant, CanonicalToken::Seq { .. } | CanonicalToken::Tuple { .. } => Unexpected::Seq, CanonicalToken::SeqEnd => Unexpected::Other("SeqEnd"), CanonicalToken::TupleEnd => Unexpected::Other("TupleEnd"), CanonicalToken::TupleStruct { .. } => Unexpected::Other("TupleStruct"), CanonicalToken::TupleStructEnd => Unexpected::Other("TupleStructEnd"), CanonicalToken::TupleVariant { .. } => Unexpected::TupleVariant, CanonicalToken::TupleVariantEnd => Unexpected::Other("TupleVariantEnd"), CanonicalToken::Map { .. } => Unexpected::Map, CanonicalToken::MapEnd => Unexpected::Other("MapEnd"), CanonicalToken::Field(..) => Unexpected::Other("Field"), CanonicalToken::SkippedField(..) => Unexpected::Other("SkippedField"), CanonicalToken::Struct { .. } => Unexpected::Other("Struct"), CanonicalToken::StructEnd => Unexpected::Other("StructEnd"), CanonicalToken::StructVariant { .. } => Unexpected::StructVariant, CanonicalToken::StructVariantEnd => Unexpected::Other("StructVariantEnd"), } } } /// A sequence of [`Token`]s output by a [`Serializer`]. /// /// `Tokens` can be compared with any other sequence of `Token`s to assert that the serialized /// values are as expected. /// /// # Examples /// /// `Tokens` are output from a [`Serializer`] and can be compared against a sequence of `Token`s. /// /// ## Serialization /// /// ``` rust /// use claims::assert_ok_eq; /// use serde::Serialize; /// use serde_assert::{ /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// /// assert_ok_eq!(true.serialize(&serializer), [Token::Bool(true)]); /// ``` /// /// ## Deserialization /// /// `Tokens` obtained from a [`Serializer`] can be used as input to a [`Deserializer`]. /// /// ``` rust /// use claims::{ /// assert_ok, /// assert_ok_eq, /// }; /// use serde::{ /// Deserialize, /// Serialize, /// }; /// use serde_assert::{ /// Deserializer, /// Serializer, /// Token, /// }; /// /// let serializer = Serializer::builder().build(); /// let mut deserializer = Deserializer::builder(assert_ok!(true.serialize(&serializer))).build(); /// /// assert_ok_eq!(bool::deserialize(&mut deserializer), true); /// ``` /// /// [`Deserializer`]: crate::Deserializer /// [`Serializer`]: crate::Serializer #[derive(Clone, Debug)] pub struct Tokens(pub(crate) Vec); #[derive(Clone, Debug)] struct Context { current: slice::Iter<'static, Token>, remaining: Vec<&'static [Token]>, #[allow(clippy::struct_field_names)] // Acceptable, as the name refers to the contained type. nested_context: Option>, } impl Context { /// Creates a new context from the given parts. fn new(current: slice::Iter<'static, Token>, remaining: Vec<&'static [Token]>) -> Self { Self { current, remaining, nested_context: None, } } /// Nests this context within the contexts in the given split, returning those contexts. fn nest(self, mut split: Split) -> Vec { for context in &mut split.contexts { context.nested_context = Some(Box::new(self.clone())); } split.contexts } } impl Iterator for Context { type Item = &'static Token; fn next(&mut self) -> Option { self.current.next() } } #[derive(Debug)] struct Split { contexts: Vec, } impl Split { /// Returns whether a path exists through these split tokens using the given iterator. /// /// This will consume exactly the correct number of tokens from the given iterator. fn search<'a, I>(mut self, mut tokens: I) -> bool where I: Iterator, { while let Some(canonical_tokens) = self.next() { if canonical_tokens.is_empty() { // All contexts have ended, and therefore no path could be found. return false; } if let Some(token) = tokens.next() { self.contexts = self .contexts .into_iter() .zip(canonical_tokens) .filter_map(|(context, canonical_token)| { if *token == canonical_token { Some(context) } else { None } }) .collect(); } else { // Both sides had a different number of canonical tokens. return false; } } // We have found the end of the split tokens without failing to find equality in tokens. // This means that at least one path was found, and therefore the search succeeded. true } } impl Iterator for Split { /// Returns a token from each remaining context, removing contexts in-place if they split. /// /// If this returns an empty `Vec`, that means there were no contexts remaining when it was /// called. If this returns `None`, that means that all remaining contexts have hit the end of /// their tokens. type Item = Vec; fn next(&mut self) -> Option { if self.contexts.is_empty() { return Some(Vec::new()); } let mut result = Vec::with_capacity(self.contexts.len()); let mut index = 0; while index < self.contexts.len() { match self.contexts[index] .next() .cloned() .map(CanonicalToken::try_from) { Some(Ok(canonical_token)) => { result.push(canonical_token); index += 1; } Some(Err(unordered_tokens)) => { // Split and nest. let context = self.contexts.swap_remove(index); if let Ok(split) = unordered_tokens.try_into() { self.contexts.extend(context.nest(split)); } } None => { // Split from remaining. let context = self.contexts.swap_remove(index); if let Ok(split) = Split::try_from(context) { self.contexts.extend(split.contexts); } } } } if result.is_empty() { // No tokens returned, which means we are done processing this split. None } else { Some(result) } } } impl<'a> TryFrom<&'a [&'static [Token]]> for Split { type Error = (); fn try_from(value: &'a [&'static [Token]]) -> Result { if value.is_empty() { Err(()) } else { Ok(Self { contexts: (0..value.len()) .map(|index| { Context::new( value[index].iter(), value .iter() .enumerate() .filter_map( |(i, tokens)| if i == index { None } else { Some(*tokens) }, ) .collect(), ) }) .collect(), }) } } } impl TryFrom for Split { type Error = (); fn try_from(value: Context) -> Result { if let Ok(mut split) = Split::try_from(value.remaining.as_slice()) { for context in &mut split.contexts { context.nested_context.clone_from(&value.nested_context); } Ok(split) } else if let Some(nested_context) = value.nested_context { Ok(Split { contexts: vec![*nested_context], }) } else { Err(()) } } } impl TryFrom for Split { type Error = (); fn try_from(value: UnorderedTokens) -> Result { value.0.try_into() } } impl PartialEq for Tokens where for<'a> &'a T: IntoIterator, { fn eq(&self, other: &T) -> bool { let mut self_iter = self.0.iter(); for token in other { if !match CanonicalToken::try_from(token.clone()) { Ok(canonical_token) => { if let Some(self_token) = self_iter.next() { canonical_token == *self_token } else { // Both sides had a different number of canonical tokens. false } } Err(unordered_tokens) => Split::try_from(unordered_tokens) .map(|split| split.search(&mut self_iter)) .unwrap_or(true), } { return false; } } if self_iter.next().is_some() { // Both sides had a different number of canonical tokens. return false; } true } } impl IntoIterator for Tokens { type Item = Token; type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter { token_iter: self.0.into_iter(), } } } /// An iterator that moves [`Token`]s out of a [`Tokens`] `struct`. /// /// This `struct` is created by the [`into_iter()`] method on `Tokens` (provided by the /// [`IntoIterator`] trait). /// /// [`into_iter()`]: IntoIterator::into_iter() pub struct IntoIter { token_iter: vec::IntoIter, } impl Iterator for IntoIter { type Item = Token; fn next(&mut self) -> Option { self.token_iter.next().map(From::from) } } /// An iterator over tokens. /// /// This iterator owns the tokens, iterating over references to them. pub(crate) struct OwningIter<'a> { /// A pointer to the entire buffer that is owned by this struct. /// /// Immutable references to the `Token`s in this buffer can exist within the lifetime `'a`. buf: NonNull, /// A pointer to the current position in iteration. ptr: *mut CanonicalToken, /// A pointer to the end of the allocated buffer. end: *mut CanonicalToken, /// The capacity of the underlying allocation. /// /// This is only used for deallocating when the struct is dropped. cap: usize, /// The lifetime of the underlying `Token`s. /// /// `Token`s can be borrowed for up to the lifetime `'a`, allowing for zero-copy /// deserialization. lifetime: PhantomData<&'a ()>, } impl OwningIter<'_> { /// Creates a new `Iter` from a list of `Tokens`. /// /// Takes ownership of the `Tokens` and its underlying buffer. pub(crate) fn new(tokens: Tokens) -> Self { let mut tokens = ManuallyDrop::new(tokens); Self { // SAFETY: The pointer used by the `Vec` in `Tokens` is guaranteed to not be null. buf: unsafe { NonNull::new_unchecked(tokens.0.as_mut_ptr()) }, ptr: tokens.0.as_mut_ptr(), // SAFETY: The resulting pointer is one byte past the end of the allocated object. end: unsafe { tokens.0.as_mut_ptr().add(tokens.0.len()) }, cap: tokens.0.capacity(), lifetime: PhantomData, } } /// Returns the remaining `Token`s as a slice. fn as_slice(&self) -> &[CanonicalToken] { // SAFETY: `self.ptr` is guaranteed to be less than `self.end`, and therefore a valid // pointer within the allocated object. unsafe { slice::from_raw_parts( self.ptr, #[allow(clippy::cast_sign_loss)] { self.end.offset_from(self.ptr) as usize }, ) } } } impl<'a> Iterator for OwningIter<'a> { type Item = &'a mut CanonicalToken; fn next(&mut self) -> Option { if self.ptr == self.end { None } else { let current = self.ptr; // SAFETY: Since `self.ptr` is not equal to `self.end`, it must be before it, and // therefore incrementing by 1 will also result in a valid pointer within the allocated // object, or 1 byte past the end if the iteration has completed. self.ptr = unsafe { self.ptr.add(1) }; // SAFETY: The pointed-at object is guaranteed to be a valid `Token` that will live for // the lifetime `'a`. Some(unsafe { &mut *current }) } } } impl Debug for OwningIter<'_> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter .debug_tuple("OwningIter") .field(&self.as_slice()) .finish() } } impl Drop for OwningIter<'_> { fn drop(&mut self) { // SAFETY: The raw parts stored in this struct are guaranteed to correspond to the valid // parts of a `Vec`, since the parts were obtained directly from a `Vec` originally. unsafe { Vec::from_raw_parts( self.buf.as_ptr(), #[allow(clippy::cast_sign_loss)] { self.end.offset_from(self.buf.as_ptr()) as usize }, self.cap, ) }; } } #[cfg(test)] mod tests { use super::{ CanonicalToken, OwningIter, Token, Tokens, }; use alloc::{ borrow::ToOwned, format, vec, vec::Vec, }; use claims::{ assert_matches, assert_none, assert_some, assert_some_eq, }; use serde::de::Unexpected; #[test] fn tokens_bool_eq() { assert_eq!( Tokens(vec![CanonicalToken::Bool(true)]), [Token::Bool(true)] ); } #[test] fn tokens_bool_ne() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true)]), [Token::Bool(false)] ); } #[test] fn tokens_variant_ne() { assert_ne!(Tokens(vec![CanonicalToken::Bool(true)]), [Token::U16(42)]); } #[test] fn tokens_empty_eq() { assert_eq!(Tokens(vec![]), []); } #[test] fn tokens_multiple_eq() { assert_eq!( Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]), [Token::Bool(true), Token::U8(42)] ); } #[test] fn tokens_multiple_ne_values() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]), [Token::Bool(false), Token::U8(42)] ); } #[test] fn tokens_multiple_ne_shorter() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]), [Token::Bool(true)] ); } #[test] fn tokens_multiple_ne_longer() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]), [Token::Bool(true), Token::U8(42), Token::U8(42)] ); } #[test] fn tokens_unordered_eq_same_order() { assert_eq!( Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]), [Token::Unordered(&[&[Token::Bool(true)], &[Token::U8(42)]])], ); } #[test] fn tokens_unordered_eq_different_order() { assert_eq!( Tokens(vec![CanonicalToken::U8(42), CanonicalToken::Bool(true)]), [Token::Unordered(&[&[Token::Bool(true)], &[Token::U8(42)]])], ); } #[test] fn tokens_unordered_eq_within_other_tokens() { assert_eq!( Tokens(vec![ CanonicalToken::Char('a'), CanonicalToken::U8(42), CanonicalToken::Bool(true), CanonicalToken::I16(-42) ]), [ Token::Char('a'), Token::Unordered(&[&[Token::Bool(true)], &[Token::U8(42)]]), Token::I16(-42) ], ); } #[test] fn tokens_unordered_eq_multiple_tokens() { assert_eq!( Tokens(vec![ CanonicalToken::U8(42), CanonicalToken::Bool(true), CanonicalToken::Char('a') ]), [Token::Unordered(&[ &[Token::Bool(true), Token::Char('a')], &[Token::U8(42)] ])], ); } #[test] fn tokens_unordered_ne_empty() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true)]), [Token::Unordered(&[])], ); } #[test] fn tokens_unordered_ne_variant() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true)]), [Token::Unordered(&[&[Token::I8(42)]])], ); } #[test] fn tokens_unordered_ne_value() { assert_ne!( Tokens(vec![CanonicalToken::Bool(true)]), [Token::Unordered(&[&[Token::Bool(false)]])], ); } #[test] fn tokens_unordered_nested() { assert_eq!( Tokens(vec![ CanonicalToken::Unit, CanonicalToken::U8(4), CanonicalToken::U8(3), CanonicalToken::U8(1), CanonicalToken::U8(2), CanonicalToken::Bool(true) ]), [Token::Unordered(&[ &[Token::Bool(true)], &[Token::Unordered(&[ &[Token::U8(1), Token::U8(2)], &[Token::U8(3)], ])], &[Token::Unit, Token::U8(4)], ])] ); } #[test] fn tokens_unordered_empty() { assert_eq!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unordered(&[]), Token::Unit] ); } #[test] fn tokens_unordered_empty_nested() { assert_eq!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unordered(&[&[Token::Unordered(&[])]]), Token::Unit] ); } #[test] fn tokens_unordered_empty_at_end() { assert_eq!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unit, Token::Unordered(&[])] ); } #[test] fn tokens_unordered_nonempty_at_end() { assert_ne!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unit, Token::Unordered(&[&[Token::Unit]])] ); } #[test] fn tokens_end_within_unordered() { assert_ne!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unordered(&[&[Token::Unit,], &[Token::Unit]])] ); } #[test] fn tokens_end_within_unordered_more_tokens() { assert_ne!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unordered(&[&[Token::Unit, Token::Unit]])] ); } #[test] fn tokens_end_within_unordered_nested_empty() { assert_eq!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unordered(&[&[Token::Unit, Token::Unordered(&[])]])] ); } #[test] fn tokens_end_within_unordered_nested_nonempty() { assert_ne!( Tokens(vec![CanonicalToken::Unit,]), [Token::Unordered(&[&[ Token::Unit, Token::Unordered(&[&[Token::Unit, Token::Unit], &[Token::Unit]]) ]])] ); } #[test] fn token_from_canonical_token_bool() { assert_matches!(Token::from(CanonicalToken::Bool(true)), Token::Bool(true)) } #[test] fn token_from_canonical_token_i8() { assert_matches!(Token::from(CanonicalToken::I8(42)), Token::I8(42)) } #[test] fn token_from_canonical_token_i16() { assert_matches!(Token::from(CanonicalToken::I16(42)), Token::I16(42)) } #[test] fn token_from_canonical_token_i32() { assert_matches!(Token::from(CanonicalToken::I32(42)), Token::I32(42)) } #[test] fn token_from_canonical_token_i64() { assert_matches!(Token::from(CanonicalToken::I64(42)), Token::I64(42)) } #[test] fn token_from_canonical_token_i128() { assert_matches!(Token::from(CanonicalToken::I128(42)), Token::I128(42)) } #[test] fn token_from_canonical_token_u8() { assert_matches!(Token::from(CanonicalToken::U8(42)), Token::U8(42)) } #[test] fn token_from_canonical_token_u16() { assert_matches!(Token::from(CanonicalToken::U16(42)), Token::U16(42)) } #[test] fn token_from_canonical_token_u32() { assert_matches!(Token::from(CanonicalToken::U32(42)), Token::U32(42)) } #[test] fn token_from_canonical_token_u64() { assert_matches!(Token::from(CanonicalToken::U64(42)), Token::U64(42)) } #[test] fn token_from_canonical_token_u128() { assert_matches!(Token::from(CanonicalToken::U128(42)), Token::U128(42)) } #[test] fn token_from_canonical_token_f32() { assert_matches!(Token::from(CanonicalToken::F32(42.9)), Token::F32(_)) } #[test] fn token_from_canonical_token_f64() { assert_matches!(Token::from(CanonicalToken::F64(42.9)), Token::F64(_)) } #[test] fn token_from_canonical_token_char() { assert_matches!(Token::from(CanonicalToken::Char('a')), Token::Char('a')) } #[test] fn token_from_canonical_token_str() { assert_matches!( Token::from(CanonicalToken::Str("foo".to_owned())), Token::Str(_) ) } #[test] fn token_from_canonical_token_bytes() { assert_matches!( Token::from(CanonicalToken::Bytes(b"foo".to_vec())), Token::Bytes(_) ) } #[test] fn token_from_canonical_token_none() { assert_matches!(Token::from(CanonicalToken::None), Token::None) } #[test] fn token_from_canonical_token_some() { assert_matches!(Token::from(CanonicalToken::Some), Token::Some) } #[test] fn token_from_canonical_token_unit() { assert_matches!(Token::from(CanonicalToken::Unit), Token::Unit) } #[test] fn token_from_canonical_token_unit_struct() { assert_matches!( Token::from(CanonicalToken::UnitStruct { name: "foo" }), Token::UnitStruct { name: "foo" } ) } #[test] fn token_from_canonical_token_unit_variant() { assert_matches!( Token::from(CanonicalToken::UnitVariant { name: "foo", variant_index: 42, variant: "bar" }), Token::UnitVariant { name: "foo", variant_index: 42, variant: "bar" } ) } #[test] fn token_from_canonical_token_newtype_struct() { assert_matches!( Token::from(CanonicalToken::NewtypeStruct { name: "foo" }), Token::NewtypeStruct { name: "foo" } ) } #[test] fn token_from_canonical_token_newtype_variant() { assert_matches!( Token::from(CanonicalToken::NewtypeVariant { name: "foo", variant_index: 42, variant: "bar" }), Token::NewtypeVariant { name: "foo", variant_index: 42, variant: "bar" } ) } #[test] fn token_from_canonical_token_seq() { assert_matches!( Token::from(CanonicalToken::Seq { len: Some(42) }), Token::Seq { len: Some(42) } ) } #[test] fn token_from_canonical_token_seq_end() { assert_matches!(Token::from(CanonicalToken::SeqEnd), Token::SeqEnd) } #[test] fn token_from_canonical_token_tuple() { assert_matches!( Token::from(CanonicalToken::Tuple { len: 42 }), Token::Tuple { len: 42 } ) } #[test] fn token_from_canonical_token_tuple_end() { assert_matches!(Token::from(CanonicalToken::TupleEnd), Token::TupleEnd) } #[test] fn token_from_canonical_token_tuple_struct() { assert_matches!( Token::from(CanonicalToken::TupleStruct { name: "foo", len: 42 }), Token::TupleStruct { name: "foo", len: 42 } ) } #[test] fn token_from_canonical_token_tuple_struct_end() { assert_matches!( Token::from(CanonicalToken::TupleStructEnd), Token::TupleStructEnd ) } #[test] fn token_from_canonical_token_tuple_variant() { assert_matches!( Token::from(CanonicalToken::TupleVariant { name: "foo", variant_index: 42, variant: "bar", len: 42 }), Token::TupleVariant { name: "foo", variant_index: 42, variant: "bar", len: 42 } ) } #[test] fn token_from_canonical_token_tuple_variant_end() { assert_matches!( Token::from(CanonicalToken::TupleVariantEnd), Token::TupleVariantEnd ) } #[test] fn token_from_canonical_token_map() { assert_matches!( Token::from(CanonicalToken::Map { len: Some(42) }), Token::Map { len: Some(42) } ) } #[test] fn token_from_canonical_token_map_end() { assert_matches!(Token::from(CanonicalToken::MapEnd), Token::MapEnd) } #[test] fn token_from_canonical_token_field() { assert_matches!( Token::from(CanonicalToken::Field("foo")), Token::Field("foo") ) } #[test] fn token_from_canonical_token_skipped_field() { assert_matches!( Token::from(CanonicalToken::SkippedField("foo")), Token::SkippedField("foo") ) } #[test] fn token_from_canonical_token_struct() { assert_matches!( Token::from(CanonicalToken::Struct { name: "foo", len: 42 }), Token::Struct { name: "foo", len: 42 } ) } #[test] fn token_from_canonical_token_struct_end() { assert_matches!(Token::from(CanonicalToken::StructEnd), Token::StructEnd) } #[test] fn token_from_canonical_token_struct_variant() { assert_matches!( Token::from(CanonicalToken::StructVariant { name: "foo", variant_index: 42, variant: "bar", len: 42 }), Token::StructVariant { name: "foo", variant_index: 42, variant: "bar", len: 42 } ) } #[test] fn token_from_canonical_token_struct_variant_end() { assert_matches!( Token::from(CanonicalToken::StructVariantEnd), Token::StructVariantEnd ) } #[test] fn unexpected_from_canonical_token_bool() { assert_eq!( Unexpected::from(&mut CanonicalToken::Bool(true)), Unexpected::Bool(true) ) } #[test] fn unexpected_from_canonical_token_i8() { assert_eq!( Unexpected::from(&mut CanonicalToken::I8(42)), Unexpected::Signed(42) ) } #[test] fn unexpected_from_canonical_token_i16() { assert_eq!( Unexpected::from(&mut CanonicalToken::I16(42)), Unexpected::Signed(42) ) } #[test] fn unexpected_from_canonical_token_i32() { assert_eq!( Unexpected::from(&mut CanonicalToken::I32(42)), Unexpected::Signed(42) ) } #[test] fn unexpected_from_canonical_token_i64() { assert_eq!( Unexpected::from(&mut CanonicalToken::I64(42)), Unexpected::Signed(42) ) } #[test] fn unexpected_from_canonical_token_i128() { assert_eq!( Unexpected::from(&mut CanonicalToken::I128(42)), Unexpected::Other("i128") ) } #[test] fn unexpected_from_canonical_token_u8() { assert_eq!( Unexpected::from(&mut CanonicalToken::U8(42)), Unexpected::Unsigned(42) ) } #[test] fn unexpected_from_canonical_token_u16() { assert_eq!( Unexpected::from(&mut CanonicalToken::U16(42)), Unexpected::Unsigned(42) ) } #[test] fn unexpected_from_canonical_token_u32() { assert_eq!( Unexpected::from(&mut CanonicalToken::U32(42)), Unexpected::Unsigned(42) ) } #[test] fn unexpected_from_canonical_token_u64() { assert_eq!( Unexpected::from(&mut CanonicalToken::U64(42)), Unexpected::Unsigned(42) ) } #[test] fn unexpected_from_canonical_token_u128() { assert_eq!( Unexpected::from(&mut CanonicalToken::U128(42)), Unexpected::Other("u128") ) } #[test] fn unexpected_from_canonical_token_f32() { assert_eq!( Unexpected::from(&mut CanonicalToken::F32(42.)), Unexpected::Float(42.) ) } #[test] fn unexpected_from_canonical_token_f64() { assert_eq!( Unexpected::from(&mut CanonicalToken::F64(42.)), Unexpected::Float(42.) ) } #[test] fn unexpected_from_canonical_token_char() { assert_eq!( Unexpected::from(&mut CanonicalToken::Char('a')), Unexpected::Char('a') ) } #[test] fn unexpected_from_canonical_token_str() { assert_eq!( Unexpected::from(&mut CanonicalToken::Str("foo".to_owned())), Unexpected::Str("foo") ) } #[test] fn unexpected_from_canonical_token_bytes() { assert_eq!( Unexpected::from(&mut CanonicalToken::Bytes(b"foo".to_vec())), Unexpected::Bytes(b"foo") ) } #[test] fn unexpected_from_canonical_token_some() { assert_eq!( Unexpected::from(&mut CanonicalToken::Some), Unexpected::Option ) } #[test] fn unexpected_from_canonical_token_none() { assert_eq!( Unexpected::from(&mut CanonicalToken::None), Unexpected::Option ) } #[test] fn unexpected_from_canonical_token_unit() { assert_eq!( Unexpected::from(&mut CanonicalToken::Unit), Unexpected::Unit ) } #[test] fn unexpected_from_canonical_token_unit_struct() { assert_eq!( Unexpected::from(&mut CanonicalToken::UnitStruct { name: "foo" }), Unexpected::Unit ) } #[test] fn unexpected_from_canonical_token_unit_variant() { assert_eq!( Unexpected::from(&mut CanonicalToken::UnitVariant { name: "foo", variant_index: 0, variant: "bar" }), Unexpected::UnitVariant ) } #[test] fn unexpected_from_canonical_token_newtype_struct() { assert_eq!( Unexpected::from(&mut CanonicalToken::NewtypeStruct { name: "foo" }), Unexpected::NewtypeStruct ) } #[test] fn unexpected_from_canonical_token_newtype_variant() { assert_eq!( Unexpected::from(&mut CanonicalToken::NewtypeVariant { name: "foo", variant_index: 0, variant: "bar" }), Unexpected::NewtypeVariant ) } #[test] fn unexpected_from_canonical_token_seq() { assert_eq!( Unexpected::from(&mut CanonicalToken::Seq { len: None }), Unexpected::Seq ) } #[test] fn unexpected_from_canonical_token_tuple() { assert_eq!( Unexpected::from(&mut CanonicalToken::Tuple { len: 0 }), Unexpected::Seq ) } #[test] fn unexpected_from_canonical_token_seq_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::SeqEnd), Unexpected::Other("SeqEnd") ) } #[test] fn unexpected_from_canonical_token_tuple_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::TupleEnd), Unexpected::Other("TupleEnd") ) } #[test] fn unexpected_from_canonical_token_tuple_struct() { assert_eq!( Unexpected::from(&mut CanonicalToken::TupleStruct { name: "foo", len: 0 }), Unexpected::Other("TupleStruct") ) } #[test] fn unexpected_from_canonical_token_tuple_struct_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::TupleStructEnd), Unexpected::Other("TupleStructEnd") ) } #[test] fn unexpected_from_canonical_token_tuple_variant() { assert_eq!( Unexpected::from(&mut CanonicalToken::TupleVariant { name: "foo", variant_index: 0, variant: "bar", len: 0 }), Unexpected::TupleVariant ) } #[test] fn unexpected_from_canonical_token_tuple_variant_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::TupleVariantEnd), Unexpected::Other("TupleVariantEnd") ) } #[test] fn unexpected_from_canonical_token_map() { assert_eq!( Unexpected::from(&mut CanonicalToken::Map { len: None }), Unexpected::Map ) } #[test] fn unexpected_from_canonical_token_map_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::MapEnd), Unexpected::Other("MapEnd") ) } #[test] fn unexpected_from_canonical_token_field() { assert_eq!( Unexpected::from(&mut CanonicalToken::Field("foo")), Unexpected::Other("Field") ) } #[test] fn unexpected_from_canonical_token_skipped_field() { assert_eq!( Unexpected::from(&mut CanonicalToken::SkippedField("foo")), Unexpected::Other("SkippedField") ) } #[test] fn unexpected_from_canonical_token_struct() { assert_eq!( Unexpected::from(&mut CanonicalToken::Struct { name: "foo", len: 0 }), Unexpected::Other("Struct") ) } #[test] fn unexpected_from_canonical_token_struct_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::StructEnd), Unexpected::Other("StructEnd") ) } #[test] fn unexpected_from_canonical_token_struct_variant() { assert_eq!( Unexpected::from(&mut CanonicalToken::StructVariant { name: "foo", variant_index: 0, variant: "bar", len: 0 }), Unexpected::StructVariant ) } #[test] fn unexpected_from_canonical_token_struct_variant_end() { assert_eq!( Unexpected::from(&mut CanonicalToken::StructVariantEnd), Unexpected::Other("StructVariantEnd") ) } #[test] fn owning_iter_empty() { let mut iter = OwningIter::new(Tokens(Vec::new())); assert_none!(iter.next()); } #[test] fn owning_iter_one_token() { let mut iter = OwningIter::new(Tokens(vec![CanonicalToken::Bool(true)])); assert_some_eq!(iter.next(), &mut CanonicalToken::Bool(true)); assert_none!(iter.next()); } #[test] fn owning_iter_multiple_tokens() { let mut iter = OwningIter::new(Tokens(vec![ CanonicalToken::Bool(true), CanonicalToken::U64(42), CanonicalToken::Str("foo".to_owned()), ])); assert_some_eq!(iter.next(), &mut CanonicalToken::Bool(true)); assert_some_eq!(iter.next(), &mut CanonicalToken::U64(42)); assert_some_eq!(iter.next(), &mut CanonicalToken::Str("foo".to_owned())); assert_none!(iter.next()); } #[test] fn owning_iter_empty_debug() { let iter = OwningIter::new(Tokens(Vec::new())); assert_eq!(format!("{:?}", iter), "OwningIter([])") } #[test] fn owning_iter_uniterated_debug() { let iter = OwningIter::new(Tokens(vec![ CanonicalToken::Bool(true), CanonicalToken::U64(42), CanonicalToken::Str("foo".to_owned()), ])); assert_eq!( format!("{:?}", iter), "OwningIter([Bool(true), U64(42), Str(\"foo\")])" ) } #[test] fn owning_iter_partially_iterated_debug() { let mut iter = OwningIter::new(Tokens(vec![ CanonicalToken::Bool(true), CanonicalToken::U64(42), CanonicalToken::Str("foo".to_owned()), ])); assert_some!(iter.next()); assert_eq!(format!("{:?}", iter), "OwningIter([U64(42), Str(\"foo\")])") } #[test] fn owning_iter_fully_iterated_debug() { let mut iter = OwningIter::new(Tokens(vec![ CanonicalToken::Bool(true), CanonicalToken::U64(42), CanonicalToken::Str("foo".to_owned()), ])); assert_some!(iter.next()); assert_some!(iter.next()); assert_some!(iter.next()); assert_eq!(format!("{:?}", iter), "OwningIter([])") } } serde_assert-0.8.0/tests/roundtrip.rs000064400000000000000000000006750072674642500161120ustar 00000000000000use claims::{ assert_ok, assert_ok_eq, }; use serde::{ Deserialize, Serialize, }; use serde_assert::{ Deserializer, Serializer, }; #[test] fn roundtrip() { let value = true; let serializer = Serializer::builder().build(); let mut deserializer = Deserializer::builder(assert_ok!(value.serialize(&serializer))).build(); assert_ok_eq!(bool::deserialize(&mut deserializer), value); }