From e02c5b5930c2c9ba3e5423fe12e2ef0155017297 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 20:31:36 +0200 Subject: Merging upstream version 1.74.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/erased-serde/.cargo-checksum.json | 1 + vendor/erased-serde/Cargo.toml | 68 + vendor/erased-serde/LICENSE-APACHE | 176 +++ vendor/erased-serde/LICENSE-MIT | 23 + vendor/erased-serde/README.md | 149 ++ vendor/erased-serde/src/any.rs | 179 +++ vendor/erased-serde/src/de.rs | 1628 ++++++++++++++++++++ vendor/erased-serde/src/error.rs | 35 + vendor/erased-serde/src/features_check/error.rs | 1 + vendor/erased-serde/src/features_check/mod.rs | 13 + vendor/erased-serde/src/lib.rs | 144 ++ vendor/erased-serde/src/macros.rs | 165 ++ vendor/erased-serde/src/map.rs | 25 + vendor/erased-serde/src/private.rs | 16 + vendor/erased-serde/src/ser.rs | 1495 ++++++++++++++++++ vendor/erased-serde/tests/compiletest.rs | 7 + vendor/erased-serde/tests/readme.rs | 57 + vendor/erased-serde/tests/traitobject.rs | 9 + vendor/erased-serde/tests/ui/missing-supertrait.rs | 7 + .../tests/ui/missing-supertrait.stderr | 20 + 20 files changed, 4218 insertions(+) create mode 100644 vendor/erased-serde/.cargo-checksum.json create mode 100644 vendor/erased-serde/Cargo.toml create mode 100644 vendor/erased-serde/LICENSE-APACHE create mode 100644 vendor/erased-serde/LICENSE-MIT create mode 100644 vendor/erased-serde/README.md create mode 100644 vendor/erased-serde/src/any.rs create mode 100644 vendor/erased-serde/src/de.rs create mode 100644 vendor/erased-serde/src/error.rs create mode 100644 vendor/erased-serde/src/features_check/error.rs create mode 100644 vendor/erased-serde/src/features_check/mod.rs create mode 100644 vendor/erased-serde/src/lib.rs create mode 100644 vendor/erased-serde/src/macros.rs create mode 100644 vendor/erased-serde/src/map.rs create mode 100644 vendor/erased-serde/src/private.rs create mode 100644 vendor/erased-serde/src/ser.rs create mode 100644 vendor/erased-serde/tests/compiletest.rs create mode 100644 vendor/erased-serde/tests/readme.rs create mode 100644 vendor/erased-serde/tests/traitobject.rs create mode 100644 vendor/erased-serde/tests/ui/missing-supertrait.rs create mode 100644 vendor/erased-serde/tests/ui/missing-supertrait.stderr (limited to 'vendor/erased-serde') diff --git a/vendor/erased-serde/.cargo-checksum.json b/vendor/erased-serde/.cargo-checksum.json new file mode 100644 index 000000000..c508d1330 --- /dev/null +++ b/vendor/erased-serde/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"de39afb1c0cf20ecc92981167970609c3d9cbb4a8e1c8fe02e6a9986f85807ed","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f6b87ecbc2801e77cbd1a52b3724e1e665d78222466fcb1460e6b96cb4ee42ac","src/any.rs":"66e1b5dadbfe1d744fad7d59b5ba545fba0c242e3293a7531cccf4228583acf4","src/de.rs":"f232f3096e8b5d5e4fcc83a5ef330d3a0ed7169388f99827d3f2340db6140840","src/error.rs":"f433eb3f6cce216e17f1d0d6ffc218185f72ea8f47eef97dd265f910098d6d84","src/features_check/error.rs":"1f2b5d89f9d59ad84a9b77566f9446d36ce430e45eaffdcc30701e8e4de289b9","src/features_check/mod.rs":"2209f8d5c46b50c8a3b8dc22338dcaf0135d192e8b05d2f456cbe6a73104e958","src/lib.rs":"a1c90d18a80b1666d051a1528135819aead0e58ec0022e49293ec137ac181bca","src/macros.rs":"49a81da2c9d1d30f90fbb098f80a1087f452f2b040e8acdaea22882be6f7525f","src/map.rs":"56f8817b57c5b144575d2c20d3976adb90e1d56d5128cb3fda88c103144fd5da","src/private.rs":"86d585e6d55e9f4752631d5af74cb857aabf7bfe5f21090e5664b4e3cfb4e69f","src/ser.rs":"637348ed7e53c59787370f04953e3a20af72ddc324fc8694483caa9a526b8b6f","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/readme.rs":"5912a854d3c2d14d9da6b014c7af611b21217c9d5eadec3a874be41945742196","tests/traitobject.rs":"bbaae0d969b5b971e29efa16f7166850944006dc85abf6fa212e31f5e27d4cd0","tests/ui/missing-supertrait.rs":"4660ac0656579f2d7e4186c4a2158ac96a72b15c136cf06840be3812412c187d","tests/ui/missing-supertrait.stderr":"86edc9111421f57d7d59001a8a4e3b5266dc8200345dbae4df00a128bfe7aa6c"},"package":"6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c"} \ No newline at end of file diff --git a/vendor/erased-serde/Cargo.toml b/vendor/erased-serde/Cargo.toml new file mode 100644 index 000000000..8e6b593de --- /dev/null +++ b/vendor/erased-serde/Cargo.toml @@ -0,0 +1,68 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.56" +name = "erased-serde" +version = "0.3.31" +authors = ["David Tolnay "] +description = "Type-erased Serialize and Serializer traits" +documentation = "https://docs.rs/erased-serde" +readme = "README.md" +keywords = [ + "serde", + "erasure", +] +categories = [ + "encoding", + "rust-patterns", + "no-std", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/erased-serde" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +doc-scrape-examples = false + +[[test]] +name = "test" +path = "tests/readme.rs" + +[dependencies.serde] +version = "1.0.166" +default-features = false + +[dev-dependencies.rustversion] +version = "1.0.13" + +[dev-dependencies.serde_cbor] +version = "0.11.2" + +[dev-dependencies.serde_derive] +version = "1.0.166" + +[dev-dependencies.serde_json] +version = "1.0.99" + +[dev-dependencies.trybuild] +version = "1.0.83" +features = ["diff"] + +[features] +alloc = ["serde/alloc"] +default = ["std"] +std = ["serde/std"] +unstable-debug = [] diff --git a/vendor/erased-serde/LICENSE-APACHE b/vendor/erased-serde/LICENSE-APACHE new file mode 100644 index 000000000..1b5ec8b78 --- /dev/null +++ b/vendor/erased-serde/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/vendor/erased-serde/LICENSE-MIT b/vendor/erased-serde/LICENSE-MIT new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/vendor/erased-serde/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/vendor/erased-serde/README.md b/vendor/erased-serde/README.md new file mode 100644 index 000000000..6061b319d --- /dev/null +++ b/vendor/erased-serde/README.md @@ -0,0 +1,149 @@ +Erased Serde +============ + +[github](https://github.com/dtolnay/erased-serde) +[crates.io](https://crates.io/crates/erased-serde) +[docs.rs](https://docs.rs/erased-serde) +[build status](https://github.com/dtolnay/erased-serde/actions?query=branch%3Amaster) + +This crate provides type-erased versions of Serde's `Serialize`, `Serializer` +and `Deserializer` traits that can be used as [trait objects]. + +[trait objects]: https://doc.rust-lang.org/book/first-edition/trait-objects.html + +- [`erased_serde::Serialize`](https://docs.rs/erased-serde/0.3/erased_serde/trait.Serialize.html) +- [`erased_serde::Serializer`](https://docs.rs/erased-serde/0.3/erased_serde/trait.Serializer.html) +- [`erased_serde::Deserializer`](https://docs.rs/erased-serde/0.3/erased_serde/trait.Deserializer.html) + +The usual Serde `Serialize`, `Serializer` and `Deserializer` traits cannot be +used as trait objects like `&dyn Serialize` or boxed trait objects like +`Box` because of Rust's ["object safety" rules]. In particular, +all three traits contain generic methods which cannot be made into a trait +object. + +["object safety" rules]: http://huonw.github.io/blog/2015/01/object-safety/ + +This library should be considered a low-level building block for interacting +with Serde APIs in an object-safe way. Most use cases will require higher level +functionality such as provided by [`typetag`] which uses this crate internally. + +[`typetag`]: https://github.com/dtolnay/typetag + +**The traits in this crate work seamlessly with any existing Serde `Serialize` +and `Deserialize` type and any existing Serde `Serializer` and `Deserializer` +format.** + +```toml +[dependencies] +serde = "1.0" +erased-serde = "0.3" +``` + +## Serialization + +```rust +use erased_serde::{Serialize, Serializer}; +use std::collections::BTreeMap as Map; +use std::io; + +fn main() { + // Construct some serializers. + let json = &mut serde_json::Serializer::new(io::stdout()); + let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); + + // The values in this map are boxed trait objects. Ordinarily this would not + // be possible with serde::Serializer because of object safety, but type + // erasure makes it possible with erased_serde::Serializer. + let mut formats: Map<&str, Box> = Map::new(); + formats.insert("json", Box::new(::erase(json))); + formats.insert("cbor", Box::new(::erase(cbor))); + + // These are boxed trait objects as well. Same thing here - type erasure + // makes this possible. + let mut values: Map<&str, Box> = Map::new(); + values.insert("vec", Box::new(vec!["a", "b"])); + values.insert("int", Box::new(65536)); + + // Pick a Serializer out of the formats map. + let format = formats.get_mut("json").unwrap(); + + // Pick a Serialize out of the values map. + let value = values.get("vec").unwrap(); + + // This line prints `["a","b"]` to stdout. + value.erased_serialize(format).unwrap(); +} +``` + +## Deserialization + +```rust +use erased_serde::Deserializer; +use std::collections::BTreeMap as Map; + +fn main() { + static JSON: &[u8] = br#"{"A": 65, "B": 66}"#; + static CBOR: &[u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66]; + + // Construct some deserializers. + let json = &mut serde_json::Deserializer::from_slice(JSON); + let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR); + + // The values in this map are boxed trait objects, which is not possible + // with the normal serde::Deserializer because of object safety. + let mut formats: Map<&str, Box> = Map::new(); + formats.insert("json", Box::new(::erase(json))); + formats.insert("cbor", Box::new(::erase(cbor))); + + // Pick a Deserializer out of the formats map. + let format = formats.get_mut("json").unwrap(); + + let data: Map = erased_serde::deserialize(format).unwrap(); + + println!("{}", data["A"] + data["B"]); +} +``` + +## How it works + +This crate is based on a general technique for building trait objects of traits +that have generic methods (like all of Serde's traits). [This example code] +demonstrates the technique applied to a simplified case of a single generic +method. [Try it in the playground.] + +[This example code]: https://github.com/dtolnay/erased-serde/blob/master/explanation/main.rs +[Try it in the playground.]: https://play.rust-lang.org/?gist=c1111875e7462ba3d0190aacb2fc2211 + +In erased-serde things are a bit more complicated than in the example for three +reasons but the idea is the same. + +- We need to deal with trait methods that take `self` by value -- effectively by + implementing the object-safe trait for `Option` where `T` implements the + real trait. +- We need to deal with traits that have associated types like `Serializer::Ok` + and `Visitor::Value` -- by carefully short-term stashing things behind a + pointer. +- We need to support trait methods that have a generic type in the return type + but none of the argument types, like `SeqAccess::next_element` -- this can be + flipped around into a callback style where the return value is instead passed + on to a generic argument. + +In the future maybe the Rust compiler will be able to apply this technique +automatically to any trait that is not already object safe by the current rules. + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/vendor/erased-serde/src/any.rs b/vendor/erased-serde/src/any.rs new file mode 100644 index 000000000..c910fe909 --- /dev/null +++ b/vendor/erased-serde/src/any.rs @@ -0,0 +1,179 @@ +use crate::alloc::Box; +use core::any::TypeId; +use core::marker::PhantomData; +use core::mem::{self, MaybeUninit}; +use core::ptr; + +#[cfg(feature = "unstable-debug")] +use core::any; + +pub struct Any { + value: Value, + drop: unsafe fn(&mut Value), + type_id: TypeId, + + /// For panic messages only. Not used for comparison. + #[cfg(feature = "unstable-debug")] + type_name: &'static str, +} + +union Value { + ptr: *mut (), + inline: [MaybeUninit; 2], +} + +fn is_small() -> bool { + mem::size_of::() <= mem::size_of::() + && mem::align_of::() <= mem::align_of::() +} + +impl Any { + // This is unsafe -- caller must not hold on to the Any beyond the lifetime + // of T. + // + // Example of bad code: + // + // let s = "bad".to_owned(); + // let a = Any::new(&s); + // drop(s); + // + // Now `a.view()` and `a.take()` return references to a dead String. + pub(crate) unsafe fn new(t: T) -> Self { + let value: Value; + let drop: unsafe fn(&mut Value); + let type_id = non_static_type_id::(); + + if is_small::() { + let mut inline = [MaybeUninit::uninit(); 2]; + unsafe { ptr::write(inline.as_mut_ptr().cast::(), t) }; + value = Value { inline }; + unsafe fn inline_drop(value: &mut Value) { + unsafe { ptr::drop_in_place(value.inline.as_mut_ptr().cast::()) } + } + drop = inline_drop::; + } else { + let ptr = Box::into_raw(Box::new(t)).cast::<()>(); + value = Value { ptr }; + unsafe fn ptr_drop(value: &mut Value) { + mem::drop(unsafe { Box::from_raw(value.ptr.cast::()) }); + } + drop = ptr_drop::; + }; + + Any { + value, + drop, + type_id, + #[cfg(feature = "unstable-debug")] + type_name: any::type_name::(), + } + } + + // This is unsafe -- caller is responsible that T is the correct type. + pub(crate) unsafe fn view(&mut self) -> &mut T { + if self.type_id != non_static_type_id::() { + self.invalid_cast_to::(); + } + + let ptr = if is_small::() { + unsafe { self.value.inline.as_mut_ptr().cast::() } + } else { + unsafe { self.value.ptr.cast::() } + }; + + unsafe { &mut *ptr } + } + + // This is unsafe -- caller is responsible that T is the correct type. + pub(crate) unsafe fn take(mut self) -> T { + if self.type_id != non_static_type_id::() { + self.invalid_cast_to::(); + } + + if is_small::() { + let ptr = unsafe { self.value.inline.as_mut_ptr().cast::() }; + let value = unsafe { ptr::read(ptr) }; + mem::forget(self); + value + } else { + let ptr = unsafe { self.value.ptr.cast::() }; + let box_t = unsafe { Box::from_raw(ptr) }; + mem::forget(self); + *box_t + } + } + + #[cfg(not(feature = "unstable-debug"))] + fn invalid_cast_to(&self) -> ! { + panic!("invalid cast; enable `unstable-debug` feature to debug"); + } + + #[cfg(feature = "unstable-debug")] + fn invalid_cast_to(&self) -> ! { + let from = self.type_name; + let to = any::type_name::(); + panic!("invalid cast: {} to {}", from, to); + } +} + +impl Drop for Any { + fn drop(&mut self) { + unsafe { (self.drop)(&mut self.value) } + } +} + +trait NonStaticAny { + fn get_type_id(&self) -> TypeId + where + Self: 'static; +} + +impl NonStaticAny for PhantomData { + fn get_type_id(&self) -> TypeId + where + Self: 'static, + { + TypeId::of::() + } +} + +fn non_static_type_id() -> TypeId { + let non_static_thing = &PhantomData::; + let thing = unsafe { + mem::transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(non_static_thing) + }; + NonStaticAny::get_type_id(thing) +} + +#[test] +fn test_non_static_type_id() { + assert_eq!(non_static_type_id::(), non_static_type_id::()); + assert_eq!( + non_static_type_id::<&str>(), + non_static_type_id::<&'static str>() + ); + + assert_ne!(non_static_type_id::(), non_static_type_id::<[u8; 4]>()); + assert_ne!( + non_static_type_id::(), + non_static_type_id::<[u32; 2]>() + ); + + assert_ne!(non_static_type_id::(), non_static_type_id::()); + assert_ne!( + non_static_type_id::(), + non_static_type_id::<&usize>() + ); + assert_ne!( + non_static_type_id::<&usize>(), + non_static_type_id::<&&usize>() + ); + assert_ne!( + non_static_type_id::<&usize>(), + non_static_type_id::<&mut usize>() + ); + + struct A; + struct B; + assert_ne!(non_static_type_id::(), non_static_type_id::()); +} diff --git a/vendor/erased-serde/src/de.rs b/vendor/erased-serde/src/de.rs new file mode 100644 index 000000000..e03666e3b --- /dev/null +++ b/vendor/erased-serde/src/de.rs @@ -0,0 +1,1628 @@ +use crate::alloc::*; +use crate::any::Any; +use crate::error::Error; +use crate::map::{OptionExt, ResultExt}; +use core::fmt::{self, Display}; + +/// Deserialize a value of type `T` from the given trait object. +/// +/// ```rust +/// use erased_serde::Deserializer; +/// use std::collections::BTreeMap as Map; +/// +/// fn main() { +/// static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#; +/// static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66]; +/// +/// // Construct some deserializers. +/// let json = &mut serde_json::Deserializer::from_slice(JSON); +/// let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR); +/// +/// // The values in this map are boxed trait objects, which is not possible +/// // with the normal serde::Deserializer because of object safety. +/// let mut formats: Map<&str, Box> = Map::new(); +/// formats.insert("json", Box::new(::erase(json))); +/// formats.insert("cbor", Box::new(::erase(cbor))); +/// +/// // Pick a Deserializer out of the formats map. +/// let format = formats.get_mut("json").unwrap(); +/// +/// let data: Map = erased_serde::deserialize(format).unwrap(); +/// +/// println!("{}", data["A"] + data["B"]); +/// } +/// ``` +pub fn deserialize<'de, T>(deserializer: &mut dyn Deserializer<'de>) -> Result +where + T: serde::Deserialize<'de>, +{ + serde::Deserialize::deserialize(deserializer) +} + +// TRAITS ////////////////////////////////////////////////////////////////////// + +pub trait DeserializeSeed<'de> { + fn erased_deserialize_seed(&mut self, d: &mut dyn Deserializer<'de>) -> Result; +} + +/// An object-safe equivalent of Serde's `Deserializer` trait. +/// +/// Any implementation of Serde's `Deserializer` can be converted to an +/// `&erased_serde::Deserializer` or `Box` trait +/// object using `erased_serde::Deserializer::erase`. +/// +/// ```rust +/// use erased_serde::Deserializer; +/// use std::collections::BTreeMap as Map; +/// +/// fn main() { +/// static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#; +/// static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66]; +/// +/// // Construct some deserializers. +/// let json = &mut serde_json::Deserializer::from_slice(JSON); +/// let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR); +/// +/// // The values in this map are boxed trait objects, which is not possible +/// // with the normal serde::Deserializer because of object safety. +/// let mut formats: Map<&str, Box> = Map::new(); +/// formats.insert("json", Box::new(::erase(json))); +/// formats.insert("cbor", Box::new(::erase(cbor))); +/// +/// // Pick a Deserializer out of the formats map. +/// let format = formats.get_mut("json").unwrap(); +/// +/// let data: Map = erased_serde::deserialize(format).unwrap(); +/// +/// println!("{}", data["A"] + data["B"]); +/// } +/// ``` +pub trait Deserializer<'de> { + fn erased_deserialize_any(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_bool(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_i8(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_i16(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_i32(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_i64(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_i128(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_u8(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_u16(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_u32(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_u64(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_u128(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_f32(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_f64(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_char(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_str(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_string(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_bytes(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_byte_buf(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_option(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_unit(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_unit_struct( + &mut self, + name: &'static str, + v: &mut dyn Visitor<'de>, + ) -> Result; + fn erased_deserialize_newtype_struct( + &mut self, + name: &'static str, + v: &mut dyn Visitor<'de>, + ) -> Result; + fn erased_deserialize_seq(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_tuple( + &mut self, + len: usize, + v: &mut dyn Visitor<'de>, + ) -> Result; + fn erased_deserialize_tuple_struct( + &mut self, + name: &'static str, + len: usize, + v: &mut dyn Visitor<'de>, + ) -> Result; + fn erased_deserialize_map(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_struct( + &mut self, + name: &'static str, + fields: &'static [&'static str], + v: &mut dyn Visitor<'de>, + ) -> Result; + fn erased_deserialize_identifier(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_deserialize_enum( + &mut self, + name: &'static str, + variants: &'static [&'static str], + v: &mut dyn Visitor<'de>, + ) -> Result; + fn erased_deserialize_ignored_any(&mut self, v: &mut dyn Visitor<'de>) -> Result; + fn erased_is_human_readable(&self) -> bool; +} + +pub trait Visitor<'de> { + fn erased_expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result; + fn erased_visit_bool(&mut self, v: bool) -> Result; + fn erased_visit_i8(&mut self, v: i8) -> Result; + fn erased_visit_i16(&mut self, v: i16) -> Result; + fn erased_visit_i32(&mut self, v: i32) -> Result; + fn erased_visit_i64(&mut self, v: i64) -> Result; + fn erased_visit_i128(&mut self, v: i128) -> Result; + fn erased_visit_u8(&mut self, v: u8) -> Result; + fn erased_visit_u16(&mut self, v: u16) -> Result; + fn erased_visit_u32(&mut self, v: u32) -> Result; + fn erased_visit_u64(&mut self, v: u64) -> Result; + fn erased_visit_u128(&mut self, v: u128) -> Result; + fn erased_visit_f32(&mut self, v: f32) -> Result; + fn erased_visit_f64(&mut self, v: f64) -> Result; + fn erased_visit_char(&mut self, v: char) -> Result; + fn erased_visit_str(&mut self, v: &str) -> Result; + fn erased_visit_borrowed_str(&mut self, v: &'de str) -> Result; + #[cfg(any(feature = "std", feature = "alloc"))] + fn erased_visit_string(&mut self, v: String) -> Result; + fn erased_visit_bytes(&mut self, v: &[u8]) -> Result; + fn erased_visit_borrowed_bytes(&mut self, v: &'de [u8]) -> Result; + #[cfg(any(feature = "std", feature = "alloc"))] + fn erased_visit_byte_buf(&mut self, v: Vec) -> Result; + fn erased_visit_none(&mut self) -> Result; + fn erased_visit_some(&mut self, d: &mut dyn Deserializer<'de>) -> Result; + fn erased_visit_unit(&mut self) -> Result; + fn erased_visit_newtype_struct(&mut self, d: &mut dyn Deserializer<'de>) -> Result; + fn erased_visit_seq(&mut self, s: &mut dyn SeqAccess<'de>) -> Result; + fn erased_visit_map(&mut self, m: &mut dyn MapAccess<'de>) -> Result; + fn erased_visit_enum(&mut self, e: &mut dyn EnumAccess<'de>) -> Result; +} + +pub trait SeqAccess<'de> { + fn erased_next_element( + &mut self, + d: &mut dyn DeserializeSeed<'de>, + ) -> Result, Error>; + fn erased_size_hint(&self) -> Option; +} + +pub trait MapAccess<'de> { + fn erased_next_key(&mut self, d: &mut dyn DeserializeSeed<'de>) -> Result, Error>; + fn erased_next_value(&mut self, d: &mut dyn DeserializeSeed<'de>) -> Result; + fn erased_next_entry( + &mut self, + key: &mut dyn DeserializeSeed<'de>, + value: &mut dyn DeserializeSeed<'de>, + ) -> Result, Error>; + fn erased_size_hint(&self) -> Option; +} + +pub trait EnumAccess<'de> { + fn erased_variant_seed( + &mut self, + d: &mut dyn DeserializeSeed<'de>, + ) -> Result<(Out, Variant<'de>), Error>; +} + +impl<'de> dyn Deserializer<'de> { + /// Convert any Serde `Deserializer` to a trait object. + /// + /// ```rust + /// use erased_serde::Deserializer; + /// use std::collections::BTreeMap as Map; + /// + /// fn main() { + /// static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#; + /// static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66]; + /// + /// // Construct some deserializers. + /// let json = &mut serde_json::Deserializer::from_slice(JSON); + /// let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR); + /// + /// // The values in this map are boxed trait objects, which is not possible + /// // with the normal serde::Deserializer because of object safety. + /// let mut formats: Map<&str, Box> = Map::new(); + /// formats.insert("json", Box::new(::erase(json))); + /// formats.insert("cbor", Box::new(::erase(cbor))); + /// + /// // Pick a Deserializer out of the formats map. + /// let format = formats.get_mut("json").unwrap(); + /// + /// let data: Map = erased_serde::deserialize(format).unwrap(); + /// + /// println!("{}", data["A"] + data["B"]); + /// } + /// ``` + pub fn erase(deserializer: D) -> erase::Deserializer + where + D: serde::Deserializer<'de>, + { + erase::Deserializer { + state: Some(deserializer), + } + } +} + +// OUT ///////////////////////////////////////////////////////////////////////// + +pub struct Out(Any); + +impl Out { + unsafe fn new(t: T) -> Self { + Out(unsafe { Any::new(t) }) + } + + unsafe fn take(self) -> T { + unsafe { self.0.take() } + } +} + +// IMPL ERASED SERDE FOR SERDE ///////////////////////////////////////////////// + +mod erase { + pub struct DeserializeSeed { + pub(crate) state: Option, + } + + impl DeserializeSeed { + pub(crate) fn take(&mut self) -> D { + self.state.take().unwrap() + } + } + + pub struct Deserializer { + pub(crate) state: Option, + } + + impl Deserializer { + pub(crate) fn take(&mut self) -> D { + self.state.take().unwrap() + } + pub(crate) fn as_ref(&self) -> &D { + self.state.as_ref().unwrap() + } + } + + pub struct Visitor { + pub(crate) state: Option, + } + + impl Visitor { + pub(crate) fn take(&mut self) -> D { + self.state.take().unwrap() + } + pub(crate) fn as_ref(&self) -> &D { + self.state.as_ref().unwrap() + } + } + + pub struct SeqAccess { + pub(crate) state: D, + } + + impl SeqAccess { + pub(crate) fn as_ref(&self) -> &D { + &self.state + } + pub(crate) fn as_mut(&mut self) -> &mut D { + &mut self.state + } + } + + pub struct MapAccess { + pub(crate) state: D, + } + + impl MapAccess { + pub(crate) fn as_ref(&self) -> &D { + &self.state + } + pub(crate) fn as_mut(&mut self) -> &mut D { + &mut self.state + } + } + + pub struct EnumAccess { + pub(crate) state: Option, + } + + impl EnumAccess { + pub(crate) fn take(&mut self) -> D { + self.state.take().unwrap() + } + } +} + +impl<'de, T> DeserializeSeed<'de> for erase::DeserializeSeed +where + T: serde::de::DeserializeSeed<'de>, +{ + fn erased_deserialize_seed( + &mut self, + deserializer: &mut dyn Deserializer<'de>, + ) -> Result { + unsafe { self.take().deserialize(deserializer).unsafe_map(Out::new) } + } +} + +impl<'de, T> Deserializer<'de> for erase::Deserializer +where + T: serde::Deserializer<'de>, +{ + fn erased_deserialize_any(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_any(visitor).map_err(erase) + } + + fn erased_deserialize_bool(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_bool(visitor).map_err(erase) + } + + fn erased_deserialize_i8(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_i8(visitor).map_err(erase) + } + + fn erased_deserialize_i16(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_i16(visitor).map_err(erase) + } + + fn erased_deserialize_i32(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_i32(visitor).map_err(erase) + } + + fn erased_deserialize_i64(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_i64(visitor).map_err(erase) + } + + fn erased_deserialize_i128(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_i128(visitor).map_err(erase) + } + + fn erased_deserialize_u8(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_u8(visitor).map_err(erase) + } + + fn erased_deserialize_u16(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_u16(visitor).map_err(erase) + } + + fn erased_deserialize_u32(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_u32(visitor).map_err(erase) + } + + fn erased_deserialize_u64(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_u64(visitor).map_err(erase) + } + + fn erased_deserialize_u128(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_u128(visitor).map_err(erase) + } + + fn erased_deserialize_f32(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_f32(visitor).map_err(erase) + } + + fn erased_deserialize_f64(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_f64(visitor).map_err(erase) + } + + fn erased_deserialize_char(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_char(visitor).map_err(erase) + } + + fn erased_deserialize_str(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_str(visitor).map_err(erase) + } + + fn erased_deserialize_string(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_string(visitor).map_err(erase) + } + + fn erased_deserialize_bytes(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_bytes(visitor).map_err(erase) + } + + fn erased_deserialize_byte_buf( + &mut self, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take().deserialize_byte_buf(visitor).map_err(erase) + } + + fn erased_deserialize_option(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_option(visitor).map_err(erase) + } + + fn erased_deserialize_unit(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_unit(visitor).map_err(erase) + } + + fn erased_deserialize_unit_struct( + &mut self, + name: &'static str, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take() + .deserialize_unit_struct(name, visitor) + .map_err(erase) + } + + fn erased_deserialize_newtype_struct( + &mut self, + name: &'static str, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take() + .deserialize_newtype_struct(name, visitor) + .map_err(erase) + } + + fn erased_deserialize_seq(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_seq(visitor).map_err(erase) + } + + fn erased_deserialize_tuple( + &mut self, + len: usize, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take().deserialize_tuple(len, visitor).map_err(erase) + } + + fn erased_deserialize_tuple_struct( + &mut self, + name: &'static str, + len: usize, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take() + .deserialize_tuple_struct(name, len, visitor) + .map_err(erase) + } + + fn erased_deserialize_map(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + self.take().deserialize_map(visitor).map_err(erase) + } + + fn erased_deserialize_struct( + &mut self, + name: &'static str, + fields: &'static [&'static str], + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take() + .deserialize_struct(name, fields, visitor) + .map_err(erase) + } + + fn erased_deserialize_identifier( + &mut self, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take().deserialize_identifier(visitor).map_err(erase) + } + + fn erased_deserialize_enum( + &mut self, + name: &'static str, + variants: &'static [&'static str], + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take() + .deserialize_enum(name, variants, visitor) + .map_err(erase) + } + + fn erased_deserialize_ignored_any( + &mut self, + visitor: &mut dyn Visitor<'de>, + ) -> Result { + self.take().deserialize_ignored_any(visitor).map_err(erase) + } + + fn erased_is_human_readable(&self) -> bool { + self.as_ref().is_human_readable() + } +} + +impl<'de, T> Visitor<'de> for erase::Visitor +where + T: serde::de::Visitor<'de>, +{ + fn erased_expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.as_ref().expecting(formatter) + } + + fn erased_visit_bool(&mut self, v: bool) -> Result { + unsafe { self.take().visit_bool(v).unsafe_map(Out::new) } + } + + fn erased_visit_i8(&mut self, v: i8) -> Result { + unsafe { self.take().visit_i8(v).unsafe_map(Out::new) } + } + + fn erased_visit_i16(&mut self, v: i16) -> Result { + unsafe { self.take().visit_i16(v).unsafe_map(Out::new) } + } + + fn erased_visit_i32(&mut self, v: i32) -> Result { + unsafe { self.take().visit_i32(v).unsafe_map(Out::new) } + } + + fn erased_visit_i64(&mut self, v: i64) -> Result { + unsafe { self.take().visit_i64(v).unsafe_map(Out::new) } + } + + fn erased_visit_i128(&mut self, v: i128) -> Result { + unsafe { self.take().visit_i128(v).unsafe_map(Out::new) } + } + + fn erased_visit_u8(&mut self, v: u8) -> Result { + unsafe { self.take().visit_u8(v).unsafe_map(Out::new) } + } + + fn erased_visit_u16(&mut self, v: u16) -> Result { + unsafe { self.take().visit_u16(v).unsafe_map(Out::new) } + } + + fn erased_visit_u32(&mut self, v: u32) -> Result { + unsafe { self.take().visit_u32(v).unsafe_map(Out::new) } + } + + fn erased_visit_u64(&mut self, v: u64) -> Result { + unsafe { self.take().visit_u64(v).unsafe_map(Out::new) } + } + + fn erased_visit_u128(&mut self, v: u128) -> Result { + unsafe { self.take().visit_u128(v).unsafe_map(Out::new) } + } + + fn erased_visit_f32(&mut self, v: f32) -> Result { + unsafe { self.take().visit_f32(v).unsafe_map(Out::new) } + } + + fn erased_visit_f64(&mut self, v: f64) -> Result { + unsafe { self.take().visit_f64(v).unsafe_map(Out::new) } + } + + fn erased_visit_char(&mut self, v: char) -> Result { + unsafe { self.take().visit_char(v).unsafe_map(Out::new) } + } + + fn erased_visit_str(&mut self, v: &str) -> Result { + unsafe { self.take().visit_str(v).unsafe_map(Out::new) } + } + + fn erased_visit_borrowed_str(&mut self, v: &'de str) -> Result { + unsafe { self.take().visit_borrowed_str(v).unsafe_map(Out::new) } + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn erased_visit_string(&mut self, v: String) -> Result { + unsafe { self.take().visit_string(v).unsafe_map(Out::new) } + } + + fn erased_visit_bytes(&mut self, v: &[u8]) -> Result { + unsafe { self.take().visit_bytes(v).unsafe_map(Out::new) } + } + + fn erased_visit_borrowed_bytes(&mut self, v: &'de [u8]) -> Result { + unsafe { self.take().visit_borrowed_bytes(v).unsafe_map(Out::new) } + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn erased_visit_byte_buf(&mut self, v: Vec) -> Result { + unsafe { self.take().visit_byte_buf(v).unsafe_map(Out::new) } + } + + fn erased_visit_none(&mut self) -> Result { + unsafe { self.take().visit_none().unsafe_map(Out::new) } + } + + fn erased_visit_some( + &mut self, + deserializer: &mut dyn Deserializer<'de>, + ) -> Result { + unsafe { self.take().visit_some(deserializer).unsafe_map(Out::new) } + } + + fn erased_visit_unit(&mut self) -> Result { + unsafe { self.take().visit_unit().unsafe_map(Out::new) } + } + + fn erased_visit_newtype_struct( + &mut self, + deserializer: &mut dyn Deserializer<'de>, + ) -> Result { + unsafe { + self.take() + .visit_newtype_struct(deserializer) + .unsafe_map(Out::new) + } + } + + fn erased_visit_seq(&mut self, seq: &mut dyn SeqAccess<'de>) -> Result { + unsafe { self.take().visit_seq(seq).unsafe_map(Out::new) } + } + + fn erased_visit_map(&mut self, map: &mut dyn MapAccess<'de>) -> Result { + unsafe { self.take().visit_map(map).unsafe_map(Out::new) } + } + + fn erased_visit_enum(&mut self, data: &mut dyn EnumAccess<'de>) -> Result { + unsafe { self.take().visit_enum(data).unsafe_map(Out::new) } + } +} + +impl<'de, T> SeqAccess<'de> for erase::SeqAccess +where + T: serde::de::SeqAccess<'de>, +{ + fn erased_next_element( + &mut self, + seed: &mut dyn DeserializeSeed<'de>, + ) -> Result, Error> { + self.as_mut().next_element_seed(seed).map_err(erase) + } + + fn erased_size_hint(&self) -> Option { + self.as_ref().size_hint() + } +} + +impl<'de, T> MapAccess<'de> for erase::MapAccess +where + T: serde::de::MapAccess<'de>, +{ + fn erased_next_key( + &mut self, + seed: &mut dyn DeserializeSeed<'de>, + ) -> Result, Error> { + self.as_mut().next_key_seed(seed).map_err(erase) + } + + fn erased_next_value(&mut self, seed: &mut dyn DeserializeSeed<'de>) -> Result { + self.as_mut().next_value_seed(seed).map_err(erase) + } + + fn erased_next_entry( + &mut self, + k: &mut dyn DeserializeSeed<'de>, + v: &mut dyn DeserializeSeed<'de>, + ) -> Result, Error> { + self.as_mut().next_entry_seed(k, v).map_err(erase) + } + + fn erased_size_hint(&self) -> Option { + self.as_ref().size_hint() + } +} + +impl<'de, T> EnumAccess<'de> for erase::EnumAccess +where + T: serde::de::EnumAccess<'de>, +{ + fn erased_variant_seed( + &mut self, + seed: &mut dyn DeserializeSeed<'de>, + ) -> Result<(Out, Variant<'de>), Error> { + self.take() + .variant_seed(seed) + .map(|(out, variant)| { + use serde::de::VariantAccess; + let erased = Variant { + data: unsafe { Any::new(variant) }, + unit_variant: { + unsafe fn unit_variant<'de, T>(a: Any) -> Result<(), Error> + where + T: serde::de::EnumAccess<'de>, + { + unsafe { a.take::().unit_variant().map_err(erase) } + } + unit_variant:: + }, + visit_newtype: { + unsafe fn visit_newtype<'de, T>( + a: Any, + seed: &mut dyn DeserializeSeed<'de>, + ) -> Result + where + T: serde::de::EnumAccess<'de>, + { + unsafe { + a.take::() + .newtype_variant_seed(seed) + .map_err(erase) + } + } + visit_newtype:: + }, + tuple_variant: { + unsafe fn tuple_variant<'de, T>( + a: Any, + len: usize, + visitor: &mut dyn Visitor<'de>, + ) -> Result + where + T: serde::de::EnumAccess<'de>, + { + unsafe { + a.take::() + .tuple_variant(len, visitor) + .map_err(erase) + } + } + tuple_variant:: + }, + struct_variant: { + unsafe fn struct_variant<'de, T>( + a: Any, + fields: &'static [&'static str], + visitor: &mut dyn Visitor<'de>, + ) -> Result + where + T: serde::de::EnumAccess<'de>, + { + unsafe { + a.take::() + .struct_variant(fields, visitor) + .map_err(erase) + } + } + struct_variant:: + }, + }; + (out, erased) + }) + .map_err(erase) + } +} + +// IMPL SERDE FOR ERASED SERDE ///////////////////////////////////////////////// + +impl<'de> serde::de::DeserializeSeed<'de> for &mut (dyn DeserializeSeed<'de> + '_) { + type Value = Out; + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut erased = erase::Deserializer { + state: Some(deserializer), + }; + self.erased_deserialize_seed(&mut erased).map_err(unerase) + } +} + +macro_rules! impl_deserializer_for_trait_object { + ({$($mut:tt)*} $ty:ty) => { + impl<'de> serde::Deserializer<'de> for $ty { + type Error = Error; + + fn deserialize_any($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_any(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_bool($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_bool(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_i8($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_i8(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_i16($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_i16(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_i32($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_i32(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_i64($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_i64(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_i128($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_i128(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_u8($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_u8(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_u16($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_u16(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_u32($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_u32(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_u64($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_u64(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_u128($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_u128(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_f32($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_f32(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_f64($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_f64(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_char($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_char(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_str($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_str(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_string($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_string(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_bytes($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_bytes(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_byte_buf($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_byte_buf(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_option($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_option(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_unit($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_unit(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_unit_struct($($mut)* self, name: &'static str, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_unit_struct(name, &mut erased).unsafe_map(Out::take) } + } + + fn deserialize_newtype_struct($($mut)* self, name: &'static str, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_newtype_struct(name, &mut erased).unsafe_map(Out::take) } + } + + fn deserialize_seq($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_seq(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_tuple($($mut)* self, len: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_tuple(len, &mut erased).unsafe_map(Out::take) } + } + + fn deserialize_tuple_struct($($mut)* self, name: &'static str, len: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_tuple_struct(name, len, &mut erased).unsafe_map(Out::take) } + } + + fn deserialize_map($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_map(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_struct($($mut)* self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_struct(name, fields, &mut erased).unsafe_map(Out::take) } + } + + fn deserialize_identifier($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_identifier(&mut erased).unsafe_map(Out::take) } + } + + fn deserialize_enum($($mut)* self, name: &'static str, variants: &'static [&'static str], visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_enum(name, variants, &mut erased).unsafe_map(Out::take) } + } + + fn deserialize_ignored_any($($mut)* self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { state: Some(visitor) }; + unsafe { self.erased_deserialize_ignored_any(&mut erased).unsafe_map(Out::take) } + } + + fn is_human_readable(&self) -> bool { + self.erased_is_human_readable() + } + } + }; +} + +impl_deserializer_for_trait_object!({} &mut (dyn Deserializer<'de> + '_)); +impl_deserializer_for_trait_object!({} &mut (dyn Deserializer<'de> + Send + '_)); +impl_deserializer_for_trait_object!({} &mut (dyn Deserializer<'de> + Sync + '_)); +impl_deserializer_for_trait_object!({} &mut (dyn Deserializer<'de> + Send + Sync + '_)); +impl_deserializer_for_trait_object!({mut} Box + '_>); +impl_deserializer_for_trait_object!({mut} Box + Send + '_>); +impl_deserializer_for_trait_object!({mut} Box + Sync + '_>); +impl_deserializer_for_trait_object!({mut} Box + Send + Sync + '_>); + +impl<'de> serde::de::Visitor<'de> for &mut (dyn Visitor<'de> + '_) { + type Value = Out; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + (**self).erased_expecting(formatter) + } + + fn visit_bool(self, v: bool) -> Result + where + E: serde::de::Error, + { + self.erased_visit_bool(v).map_err(unerase) + } + + fn visit_i8(self, v: i8) -> Result + where + E: serde::de::Error, + { + self.erased_visit_i8(v).map_err(unerase) + } + + fn visit_i16(self, v: i16) -> Result + where + E: serde::de::Error, + { + self.erased_visit_i16(v).map_err(unerase) + } + + fn visit_i32(self, v: i32) -> Result + where + E: serde::de::Error, + { + self.erased_visit_i32(v).map_err(unerase) + } + + fn visit_i64(self, v: i64) -> Result + where + E: serde::de::Error, + { + self.erased_visit_i64(v).map_err(unerase) + } + + fn visit_i128(self, v: i128) -> Result + where + E: serde::de::Error, + { + self.erased_visit_i128(v).map_err(unerase) + } + + fn visit_u8(self, v: u8) -> Result + where + E: serde::de::Error, + { + self.erased_visit_u8(v).map_err(unerase) + } + + fn visit_u16(self, v: u16) -> Result + where + E: serde::de::Error, + { + self.erased_visit_u16(v).map_err(unerase) + } + + fn visit_u32(self, v: u32) -> Result + where + E: serde::de::Error, + { + self.erased_visit_u32(v).map_err(unerase) + } + + fn visit_u64(self, v: u64) -> Result + where + E: serde::de::Error, + { + self.erased_visit_u64(v).map_err(unerase) + } + + fn visit_u128(self, v: u128) -> Result + where + E: serde::de::Error, + { + self.erased_visit_u128(v).map_err(unerase) + } + + fn visit_f32(self, v: f32) -> Result + where + E: serde::de::Error, + { + self.erased_visit_f32(v).map_err(unerase) + } + + fn visit_f64(self, v: f64) -> Result + where + E: serde::de::Error, + { + self.erased_visit_f64(v).map_err(unerase) + } + + fn visit_char(self, v: char) -> Result + where + E: serde::de::Error, + { + self.erased_visit_char(v).map_err(unerase) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + self.erased_visit_str(v).map_err(unerase) + } + + fn visit_borrowed_str(self, v: &'de str) -> Result + where + E: serde::de::Error, + { + self.erased_visit_borrowed_str(v).map_err(unerase) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_string(self, v: String) -> Result + where + E: serde::de::Error, + { + self.erased_visit_string(v).map_err(unerase) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + self.erased_visit_bytes(v).map_err(unerase) + } + + fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result + where + E: serde::de::Error, + { + self.erased_visit_borrowed_bytes(v).map_err(unerase) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_byte_buf(self, v: Vec) -> Result + where + E: serde::de::Error, + { + self.erased_visit_byte_buf(v).map_err(unerase) + } + + fn visit_none(self) -> Result + where + E: serde::de::Error, + { + self.erased_visit_none().map_err(unerase) + } + + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut erased = erase::Deserializer { + state: Some(deserializer), + }; + self.erased_visit_some(&mut erased).map_err(unerase) + } + + fn visit_unit(self) -> Result + where + E: serde::de::Error, + { + self.erased_visit_unit().map_err(unerase) + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut erased = erase::Deserializer { + state: Some(deserializer), + }; + self.erased_visit_newtype_struct(&mut erased) + .map_err(unerase) + } + + fn visit_seq(self, seq: V) -> Result + where + V: serde::de::SeqAccess<'de>, + { + let mut erased = erase::SeqAccess { state: seq }; + self.erased_visit_seq(&mut erased).map_err(unerase) + } + + fn visit_map(self, map: V) -> Result + where + V: serde::de::MapAccess<'de>, + { + let mut erased = erase::MapAccess { state: map }; + self.erased_visit_map(&mut erased).map_err(unerase) + } + + fn visit_enum(self, data: V) -> Result + where + V: serde::de::EnumAccess<'de>, + { + let mut erased = erase::EnumAccess { state: Some(data) }; + self.erased_visit_enum(&mut erased).map_err(unerase) + } +} + +impl<'de> serde::de::SeqAccess<'de> for &mut (dyn SeqAccess<'de> + '_) { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: serde::de::DeserializeSeed<'de>, + { + let mut seed = erase::DeserializeSeed { state: Some(seed) }; + unsafe { + (**self) + .erased_next_element(&mut seed) + .map(|opt| opt.unsafe_map(Out::take)) + } + } + + fn size_hint(&self) -> Option { + (**self).erased_size_hint() + } +} + +impl<'de> serde::de::MapAccess<'de> for &mut (dyn MapAccess<'de> + '_) { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Error> + where + K: serde::de::DeserializeSeed<'de>, + { + let mut erased = erase::DeserializeSeed { state: Some(seed) }; + unsafe { + (**self) + .erased_next_key(&mut erased) + .map(|opt| opt.unsafe_map(Out::take)) + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: serde::de::DeserializeSeed<'de>, + { + let mut erased = erase::DeserializeSeed { state: Some(seed) }; + unsafe { + (**self) + .erased_next_value(&mut erased) + .unsafe_map(Out::take) + } + } + + fn size_hint(&self) -> Option { + (**self).erased_size_hint() + } +} + +impl<'de> serde::de::EnumAccess<'de> for &mut (dyn EnumAccess<'de> + '_) { + type Error = Error; + type Variant = Variant<'de>; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: serde::de::DeserializeSeed<'de>, + { + let mut erased = erase::DeserializeSeed { state: Some(seed) }; + match self.erased_variant_seed(&mut erased) { + Ok((out, variant)) => Ok((unsafe { out.take() }, variant)), + Err(err) => Err(err), + } + } +} + +pub struct Variant<'de> { + data: Any, + unit_variant: unsafe fn(Any) -> Result<(), Error>, + visit_newtype: unsafe fn(Any, seed: &mut dyn DeserializeSeed<'de>) -> Result, + tuple_variant: unsafe fn(Any, len: usize, visitor: &mut dyn Visitor<'de>) -> Result, + struct_variant: unsafe fn( + Any, + fields: &'static [&'static str], + visitor: &mut dyn Visitor<'de>, + ) -> Result, +} + +impl<'de> serde::de::VariantAccess<'de> for Variant<'de> { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + unsafe { (self.unit_variant)(self.data) } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: serde::de::DeserializeSeed<'de>, + { + let mut erased = erase::DeserializeSeed { state: Some(seed) }; + unsafe { (self.visit_newtype)(self.data, &mut erased).unsafe_map(Out::take) } + } + + fn tuple_variant(self, len: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { + state: Some(visitor), + }; + unsafe { (self.tuple_variant)(self.data, len, &mut erased).unsafe_map(Out::take) } + } + + fn struct_variant( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde::de::Visitor<'de>, + { + let mut erased = erase::Visitor { + state: Some(visitor), + }; + unsafe { (self.struct_variant)(self.data, fields, &mut erased).unsafe_map(Out::take) } + } +} + +// IMPL ERASED SERDE FOR ERASED SERDE ////////////////////////////////////////// + +macro_rules! deref_erased_deserializer { + ($($imp:tt)+) => { + impl $($imp)+ { + fn erased_deserialize_any(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_any(visitor) + } + + fn erased_deserialize_bool(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_bool(visitor) + } + + fn erased_deserialize_i8(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_i8(visitor) + } + + fn erased_deserialize_i16(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_i16(visitor) + } + + fn erased_deserialize_i32(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_i32(visitor) + } + + fn erased_deserialize_i64(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_i64(visitor) + } + + fn erased_deserialize_i128(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_i128(visitor) + } + + fn erased_deserialize_u8(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_u8(visitor) + } + + fn erased_deserialize_u16(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_u16(visitor) + } + + fn erased_deserialize_u32(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_u32(visitor) + } + + fn erased_deserialize_u64(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_u64(visitor) + } + + fn erased_deserialize_u128(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_u128(visitor) + } + + fn erased_deserialize_f32(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_f32(visitor) + } + + fn erased_deserialize_f64(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_f64(visitor) + } + + fn erased_deserialize_char(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_char(visitor) + } + + fn erased_deserialize_str(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_str(visitor) + } + + fn erased_deserialize_string(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_string(visitor) + } + + fn erased_deserialize_bytes(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_bytes(visitor) + } + + fn erased_deserialize_byte_buf(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_byte_buf(visitor) + } + + fn erased_deserialize_option(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_option(visitor) + } + + fn erased_deserialize_unit(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_unit(visitor) + } + + fn erased_deserialize_unit_struct(&mut self, name: &'static str, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_unit_struct(name, visitor) + } + + fn erased_deserialize_newtype_struct(&mut self, name: &'static str, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_newtype_struct(name, visitor) + } + + fn erased_deserialize_seq(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_seq(visitor) + } + + fn erased_deserialize_tuple(&mut self, len: usize, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_tuple(len, visitor) + } + + fn erased_deserialize_tuple_struct(&mut self, name: &'static str, len: usize, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_tuple_struct(name, len, visitor) + } + + fn erased_deserialize_map(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_map(visitor) + } + + fn erased_deserialize_struct(&mut self, name: &'static str, fields: &'static [&'static str], visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_struct(name, fields, visitor) + } + + fn erased_deserialize_identifier(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_identifier(visitor) + } + + fn erased_deserialize_enum(&mut self, name: &'static str, variants: &'static [&'static str], visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_enum(name, variants, visitor) + } + + fn erased_deserialize_ignored_any(&mut self, visitor: &mut dyn Visitor<'de>) -> Result { + (**self).erased_deserialize_ignored_any(visitor) + } + + fn erased_is_human_readable(&self) -> bool { + (**self).erased_is_human_readable() + } + } + }; +} + +deref_erased_deserializer!(<'de> Deserializer<'de> for Box + '_>); +deref_erased_deserializer!(<'de> Deserializer<'de> for Box + Send + '_>); +deref_erased_deserializer!(<'de> Deserializer<'de> for Box + Sync + '_>); +deref_erased_deserializer!(<'de> Deserializer<'de> for Box + Send + Sync + '_>); +deref_erased_deserializer!(<'de, T: ?Sized + Deserializer<'de>> Deserializer<'de> for &mut T); + +// ERROR /////////////////////////////////////////////////////////////////////// + +fn erase(e: E) -> Error +where + E: Display, +{ + serde::de::Error::custom(e) +} + +fn unerase(e: Error) -> E +where + E: serde::de::Error, +{ + E::custom(e) +} + +// TEST //////////////////////////////////////////////////////////////////////// + +#[cfg(test)] +mod tests { + use super::*; + use crate::alloc::ToOwned; + use core::fmt::Debug; + use serde_derive::Deserialize; + + fn test_json<'de, T>(json: &'de [u8]) + where + T: serde::Deserialize<'de> + PartialEq + Debug, + { + let expected: T = serde_json::from_slice(json).unwrap(); + + // test borrowed trait object + { + let mut de = serde_json::Deserializer::from_slice(json); + let de: &mut dyn Deserializer = &mut ::erase(&mut de); + assert_eq!(expected, deserialize::(de).unwrap()); + } + + // test boxed trait object + { + let mut de = serde_json::Deserializer::from_slice(json); + let mut de: Box = Box::new(::erase(&mut de)); + assert_eq!(expected, deserialize::(&mut de).unwrap()); + } + } + + #[test] + fn test_value() { + test_json::(br#"["a", 1, [true], {"a": 1}]"#); + } + + #[test] + fn test_struct() { + #[derive(Deserialize, PartialEq, Debug)] + struct S { + f: usize, + } + + test_json::(br#"{"f":256}"#); + } + + #[test] + fn test_enum() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Unit, + Newtype(bool), + Tuple(bool, bool), + Struct { t: bool, f: bool }, + } + + test_json::(br#""Unit""#); + test_json::(br#"{"Newtype":true}"#); + test_json::(br#"{"Tuple":[true,false]}"#); + test_json::(br#"{"Struct":{"t":true,"f":false}}"#); + } + + #[test] + fn test_borrowed() { + let bytes = br#""borrowed""#.to_owned(); + test_json::<&str>(&bytes); + } + + #[test] + fn assert_deserializer() { + fn assert<'de, T: serde::Deserializer<'de>>() {} + + assert::<&mut dyn Deserializer>(); + assert::<&mut (dyn Deserializer + Send)>(); + assert::<&mut (dyn Deserializer + Sync)>(); + assert::<&mut (dyn Deserializer + Send + Sync)>(); + assert::<&mut (dyn Deserializer + Sync + Send)>(); + + assert::>(); + assert::>(); + assert::>(); + assert::>(); + assert::>(); + } +} diff --git a/vendor/erased-serde/src/error.rs b/vendor/erased-serde/src/error.rs new file mode 100644 index 000000000..20952775b --- /dev/null +++ b/vendor/erased-serde/src/error.rs @@ -0,0 +1,35 @@ +use crate::alloc::{String, ToString}; +use core::fmt::{self, Display}; + +/// Error when a `Serializer` or `Deserializer` trait object fails. +#[derive(Debug)] +pub struct Error { + msg: String, +} + +/// Result type alias where the error is `erased_serde::Error`. +pub type Result = core::result::Result; + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.msg.fmt(formatter) + } +} + +impl serde::ser::StdError for Error {} + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self { + Error { + msg: msg.to_string(), + } + } +} + +impl serde::de::Error for Error { + fn custom(msg: T) -> Self { + Error { + msg: msg.to_string(), + } + } +} diff --git a/vendor/erased-serde/src/features_check/error.rs b/vendor/erased-serde/src/features_check/error.rs new file mode 100644 index 000000000..b5e6060b5 --- /dev/null +++ b/vendor/erased-serde/src/features_check/error.rs @@ -0,0 +1 @@ +"erased-serde requires that either `std` (default) or `alloc` feature is enabled" diff --git a/vendor/erased-serde/src/features_check/mod.rs b/vendor/erased-serde/src/features_check/mod.rs new file mode 100644 index 000000000..d12032cef --- /dev/null +++ b/vendor/erased-serde/src/features_check/mod.rs @@ -0,0 +1,13 @@ +//! Shows a user-friendly compiler error on incompatible selected features. + +#[allow(unused_macros)] +macro_rules! hide_from_rustfmt { + ($mod:item) => { + $mod + }; +} + +#[cfg(not(any(feature = "std", feature = "alloc")))] +hide_from_rustfmt! { + mod error; +} diff --git a/vendor/erased-serde/src/lib.rs b/vendor/erased-serde/src/lib.rs new file mode 100644 index 000000000..6b52ccc1b --- /dev/null +++ b/vendor/erased-serde/src/lib.rs @@ -0,0 +1,144 @@ +//! [![github]](https://github.com/dtolnay/erased-serde) [![crates-io]](https://crates.io/crates/erased-serde) [![docs-rs]](https://docs.rs/erased-serde) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! This crate provides type-erased versions of Serde's `Serialize`, `Serializer` +//! and `Deserializer` traits that can be used as [trait objects]. +//! +//! [trait objects]: https://doc.rust-lang.org/book/trait-objects.html +//! +//! The usual Serde `Serialize`, `Serializer` and `Deserializer` traits cannot +//! be used as trait objects like `&dyn Serialize` or boxed trait objects like +//! `Box` because of Rust's ["object safety" rules]. In +//! particular, all three traits contain generic methods which cannot be made +//! into a trait object. +//! +//! ["object safety" rules]: http://huonw.github.io/blog/2015/01/object-safety/ +//! +//! This library should be considered a low-level building block for interacting +//! with Serde APIs in an object-safe way. Most use cases will require higher +//! level functionality such as provided by [`typetag`] which uses this crate +//! internally. +//! +//! [`typetag`]: https://github.com/dtolnay/typetag +//! +//! **The traits in this crate work seamlessly with any existing Serde +//! `Serialize` and `Deserialize` type and any existing Serde `Serializer` and +//! `Deserializer` format.** +//! +//! ## Serialization +//! +//! ```rust +//! use erased_serde::{Serialize, Serializer}; +//! use std::collections::BTreeMap as Map; +//! use std::io; +//! +//! fn main() { +//! // Construct some serializers. +//! let json = &mut serde_json::Serializer::new(io::stdout()); +//! let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); +//! +//! // The values in this map are boxed trait objects. Ordinarily this would not +//! // be possible with serde::Serializer because of object safety, but type +//! // erasure makes it possible with erased_serde::Serializer. +//! let mut formats: Map<&str, Box> = Map::new(); +//! formats.insert("json", Box::new(::erase(json))); +//! formats.insert("cbor", Box::new(::erase(cbor))); +//! +//! // These are boxed trait objects as well. Same thing here - type erasure +//! // makes this possible. +//! let mut values: Map<&str, Box> = Map::new(); +//! values.insert("vec", Box::new(vec!["a", "b"])); +//! values.insert("int", Box::new(65536)); +//! +//! // Pick a Serializer out of the formats map. +//! let format = formats.get_mut("json").unwrap(); +//! +//! // Pick a Serialize out of the values map. +//! let value = values.get("vec").unwrap(); +//! +//! // This line prints `["a","b"]` to stdout. +//! value.erased_serialize(format).unwrap(); +//! } +//! ``` +//! +//! ## Deserialization +//! +//! ```rust +//! use erased_serde::Deserializer; +//! use std::collections::BTreeMap as Map; +//! +//! fn main() { +//! static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#; +//! static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66]; +//! +//! // Construct some deserializers. +//! let json = &mut serde_json::Deserializer::from_slice(JSON); +//! let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR); +//! +//! // The values in this map are boxed trait objects, which is not possible +//! // with the normal serde::Deserializer because of object safety. +//! let mut formats: Map<&str, Box> = Map::new(); +//! formats.insert("json", Box::new(::erase(json))); +//! formats.insert("cbor", Box::new(::erase(cbor))); +//! +//! // Pick a Deserializer out of the formats map. +//! let format = formats.get_mut("json").unwrap(); +//! +//! let data: Map = erased_serde::deserialize(format).unwrap(); +//! +//! println!("{}", data["A"] + data["B"]); +//! } +//! ``` + +#![doc(html_root_url = "https://docs.rs/erased-serde/0.3.31")] +#![cfg_attr(not(feature = "std"), no_std)] +#![deny(unsafe_op_in_unsafe_fn)] +#![allow( + clippy::derive_partial_eq_without_eq, + clippy::extra_unused_type_parameters, + clippy::items_after_statements, + clippy::manual_map, // https://github.com/rust-lang/rust-clippy/issues/7820 + clippy::missing_errors_doc, + clippy::needless_doctest_main, + clippy::needless_pass_by_ref_mut, + clippy::semicolon_if_nothing_returned, // https://github.com/rust-lang/rust-clippy/issues/7324 + clippy::unused_self, + clippy::wildcard_imports +)] + +mod alloc { + #[cfg(not(feature = "std"))] + extern crate alloc; + + #[cfg(feature = "std")] + use std as alloc; + + pub use self::alloc::borrow::ToOwned; + pub use self::alloc::boxed::Box; + pub use self::alloc::string::{String, ToString}; + pub use self::alloc::{vec, vec::Vec}; +} + +#[macro_use] +mod macros; + +mod any; +mod de; +mod error; +mod features_check; +mod map; +mod ser; + +pub use crate::de::{deserialize, Deserializer}; +pub use crate::error::{Error, Result}; +pub use crate::ser::{serialize, Serialize, Serializer}; + +// Not public API. +#[doc(hidden)] +#[path = "private.rs"] +pub mod __private; diff --git a/vendor/erased-serde/src/macros.rs b/vendor/erased-serde/src/macros.rs new file mode 100644 index 000000000..393798c46 --- /dev/null +++ b/vendor/erased-serde/src/macros.rs @@ -0,0 +1,165 @@ +/// Implement `serde::Serialize` for a trait object that has +/// `erased_serde::Serialize` as a supertrait. +/// +/// ``` +/// use erased_serde::serialize_trait_object; +/// +/// trait Event: erased_serde::Serialize { +/// /* ... */ +/// } +/// +/// erased_serde::serialize_trait_object!(Event); +/// ``` +/// +/// The macro supports traits that have type parameters and/or `where` clauses. +/// +/// ``` +/// # use erased_serde::serialize_trait_object; +/// # +/// trait Difficult: erased_serde::Serialize where T: Copy { +/// /* ... */ +/// } +/// +/// serialize_trait_object!( Difficult where T: Copy); +/// ``` +#[macro_export] +macro_rules! serialize_trait_object { + ($($path:tt)+) => { + $crate::__internal_serialize_trait_object!(begin $($path)+); + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __internal_serialize_trait_object { + // Invocation started with `<`, parse generics. + (begin < $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(generics () () $($rest)*); + }; + + // Invocation did not start with `<`. + (begin $first:tt $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(path () ($first) $($rest)*); + }; + + // End of generics with trailing comma. + (generics ($($generics:tt)*) () , > $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(path ($($generics)* ,) () $($rest)*); + }; + + // End of generics without trailing comma. + (generics ($($generics:tt)*) () > $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(path ($($generics)* ,) () $($rest)*); + }; + + // Generics open bracket. + (generics ($($generics:tt)*) ($($brackets:tt)*) < $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(generics ($($generics)* <) ($($brackets)* <) $($rest)*); + }; + + // Generics close bracket. + (generics ($($generics:tt)*) (< $($brackets:tt)*) > $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(generics ($($generics)* >) ($($brackets)*) $($rest)*); + }; + + // Token inside of generics. + (generics ($($generics:tt)*) ($($brackets:tt)*) $first:tt $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(generics ($($generics)* $first) ($($brackets)*) $($rest)*); + }; + + // End with `where` clause. + (path ($($generics:tt)*) ($($path:tt)*) where $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(sendsync ($($generics)*) ($($path)*) ($($rest)*)); + }; + + // End without `where` clause. + (path ($($generics:tt)*) ($($path:tt)*)) => { + $crate::__internal_serialize_trait_object!(sendsync ($($generics)*) ($($path)*) ()); + }; + + // Token inside of path. + (path ($($generics:tt)*) ($($path:tt)*) $first:tt $($rest:tt)*) => { + $crate::__internal_serialize_trait_object!(path ($($generics)*) ($($path)* $first) $($rest)*); + }; + + // Expand into four impls. + (sendsync ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => { + $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)*) ($($bound)*) { + fn __check_erased_serialize_supertrait<$($generics)* __T>() + where + __T: ?$crate::__private::Sized + $($path)*, + $($bound)* + { + $crate::__private::require_erased_serialize_impl::<__T>(); + } + }); + $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::__private::Send) ($($bound)*)); + $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::__private::Sync) ($($bound)*)); + $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::__private::Send + $crate::__private::Sync) ($($bound)*)); + }; + + // The impl. + (impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*) $({$($body:tt)*})*) => { + impl<'erased, $($generics)*> $crate::__private::serde::Serialize for dyn $($path)* + 'erased + where + $($bound)* + { + fn serialize(&self, serializer: S) -> $crate::__private::Result + where + S: $crate::__private::serde::Serializer, + { + $($($body)*)* + $crate::serialize(self, serializer) + } + } + }; +} + +// TEST //////////////////////////////////////////////////////////////////////// + +#[cfg(test)] +mod tests { + use crate::Serialize; + + fn assert_serialize() {} + + #[test] + fn test_plain() { + trait Trait: Serialize {} + + serialize_trait_object!(Trait); + assert_serialize::(); + assert_serialize::(); + } + + #[test] + fn test_type_parameter() { + trait Trait: Serialize {} + + serialize_trait_object!( Trait); + assert_serialize::>(); + assert_serialize:: + Send>(); + } + + #[test] + fn test_generic_bound() { + trait Trait, U>: Serialize {} + + serialize_trait_object!(, U> Trait); + assert_serialize::>(); + assert_serialize:: + Send>(); + } + + #[test] + fn test_where_clause() { + trait Trait: Serialize + where + T: Clone, + { + } + + serialize_trait_object!( Trait where T: Clone); + assert_serialize::>(); + assert_serialize:: + Send>(); + } +} diff --git a/vendor/erased-serde/src/map.rs b/vendor/erased-serde/src/map.rs new file mode 100644 index 000000000..c670805e3 --- /dev/null +++ b/vendor/erased-serde/src/map.rs @@ -0,0 +1,25 @@ +pub(crate) trait ResultExt { + unsafe fn unsafe_map(self, op: unsafe fn(T) -> U) -> Result; +} + +impl ResultExt for Result { + unsafe fn unsafe_map(self, op: unsafe fn(T) -> U) -> Result { + match self { + Ok(t) => Ok(unsafe { op(t) }), + Err(e) => Err(e), + } + } +} + +pub(crate) trait OptionExt { + unsafe fn unsafe_map(self, op: unsafe fn(T) -> U) -> Option; +} + +impl OptionExt for Option { + unsafe fn unsafe_map(self, op: unsafe fn(T) -> U) -> Option { + match self { + Some(t) => Some(unsafe { op(t) }), + None => None, + } + } +} diff --git a/vendor/erased-serde/src/private.rs b/vendor/erased-serde/src/private.rs new file mode 100644 index 000000000..c23ab3722 --- /dev/null +++ b/vendor/erased-serde/src/private.rs @@ -0,0 +1,16 @@ +//! Not public API. Used as `$crate::__private` by macros. + +#[doc(hidden)] +pub use core::marker::{Send, Sized, Sync}; +#[doc(hidden)] +pub use serde; + +#[doc(hidden)] +pub type Result = core::result::Result; + +#[doc(hidden)] +pub fn require_erased_serialize_impl() +where + T: ?Sized + crate::Serialize, +{ +} diff --git a/vendor/erased-serde/src/ser.rs b/vendor/erased-serde/src/ser.rs new file mode 100644 index 000000000..10c486bcb --- /dev/null +++ b/vendor/erased-serde/src/ser.rs @@ -0,0 +1,1495 @@ +use crate::alloc::Box; +use crate::any::Any; +use crate::error::Error; +use crate::map::ResultExt; +use core::fmt::Display; +use core::marker::PhantomData; +use serde::ser::{ + SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, + SerializeTupleStruct, SerializeTupleVariant, +}; + +// TRAITS ////////////////////////////////////////////////////////////////////// + +/// An object-safe equivalent of Serde's `Serialize` trait. +/// +/// Any implementation of Serde's `Serialize` converts seamlessly to an +/// `&erased_serde::Serialize` or `Box` trait object. +/// +/// ```rust +/// use erased_serde::{Serialize, Serializer}; +/// use std::collections::BTreeMap as Map; +/// use std::io; +/// +/// fn main() { +/// // Construct some serializers. +/// let json = &mut serde_json::Serializer::new(io::stdout()); +/// let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); +/// +/// // The values in this map are boxed trait objects. Ordinarily this would not +/// // be possible with serde::Serializer because of object safety, but type +/// // erasure makes it possible with erased_serde::Serializer. +/// let mut formats: Map<&str, Box> = Map::new(); +/// formats.insert("json", Box::new(::erase(json))); +/// formats.insert("cbor", Box::new(::erase(cbor))); +/// +/// // These are boxed trait objects as well. Same thing here - type erasure +/// // makes this possible. +/// let mut values: Map<&str, Box> = Map::new(); +/// values.insert("vec", Box::new(vec!["a", "b"])); +/// values.insert("int", Box::new(65536)); +/// +/// // Pick a Serializer out of the formats map. +/// let format = formats.get_mut("json").unwrap(); +/// +/// // Pick a Serialize out of the values map. +/// let value = values.get("vec").unwrap(); +/// +/// // This line prints `["a","b"]` to stdout. +/// value.erased_serialize(format).unwrap(); +/// } +/// ``` +pub trait Serialize { + fn erased_serialize(&self, v: &mut dyn Serializer) -> Result; +} + +/// An object-safe equivalent of Serde's `Serializer` trait. +/// +/// Any implementation of Serde's `Serializer` can be converted to an +/// `&erased_serde::Serializer` or `Box` trait object +/// using `erased_serde::Serializer::erase`. +/// +/// ```rust +/// use erased_serde::{Serialize, Serializer}; +/// use std::collections::BTreeMap as Map; +/// use std::io; +/// +/// fn main() { +/// // Construct some serializers. +/// let json = &mut serde_json::Serializer::new(io::stdout()); +/// let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); +/// +/// // The values in this map are boxed trait objects. Ordinarily this would not +/// // be possible with serde::Serializer because of object safety, but type +/// // erasure makes it possible with erased_serde::Serializer. +/// let mut formats: Map<&str, Box> = Map::new(); +/// formats.insert("json", Box::new(::erase(json))); +/// formats.insert("cbor", Box::new(::erase(cbor))); +/// +/// // These are boxed trait objects as well. Same thing here - type erasure +/// // makes this possible. +/// let mut values: Map<&str, Box> = Map::new(); +/// values.insert("vec", Box::new(vec!["a", "b"])); +/// values.insert("int", Box::new(65536)); +/// +/// // Pick a Serializer out of the formats map. +/// let format = formats.get_mut("json").unwrap(); +/// +/// // Pick a Serialize out of the values map. +/// let value = values.get("vec").unwrap(); +/// +/// // This line prints `["a","b"]` to stdout. +/// value.erased_serialize(format).unwrap(); +/// } +/// ``` +pub trait Serializer { + fn erased_serialize_bool(&mut self, v: bool) -> Result; + fn erased_serialize_i8(&mut self, v: i8) -> Result; + fn erased_serialize_i16(&mut self, v: i16) -> Result; + fn erased_serialize_i32(&mut self, v: i32) -> Result; + fn erased_serialize_i64(&mut self, v: i64) -> Result; + fn erased_serialize_i128(&mut self, v: i128) -> Result; + fn erased_serialize_u8(&mut self, v: u8) -> Result; + fn erased_serialize_u16(&mut self, v: u16) -> Result; + fn erased_serialize_u32(&mut self, v: u32) -> Result; + fn erased_serialize_u64(&mut self, v: u64) -> Result; + fn erased_serialize_u128(&mut self, v: u128) -> Result; + fn erased_serialize_f32(&mut self, v: f32) -> Result; + fn erased_serialize_f64(&mut self, v: f64) -> Result; + fn erased_serialize_char(&mut self, v: char) -> Result; + fn erased_serialize_str(&mut self, v: &str) -> Result; + fn erased_serialize_bytes(&mut self, v: &[u8]) -> Result; + fn erased_serialize_none(&mut self) -> Result; + fn erased_serialize_some(&mut self, v: &dyn Serialize) -> Result; + fn erased_serialize_unit(&mut self) -> Result; + fn erased_serialize_unit_struct(&mut self, name: &'static str) -> Result; + fn erased_serialize_unit_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result; + fn erased_serialize_newtype_struct( + &mut self, + name: &'static str, + v: &dyn Serialize, + ) -> Result; + fn erased_serialize_newtype_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + v: &dyn Serialize, + ) -> Result; + fn erased_serialize_seq(&mut self, len: Option) -> Result; + fn erased_serialize_tuple(&mut self, len: usize) -> Result; + fn erased_serialize_tuple_struct( + &mut self, + name: &'static str, + len: usize, + ) -> Result; + fn erased_serialize_tuple_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result; + fn erased_serialize_map(&mut self, len: Option) -> Result; + fn erased_serialize_struct(&mut self, name: &'static str, len: usize) -> Result; + fn erased_serialize_struct_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result; + fn erased_is_human_readable(&self) -> bool; +} + +impl dyn Serializer { + /// Convert any Serde `Serializer` to a trait object. + /// + /// ```rust + /// use erased_serde::{Serialize, Serializer}; + /// use std::collections::BTreeMap as Map; + /// use std::io; + /// + /// fn main() { + /// // Construct some serializers. + /// let json = &mut serde_json::Serializer::new(io::stdout()); + /// let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); + /// + /// // The values in this map are boxed trait objects. Ordinarily this would not + /// // be possible with serde::Serializer because of object safety, but type + /// // erasure makes it possible with erased_serde::Serializer. + /// let mut formats: Map<&str, Box> = Map::new(); + /// formats.insert("json", Box::new(::erase(json))); + /// formats.insert("cbor", Box::new(::erase(cbor))); + /// + /// // These are boxed trait objects as well. Same thing here - type erasure + /// // makes this possible. + /// let mut values: Map<&str, Box> = Map::new(); + /// values.insert("vec", Box::new(vec!["a", "b"])); + /// values.insert("int", Box::new(65536)); + /// + /// // Pick a Serializer out of the formats map. + /// let format = formats.get_mut("json").unwrap(); + /// + /// // Pick a Serialize out of the values map. + /// let value = values.get("vec").unwrap(); + /// + /// // This line prints `["a","b"]` to stdout. + /// value.erased_serialize(format).unwrap(); + /// } + /// ``` + pub fn erase(serializer: S) -> erase::Serializer + where + S: serde::Serializer, + S::Ok: 'static, + { + erase::Serializer { + state: Some(serializer), + } + } +} + +// OK ////////////////////////////////////////////////////////////////////////// + +// Corresponds to the Serializer::Ok associated type. +// +// This struct is exposed to users by invoking methods on the Serialize or +// Serializer trait objects, so we need to make sure they do not hold on to the +// Ok beyond the lifetime of the data in the Any. +// +// We do this by enforcing S::Ok is 'static for every Serializer trait object +// created by the user. +pub struct Ok { + data: Any, +} + +impl Ok { + unsafe fn new(t: T) -> Self { + Ok { + data: unsafe { Any::new(t) }, + } + } + + unsafe fn take(self) -> T { + unsafe { self.data.take() } + } +} + +// IMPL ERASED SERDE FOR SERDE ///////////////////////////////////////////////// + +impl Serialize for T +where + T: ?Sized + serde::Serialize, +{ + fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result { + self.serialize(serializer) + } +} + +mod erase { + pub struct Serializer { + pub(crate) state: Option, + } + + impl Serializer { + pub(crate) fn take(&mut self) -> S { + self.state.take().unwrap() + } + + pub(crate) fn as_ref(&self) -> &S { + self.state.as_ref().unwrap() + } + } +} + +impl Serializer for erase::Serializer +where + T: serde::Serializer, +{ + fn erased_serialize_bool(&mut self, v: bool) -> Result { + unsafe { + self.take() + .serialize_bool(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_i8(&mut self, v: i8) -> Result { + unsafe { + self.take() + .serialize_i8(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_i16(&mut self, v: i16) -> Result { + unsafe { + self.take() + .serialize_i16(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_i32(&mut self, v: i32) -> Result { + unsafe { + self.take() + .serialize_i32(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_i64(&mut self, v: i64) -> Result { + unsafe { + self.take() + .serialize_i64(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_i128(&mut self, v: i128) -> Result { + unsafe { + self.take() + .serialize_i128(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_u8(&mut self, v: u8) -> Result { + unsafe { + self.take() + .serialize_u8(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_u16(&mut self, v: u16) -> Result { + unsafe { + self.take() + .serialize_u16(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_u32(&mut self, v: u32) -> Result { + unsafe { + self.take() + .serialize_u32(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_u64(&mut self, v: u64) -> Result { + unsafe { + self.take() + .serialize_u64(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_u128(&mut self, v: u128) -> Result { + unsafe { + self.take() + .serialize_u128(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_f32(&mut self, v: f32) -> Result { + unsafe { + self.take() + .serialize_f32(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_f64(&mut self, v: f64) -> Result { + unsafe { + self.take() + .serialize_f64(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_char(&mut self, v: char) -> Result { + unsafe { + self.take() + .serialize_char(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_str(&mut self, v: &str) -> Result { + unsafe { + self.take() + .serialize_str(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_bytes(&mut self, v: &[u8]) -> Result { + unsafe { + self.take() + .serialize_bytes(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_none(&mut self) -> Result { + unsafe { + self.take() + .serialize_none() + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_some(&mut self, v: &dyn Serialize) -> Result { + unsafe { + self.take() + .serialize_some(v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_unit(&mut self) -> Result { + unsafe { + self.take() + .serialize_unit() + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_unit_struct(&mut self, name: &'static str) -> Result { + unsafe { + self.take() + .serialize_unit_struct(name) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_unit_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + unsafe { + self.take() + .serialize_unit_variant(name, variant_index, variant) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_newtype_struct( + &mut self, + name: &'static str, + v: &dyn Serialize, + ) -> Result { + unsafe { + self.take() + .serialize_newtype_struct(name, v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_newtype_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + v: &dyn Serialize, + ) -> Result { + unsafe { + self.take() + .serialize_newtype_variant(name, variant_index, variant, v) + .unsafe_map(Ok::new) + .map_err(erase) + } + } + + fn erased_serialize_seq(&mut self, len: Option) -> Result { + unsafe { + self.take() + .serialize_seq(len) + .unsafe_map(Seq::new) + .map_err(erase) + } + } + + fn erased_serialize_tuple(&mut self, len: usize) -> Result { + unsafe { + self.take() + .serialize_tuple(len) + .unsafe_map(Tuple::new) + .map_err(erase) + } + } + + fn erased_serialize_tuple_struct( + &mut self, + name: &'static str, + len: usize, + ) -> Result { + unsafe { + self.take() + .serialize_tuple_struct(name, len) + .unsafe_map(TupleStruct::new) + .map_err(erase) + } + } + + fn erased_serialize_tuple_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + unsafe { + self.take() + .serialize_tuple_variant(name, variant_index, variant, len) + .unsafe_map(TupleVariant::new) + .map_err(erase) + } + } + + fn erased_serialize_map(&mut self, len: Option) -> Result { + unsafe { + self.take() + .serialize_map(len) + .unsafe_map(Map::new) + .map_err(erase) + } + } + + fn erased_serialize_struct(&mut self, name: &'static str, len: usize) -> Result { + unsafe { + self.take() + .serialize_struct(name, len) + .unsafe_map(Struct::new) + .map_err(erase) + } + } + + fn erased_serialize_struct_variant( + &mut self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + unsafe { + self.take() + .serialize_struct_variant(name, variant_index, variant, len) + .unsafe_map(StructVariant::new) + .map_err(erase) + } + } + + fn erased_is_human_readable(&self) -> bool { + self.as_ref().is_human_readable() + } +} + +// IMPL SERDE FOR ERASED SERDE ///////////////////////////////////////////////// + +/// Serialize the given type-erased serializable value. +/// +/// This can be used to implement `serde::Serialize` for trait objects that have +/// `erased_serde::Serialize` as a supertrait. +/// +/// ``` +/// trait Event: erased_serde::Serialize { +/// /* ... */ +/// } +/// +/// impl<'a> serde::Serialize for dyn Event + 'a { +/// fn serialize(&self, serializer: S) -> Result +/// where S: serde::Serializer +/// { +/// erased_serde::serialize(self, serializer) +/// } +/// } +/// ``` +/// +/// Since this is reasonably common, the `serialize_trait_object!` macro +/// generates such a Serialize impl. +/// +/// ``` +/// use erased_serde::serialize_trait_object; +/// # +/// # trait Event: erased_serde::Serialize {} +/// +/// serialize_trait_object!(Event); +/// ``` +pub fn serialize(value: &T, serializer: S) -> Result +where + T: ?Sized + Serialize, + S: serde::Serializer, +{ + let mut erased = erase::Serializer { + state: Some(serializer), + }; + unsafe { + value + .erased_serialize(&mut erased) + .unsafe_map(Ok::take) + .map_err(unerase) + } +} + +serialize_trait_object!(Serialize); + +macro_rules! impl_serializer_for_trait_object { + ($ty:ty) => { + impl<'a> serde::Serializer for $ty { + type Ok = Ok; + type Error = Error; + type SerializeSeq = Seq<'a>; + type SerializeTuple = Tuple<'a>; + type SerializeTupleStruct = TupleStruct<'a>; + type SerializeTupleVariant = TupleVariant<'a>; + type SerializeMap = Map<'a>; + type SerializeStruct = Struct<'a>; + type SerializeStructVariant = StructVariant<'a>; + + fn serialize_bool(self, v: bool) -> Result { + self.erased_serialize_bool(v) + } + + fn serialize_i8(self, v: i8) -> Result { + self.erased_serialize_i8(v) + } + + fn serialize_i16(self, v: i16) -> Result { + self.erased_serialize_i16(v) + } + + fn serialize_i32(self, v: i32) -> Result { + self.erased_serialize_i32(v) + } + + fn serialize_i64(self, v: i64) -> Result { + self.erased_serialize_i64(v) + } + + fn serialize_i128(self, v: i128) -> Result { + self.erased_serialize_i128(v) + } + + fn serialize_u8(self, v: u8) -> Result { + self.erased_serialize_u8(v) + } + + fn serialize_u16(self, v: u16) -> Result { + self.erased_serialize_u16(v) + } + + fn serialize_u32(self, v: u32) -> Result { + self.erased_serialize_u32(v) + } + + fn serialize_u64(self, v: u64) -> Result { + self.erased_serialize_u64(v) + } + + fn serialize_u128(self, v: u128) -> Result { + self.erased_serialize_u128(v) + } + + fn serialize_f32(self, v: f32) -> Result { + self.erased_serialize_f32(v) + } + + fn serialize_f64(self, v: f64) -> Result { + self.erased_serialize_f64(v) + } + + fn serialize_char(self, v: char) -> Result { + self.erased_serialize_char(v) + } + + fn serialize_str(self, v: &str) -> Result { + self.erased_serialize_str(v) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + self.erased_serialize_bytes(v) + } + + fn serialize_none(self) -> Result { + self.erased_serialize_none() + } + + fn serialize_some(self, v: &T) -> Result + where + T: ?Sized + serde::Serialize, + { + self.erased_serialize_some(&v) + } + + fn serialize_unit(self) -> Result { + self.erased_serialize_unit() + } + + fn serialize_unit_struct(self, name: &'static str) -> Result { + self.erased_serialize_unit_struct(name) + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + self.erased_serialize_unit_variant(name, variant_index, variant) + } + + fn serialize_newtype_struct(self, name: &'static str, v: &T) -> Result + where + T: ?Sized + serde::Serialize, + { + self.erased_serialize_newtype_struct(name, &v) + } + + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + v: &T, + ) -> Result + where + T: ?Sized + serde::Serialize, + { + self.erased_serialize_newtype_variant(name, variant_index, variant, &v) + } + + fn serialize_seq(self, len: Option) -> Result, Error> { + self.erased_serialize_seq(len) + } + + fn serialize_tuple(self, len: usize) -> Result, Error> { + self.erased_serialize_tuple(len) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result, Error> { + self.erased_serialize_tuple_struct(name, len) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result, Error> { + self.erased_serialize_tuple_variant(name, variant_index, variant, len) + } + + fn serialize_map(self, len: Option) -> Result, Error> { + self.erased_serialize_map(len) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result, Error> { + self.erased_serialize_struct(name, len) + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result, Error> { + self.erased_serialize_struct_variant(name, variant_index, variant, len) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + unreachable!() + } + + fn is_human_readable(&self) -> bool { + self.erased_is_human_readable() + } + } + }; +} + +impl_serializer_for_trait_object!(&'a mut (dyn Serializer + '_)); +impl_serializer_for_trait_object!(&'a mut (dyn Serializer + Send + '_)); +impl_serializer_for_trait_object!(&'a mut (dyn Serializer + Sync + '_)); +impl_serializer_for_trait_object!(&'a mut (dyn Serializer + Send + Sync + '_)); + +pub struct Seq<'a> { + data: Any, + serialize_element: unsafe fn(&mut Any, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> Seq<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeSeq, + { + Seq { + data: unsafe { Any::new(data) }, + serialize_element: { + unsafe fn serialize_element( + data: &mut Any, + v: &dyn Serialize, + ) -> Result<(), Error> + where + T: serde::ser::SerializeSeq, + { + unsafe { data.view::().serialize_element(v).map_err(erase) } + } + serialize_element:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeSeq, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeSeq for Seq<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_element)(&mut self.data, &value) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +pub struct Tuple<'a> { + data: Any, + serialize_element: unsafe fn(&mut Any, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> Tuple<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeTuple, + { + Tuple { + data: unsafe { Any::new(data) }, + serialize_element: { + unsafe fn serialize_element( + data: &mut Any, + v: &dyn Serialize, + ) -> Result<(), Error> + where + T: serde::ser::SerializeTuple, + { + unsafe { data.view::().serialize_element(v).map_err(erase) } + } + serialize_element:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeTuple, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeTuple for Tuple<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_element)(&mut self.data, &value) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +pub struct TupleStruct<'a> { + data: Any, + serialize_field: unsafe fn(&mut Any, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> TupleStruct<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeTupleStruct, + { + TupleStruct { + data: unsafe { Any::new(data) }, + serialize_field: { + unsafe fn serialize_field(data: &mut Any, v: &dyn Serialize) -> Result<(), Error> + where + T: serde::ser::SerializeTupleStruct, + { + unsafe { data.view::().serialize_field(v).map_err(erase) } + } + serialize_field:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeTupleStruct, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeTupleStruct for TupleStruct<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_field)(&mut self.data, &value) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +pub struct TupleVariant<'a> { + data: Any, + serialize_field: unsafe fn(&mut Any, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> TupleVariant<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeTupleVariant, + { + TupleVariant { + data: unsafe { Any::new(data) }, + serialize_field: { + unsafe fn serialize_field(data: &mut Any, v: &dyn Serialize) -> Result<(), Error> + where + T: serde::ser::SerializeTupleVariant, + { + unsafe { data.view::().serialize_field(v).map_err(erase) } + } + serialize_field:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeTupleVariant, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeTupleVariant for TupleVariant<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_field)(&mut self.data, &value) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +pub struct Map<'a> { + data: Any, + serialize_key: unsafe fn(&mut Any, &dyn Serialize) -> Result<(), Error>, + serialize_value: unsafe fn(&mut Any, &dyn Serialize) -> Result<(), Error>, + serialize_entry: unsafe fn(&mut Any, &dyn Serialize, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> Map<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeMap, + { + Map { + data: unsafe { Any::new(data) }, + serialize_key: { + unsafe fn serialize_key(data: &mut Any, v: &dyn Serialize) -> Result<(), Error> + where + T: serde::ser::SerializeMap, + { + unsafe { data.view::().serialize_key(v).map_err(erase) } + } + serialize_key:: + }, + serialize_value: { + unsafe fn serialize_value(data: &mut Any, v: &dyn Serialize) -> Result<(), Error> + where + T: serde::ser::SerializeMap, + { + unsafe { data.view::().serialize_value(v).map_err(erase) } + } + serialize_value:: + }, + serialize_entry: { + unsafe fn serialize_entry( + data: &mut Any, + k: &dyn Serialize, + v: &dyn Serialize, + ) -> Result<(), Error> + where + T: serde::ser::SerializeMap, + { + unsafe { data.view::().serialize_entry(k, v).map_err(erase) } + } + serialize_entry:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeMap, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeMap for Map<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_key)(&mut self.data, &key) } + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_value)(&mut self.data, &value) } + } + + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), Error> + where + K: ?Sized + serde::Serialize, + V: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_entry)(&mut self.data, &key, &value) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +pub struct Struct<'a> { + data: Any, + serialize_field: unsafe fn(&mut Any, &'static str, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> Struct<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeStruct, + { + Struct { + data: unsafe { Any::new(data) }, + serialize_field: { + unsafe fn serialize_field( + data: &mut Any, + k: &'static str, + v: &dyn Serialize, + ) -> Result<(), Error> + where + T: serde::ser::SerializeStruct, + { + unsafe { data.view::().serialize_field(k, v).map_err(erase) } + } + serialize_field:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeStruct, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeStruct for Struct<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, name: &'static str, field: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_field)(&mut self.data, name, &field) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +pub struct StructVariant<'a> { + data: Any, + serialize_field: unsafe fn(&mut Any, &'static str, &dyn Serialize) -> Result<(), Error>, + end: unsafe fn(Any) -> Result, + lifetime: PhantomData<&'a dyn Serializer>, +} + +impl<'a> StructVariant<'a> { + unsafe fn new(data: T) -> Self + where + T: serde::ser::SerializeStructVariant, + { + StructVariant { + data: unsafe { Any::new(data) }, + serialize_field: { + unsafe fn serialize_field( + data: &mut Any, + k: &'static str, + v: &dyn Serialize, + ) -> Result<(), Error> + where + T: serde::ser::SerializeStructVariant, + { + unsafe { data.view::().serialize_field(k, v).map_err(erase) } + } + serialize_field:: + }, + end: { + unsafe fn end(data: Any) -> Result + where + T: serde::ser::SerializeStructVariant, + { + unsafe { data.take::().end().unsafe_map(Ok::new).map_err(erase) } + } + end:: + }, + lifetime: PhantomData, + } + } +} + +impl<'a> SerializeStructVariant for StructVariant<'a> { + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, name: &'static str, field: &T) -> Result<(), Error> + where + T: ?Sized + serde::Serialize, + { + unsafe { (self.serialize_field)(&mut self.data, name, &field) } + } + + fn end(self) -> Result { + unsafe { (self.end)(self.data) } + } +} + +// IMPL ERASED SERDE FOR ERASED SERDE ////////////////////////////////////////// + +macro_rules! deref_erased_serializer { + ($($imp:tt)+) => { + impl $($imp)+ { + fn erased_serialize_bool(&mut self, v: bool) -> Result { + (**self).erased_serialize_bool(v) + } + + fn erased_serialize_i8(&mut self, v: i8) -> Result { + (**self).erased_serialize_i8(v) + } + + fn erased_serialize_i16(&mut self, v: i16) -> Result { + (**self).erased_serialize_i16(v) + } + + fn erased_serialize_i32(&mut self, v: i32) -> Result { + (**self).erased_serialize_i32(v) + } + + fn erased_serialize_i64(&mut self, v: i64) -> Result { + (**self).erased_serialize_i64(v) + } + + fn erased_serialize_i128(&mut self, v: i128) -> Result { + (**self).erased_serialize_i128(v) + } + + fn erased_serialize_u8(&mut self, v: u8) -> Result { + (**self).erased_serialize_u8(v) + } + + fn erased_serialize_u16(&mut self, v: u16) -> Result { + (**self).erased_serialize_u16(v) + } + + fn erased_serialize_u32(&mut self, v: u32) -> Result { + (**self).erased_serialize_u32(v) + } + + fn erased_serialize_u64(&mut self, v: u64) -> Result { + (**self).erased_serialize_u64(v) + } + + fn erased_serialize_u128(&mut self, v: u128) -> Result { + (**self).erased_serialize_u128(v) + } + + fn erased_serialize_f32(&mut self, v: f32) -> Result { + (**self).erased_serialize_f32(v) + } + + fn erased_serialize_f64(&mut self, v: f64) -> Result { + (**self).erased_serialize_f64(v) + } + + fn erased_serialize_char(&mut self, v: char) -> Result { + (**self).erased_serialize_char(v) + } + + fn erased_serialize_str(&mut self, v: &str) -> Result { + (**self).erased_serialize_str(v) + } + + fn erased_serialize_bytes(&mut self, v: &[u8]) -> Result { + (**self).erased_serialize_bytes(v) + } + + fn erased_serialize_none(&mut self) -> Result { + (**self).erased_serialize_none() + } + + fn erased_serialize_some(&mut self, v: &dyn Serialize) -> Result { + (**self).erased_serialize_some(v) + } + + fn erased_serialize_unit(&mut self) -> Result { + (**self).erased_serialize_unit() + } + + fn erased_serialize_unit_struct(&mut self, name: &'static str) -> Result { + (**self).erased_serialize_unit_struct(name) + } + + fn erased_serialize_unit_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str) -> Result { + (**self).erased_serialize_unit_variant(name, variant_index, variant) + } + + fn erased_serialize_newtype_struct(&mut self, name: &'static str, v: &dyn Serialize) -> Result { + (**self).erased_serialize_newtype_struct(name, v) + } + + fn erased_serialize_newtype_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str, v: &dyn Serialize) -> Result { + (**self).erased_serialize_newtype_variant(name, variant_index, variant, v) + } + + fn erased_serialize_seq(&mut self, len: Option) -> Result { + (**self).erased_serialize_seq(len) + } + + fn erased_serialize_tuple(&mut self, len: usize) -> Result { + (**self).erased_serialize_tuple(len) + } + + fn erased_serialize_tuple_struct(&mut self, name: &'static str, len: usize) -> Result { + (**self).erased_serialize_tuple_struct(name, len) + } + + fn erased_serialize_tuple_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result { + (**self).erased_serialize_tuple_variant(name, variant_index, variant, len) + } + + fn erased_serialize_map(&mut self, len: Option) -> Result { + (**self).erased_serialize_map(len) + } + + fn erased_serialize_struct(&mut self, name: &'static str, len: usize) -> Result { + (**self).erased_serialize_struct(name, len) + } + + fn erased_serialize_struct_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result { + (**self).erased_serialize_struct_variant(name, variant_index, variant, len) + } + + fn erased_is_human_readable(&self) -> bool { + (**self).erased_is_human_readable() + } + } + }; +} + +deref_erased_serializer!(<'a> Serializer for Box); +deref_erased_serializer!(<'a> Serializer for Box); +deref_erased_serializer!(<'a> Serializer for Box); +deref_erased_serializer!(<'a> Serializer for Box); +deref_erased_serializer!(<'a, T: ?Sized + Serializer> Serializer for &'a mut T); + +// ERROR /////////////////////////////////////////////////////////////////////// + +fn erase(e: E) -> Error +where + E: Display, +{ + serde::ser::Error::custom(e) +} + +fn unerase(e: Error) -> E +where + E: serde::ser::Error, +{ + E::custom(e) +} + +// TEST //////////////////////////////////////////////////////////////////////// + +#[cfg(test)] +mod tests { + use super::*; + use crate::alloc::{vec, Vec}; + use serde_derive::Serialize; + + fn test_json(t: T) + where + T: serde::Serialize, + { + let expected = serde_json::to_vec(&t).unwrap(); + + // test borrowed trait object + { + let obj: &dyn Serialize = &t; + + let mut buf = Vec::new(); + + { + let mut ser = serde_json::Serializer::new(&mut buf); + let ser: &mut dyn Serializer = &mut ::erase(&mut ser); + + obj.erased_serialize(ser).unwrap(); + } + + assert_eq!(buf, expected); + } + + // test boxed trait object + { + let obj: Box = Box::new(t); + + let mut buf = Vec::new(); + + { + let mut ser = serde_json::Serializer::new(&mut buf); + let mut ser: Box = Box::new(::erase(&mut ser)); + + obj.erased_serialize(&mut ser).unwrap(); + } + + assert_eq!(buf, expected); + } + } + + #[test] + fn test_vec() { + test_json(vec!["a", "b"]); + } + + #[test] + fn test_struct() { + #[derive(Serialize)] + struct S { + f: usize, + } + + test_json(S { f: 256 }); + } + + #[test] + fn test_enum() { + #[derive(Serialize)] + enum E { + Unit, + Newtype(bool), + Tuple(bool, bool), + Struct { t: bool, f: bool }, + } + + test_json(E::Unit); + test_json(E::Newtype(true)); + test_json(E::Tuple(true, false)); + test_json(E::Struct { t: true, f: false }); + } + + #[test] + fn assert_serialize() { + fn assert() {} + + assert::<&dyn Serialize>(); + assert::<&(dyn Serialize + Send)>(); + assert::<&(dyn Serialize + Sync)>(); + assert::<&(dyn Serialize + Send + Sync)>(); + assert::<&(dyn Serialize + Sync + Send)>(); + assert::>(); + assert::>(); + + assert::>(); + assert::>(); + assert::>(); + assert::>(); + assert::>(); + assert::>>(); + assert::>>(); + } + + #[test] + fn assert_serializer() { + fn assert() {} + + assert::<&mut dyn Serializer>(); + assert::<&mut (dyn Serializer + Send)>(); + assert::<&mut (dyn Serializer + Sync)>(); + assert::<&mut (dyn Serializer + Send + Sync)>(); + assert::<&mut (dyn Serializer + Sync + Send)>(); + } +} diff --git a/vendor/erased-serde/tests/compiletest.rs b/vendor/erased-serde/tests/compiletest.rs new file mode 100644 index 000000000..7974a6249 --- /dev/null +++ b/vendor/erased-serde/tests/compiletest.rs @@ -0,0 +1,7 @@ +#[rustversion::attr(not(nightly), ignore)] +#[cfg_attr(miri, ignore)] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/vendor/erased-serde/tests/readme.rs b/vendor/erased-serde/tests/readme.rs new file mode 100644 index 000000000..e502e6ca0 --- /dev/null +++ b/vendor/erased-serde/tests/readme.rs @@ -0,0 +1,57 @@ +// Please also update README.md when making changes to this code. + +use erased_serde::{Deserializer, Serialize, Serializer}; +use std::collections::BTreeMap as Map; +use std::io; + +#[test] +fn serialization() { + // Construct some serializers. + let json = &mut serde_json::Serializer::new(io::stdout()); + let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); + + // The values in this map are boxed trait objects. Ordinarily this would not + // be possible with serde::Serializer because of object safety, but type + // erasure makes it possible with erased_serde::Serializer. + let mut formats: Map<&str, Box> = Map::new(); + formats.insert("json", Box::new(::erase(json))); + formats.insert("cbor", Box::new(::erase(cbor))); + + // These are boxed trait objects as well. Same thing here - type erasure + // makes this possible. + let mut values: Map<&str, Box> = Map::new(); + values.insert("vec", Box::new(vec!["a", "b"])); + values.insert("int", Box::new(65536)); + + // Pick a Serializer out of the formats map. + let format = formats.get_mut("json").unwrap(); + + // Pick a Serialize out of the values map. + let value = values.get("vec").unwrap(); + + // This line prints `["a","b"]` to stdout. + value.erased_serialize(format).unwrap(); +} + +#[test] +fn deserialization() { + static JSON: &[u8] = br#"{"A": 65, "B": 66}"#; + static CBOR: &[u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66]; + + // Construct some deserializers. + let json = &mut serde_json::Deserializer::from_slice(JSON); + let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR); + + // The values in this map are boxed trait objects, which is not possible + // with the normal serde::Deserializer because of object safety. + let mut formats: Map<&str, Box> = Map::new(); + formats.insert("json", Box::new(::erase(json))); + formats.insert("cbor", Box::new(::erase(cbor))); + + // Pick a Deserializer out of the formats map. + let format = formats.get_mut("json").unwrap(); + + let data: Map = erased_serde::deserialize(format).unwrap(); + + println!("{}", data["A"] + data["B"]); +} diff --git a/vendor/erased-serde/tests/traitobject.rs b/vendor/erased-serde/tests/traitobject.rs new file mode 100644 index 000000000..03919f346 --- /dev/null +++ b/vendor/erased-serde/tests/traitobject.rs @@ -0,0 +1,9 @@ +use erased_serde::serialize_trait_object; + +pub trait MyTrait: erased_serde::Serialize {} + +serialize_trait_object!(MyTrait); + +pub trait MyGenericTrait<'a, T>: erased_serde::Serialize {} + +serialize_trait_object!(<'a, T> MyGenericTrait<'a, T>); diff --git a/vendor/erased-serde/tests/ui/missing-supertrait.rs b/vendor/erased-serde/tests/ui/missing-supertrait.rs new file mode 100644 index 000000000..09830d6d5 --- /dev/null +++ b/vendor/erased-serde/tests/ui/missing-supertrait.rs @@ -0,0 +1,7 @@ +use erased_serde::serialize_trait_object; + +pub trait MyTrait {} + +serialize_trait_object!(MyTrait); + +fn main() {} diff --git a/vendor/erased-serde/tests/ui/missing-supertrait.stderr b/vendor/erased-serde/tests/ui/missing-supertrait.stderr new file mode 100644 index 000000000..50dca8f65 --- /dev/null +++ b/vendor/erased-serde/tests/ui/missing-supertrait.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `__T: serde::ser::Serialize` is not satisfied + --> tests/ui/missing-supertrait.rs:5:1 + | +5 | serialize_trait_object!(MyTrait); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `serde::ser::Serialize` is not implemented for `__T` + | + = note: required for `__T` to implement `erased_serde::Serialize` +note: required by a bound in `require_erased_serialize_impl` + --> src/private.rs + | + | pub fn require_erased_serialize_impl() + | ----------------------------- required by a bound in this function + | where + | T: ?Sized + crate::Serialize, + | ^^^^^^^^^^^^^^^^ required by this bound in `require_erased_serialize_impl` + = note: this error originates in the macro `$crate::__internal_serialize_trait_object` which comes from the expansion of the macro `serialize_trait_object` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting this bound + | +5 | serialize_trait_object!(MyTrait + erased_serde::__private::serde::ser::Serialize); + | ++++++++++++++++++++++++++++++++++++++++++++++++ -- cgit v1.2.3