use std::collections::HashMap; use std::error::Error; use std::fmt::Debug; use serde::{Deserialize, Serialize, Serializer}; use serde::de::DeserializeSeed; use serde_flexitos::{MapRegistry, Registry, serialize_trait_object}; use serde_flexitos::de::{DeserializeMapWith, DeserializeTraitObject, DeserializeVecWithTraitObject}; use serde_flexitos::ser::require_erased_serialize_impl; // Example trait pub trait ExampleObj: erased_serde::Serialize + Debug { fn id(&self) -> &'static str; } // Example trait implementations #[derive(Clone, Serialize, Deserialize, Debug)] struct Foo(String); impl Foo { const ID: &'static str = "Foo"; } impl ExampleObj for Foo { fn id(&self) -> &'static str { Self::ID } } #[derive(Clone, Serialize, Deserialize, Debug)] struct Bar(usize); impl Bar { const ID: &'static str = "Bar"; } impl ExampleObj for Bar { fn id(&self) -> &'static str { Self::ID } } // Serialize implementation impl<'a> Serialize for dyn ExampleObj + 'a { fn serialize(&self, serializer: S) -> Result { const fn __check_erased_serialize_supertrait() { require_erased_serialize_impl::(); } serialize_trait_object(serializer, self.id(), self) } } // Run serialization roundtrips fn main() -> Result<(), Box> { let mut registry = MapRegistry::::new("ExampleObj"); registry.register(Foo::ID, |d| Ok(Box::new(erased_serde::deserialize::(d)?))); registry.register(Bar::ID, |d| Ok(Box::new(erased_serde::deserialize::(d)?))); let foo = Foo("A".to_string()); let bar = Bar(0); { // `Box` serialization roundtrip let example: Box = Box::new(foo.clone()); let json = serde_json::to_string(example.as_ref())?; println!("`Box` serialized: {}", json); let deserialize = DeserializeTraitObject(®istry); let mut deserializer = serde_json::Deserializer::new(serde_json::de::StrRead::new(&json)); let roundtrip: Box = deserialize.deserialize(&mut deserializer)?; println!("`Box` deserialized: {:?}", roundtrip); } { // `Vec>` serialization roundtrip let examples: Vec> = vec![Box::new(foo.clone()), Box::new(bar.clone())]; let json = serde_json::to_string(&examples)?; println!("`Vec>` serialized: {}", json); let deserialize = DeserializeVecWithTraitObject(®istry); let mut deserializer = serde_json::Deserializer::new(serde_json::de::StrRead::new(&json)); let roundtrip: Vec> = deserialize.deserialize(&mut deserializer)?; println!("`Vec>` deserialized: {:?}", roundtrip); } { // `HashMap>` serialization roundtrip let mut examples = HashMap::>::new(); examples.insert("foo".to_string(), Box::new(foo.clone())); examples.insert("bar".to_string(), Box::new(bar.clone())); let json = serde_json::to_string(&examples)?; println!("`HashMap>` serialized: {}", json); let deserialize = DeserializeMapWith::trait_object_value(®istry); let mut deserializer = serde_json::Deserializer::new(serde_json::de::StrRead::new(&json)); let roundtrip: HashMap::> = deserialize.deserialize(&mut deserializer)?; println!("`HashMap>` deserialized: {:?}", roundtrip); } // This example uses `DeserializeTraitObject`, `DeserializeVecWithTraitObject`, and `DeserializeMapWith`, which // implement `DeserializeSeed` instead of `Deserialize`. // // If you need to deserialize trait objects inside your custom data structures, this will require a lot of extra // boilerplate, due to `serde_derive` not deriving `DeserializeSeed` implementations. See // https://stackoverflow.com/a/75902605 for an example on how to write these implementations. Ok(()) }