diff --git a/libafl_bolts/src/serdeany.rs b/libafl_bolts/src/serdeany.rs index 5d8d90832f..6eb429318f 100644 --- a/libafl_bolts/src/serdeany.rs +++ b/libafl_bolts/src/serdeany.rs @@ -4,6 +4,7 @@ use alloc::boxed::Box; use core::{any::Any, fmt::Debug}; use serde::{de::DeserializeSeed, Deserialize, Deserializer, Serialize, Serializer}; +pub use serdeany_registry::*; /// A (de)serializable Any trait pub trait SerdeAny: Any + erased_serde::Serialize + Debug { @@ -63,582 +64,579 @@ where /// Creates the [`serde`] registry for serialization and deserialization of [`SerdeAny`]. /// Each element needs to be registered so that it can be deserialized. -#[macro_export] -macro_rules! create_serde_registry_for_trait { - ($mod_name:ident, $trait_name:path) => { - /// A [`crate::serdeany`] module. - pub mod $mod_name { +pub mod serdeany_registry { - use alloc::boxed::Box; - use core::{any::TypeId, fmt}; + use alloc::boxed::Box; + use core::{any::TypeId, fmt}; - use hashbrown::{ - hash_map::{Keys, Values, ValuesMut}, - HashMap, - }; - use postcard; - use serde::{Deserialize, Serialize}; - use $crate::{ - anymap::{pack_type_id, unpack_type_id}, - hash_std, - serdeany::{DeserializeCallback, DeserializeCallbackSeed}, - Error, - }; - - /// Visitor object used internally for the [`crate::serdeany::SerdeAny`] registry. - #[derive(Debug)] - pub struct BoxDynVisitor {} - #[allow(unused_qualifications)] - impl<'de> serde::de::Visitor<'de> for BoxDynVisitor { - type Value = Box; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Expecting a serialized trait object") - } - - fn visit_seq(self, mut visitor: V) -> Result - where - V: serde::de::SeqAccess<'de>, - { - let id: u128 = visitor.next_element()?.unwrap(); - let cb = unsafe { - *REGISTRY - .deserializers - .as_ref() - .expect("Empty types registry") - .get(&id) - .expect("Cannot deserialize an unregistered type") - }; - let seed = DeserializeCallbackSeed:: { cb }; - let obj: Self::Value = visitor.next_element_seed(seed)?.unwrap(); - Ok(obj) - } - } - - #[allow(unused_qualifications)] - struct Registry { - deserializers: Option>>, - finalized: bool, - } - - #[allow(unused_qualifications)] - impl Registry { - pub fn register(&mut self) - where - T: $trait_name + Serialize + serde::de::DeserializeOwned, - { - assert!(!self.finalized, "Registry is already finalized!"); - - let deserializers = self.deserializers.get_or_insert_with(HashMap::default); - deserializers.insert(unpack_type_id(TypeId::of::()), |de| { - Ok(Box::new(erased_serde::deserialize::(de)?)) - }); - } - - pub fn finalize(&mut self) { - self.finalized = true; - } - } - - static mut REGISTRY: Registry = Registry { - deserializers: None, - finalized: false, - }; - - /// This sugar must be used to register all the structs which - /// have trait objects that can be serialized and deserialized in the program - #[derive(Debug)] - pub struct RegistryBuilder {} - - #[allow(unused_qualifications)] - impl RegistryBuilder { - /// Register a given struct type for trait object (de)serialization - /// - /// # Safety - /// This may never be called concurrently or at the same time as `finalize`. - /// It dereferences the `REGISTRY` hashmap and adds the given type to it. - pub unsafe fn register() - where - T: $trait_name + Serialize + serde::de::DeserializeOwned, - { - unsafe { - REGISTRY.register::(); - } - } - - /// Finalize the registry, no more registrations are allowed after this call - /// - /// # Safety - /// This may never be called concurrently or at the same time as `register`. - /// It dereferences the `REGISTRY` hashmap and adds the given type to it. - pub fn finalize() { - unsafe { - REGISTRY.finalize(); - } - } - } - - /// A (de)serializable anymap containing (de)serializable trait objects registered - /// in the registry - #[allow(clippy::unsafe_derive_deserialize)] - #[derive(Debug, Serialize, Deserialize)] - pub struct SerdeAnyMap { - map: HashMap>, - } - - // Cloning by serializing and deserializing. It ain't fast, but it's honest work. - // We unwrap postcard, it should not have a reason to fail. - impl Clone for SerdeAnyMap { - fn clone(&self) -> Self { - let serialized = postcard::to_allocvec(&self).unwrap(); - postcard::from_bytes(&serialized).unwrap() - } - } - - /* - #[cfg(feature = "anymap_debug")] - impl fmt::Debug for SerdeAnyMap { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let json = serde_json::to_string(&self); - write!(f, "SerdeAnyMap: [{:?}]", json) - } - } - - #[cfg(not(feature = "anymap_debug"))] - impl fmt::Debug for SerdeAnyMap { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "SerdeAnymap with {} elements", self.len()) - } - }*/ - - #[allow(unused_qualifications)] - impl SerdeAnyMap { - /// Get an element from the map. - #[must_use] - #[inline] - pub fn get(&self) -> Option<&T> - where - T: $trait_name, - { - self.map - .get(&unpack_type_id(TypeId::of::())) - .map(|x| x.as_ref().as_any().downcast_ref::().unwrap()) - } - - /// Get a mutable borrow for an element in the map. - #[must_use] - #[inline] - pub fn get_mut(&mut self) -> Option<&mut T> - where - T: $trait_name, - { - self.map - .get_mut(&unpack_type_id(TypeId::of::())) - .map(|x| x.as_mut().as_any_mut().downcast_mut::().unwrap()) - } - - /// Remove an element in the map. Returns the removed element. - #[must_use] - #[inline] - pub fn remove(&mut self) -> Option> - where - T: $trait_name, - { - self.map - .remove(&unpack_type_id(TypeId::of::())) - .map(|x| x.as_any_boxed().downcast::().unwrap()) - } - - /// Insert an element into the map. - #[inline] - pub fn insert(&mut self, t: T) - where - T: $trait_name, - { - self.insert_boxed(Box::new(t)); - } - - /// Insert a boxed element into the map. - #[inline] - pub fn insert_boxed(&mut self, t: Box) - where - T: $trait_name, - { - let id = unpack_type_id(TypeId::of::()); - assert!( - unsafe { - REGISTRY - .deserializers - .as_ref() - .expect("Empty types registry") - .get(&id) - .is_some() - }, - "Type {} was inserted without registration! Call {}::register or use serde_autoreg.", - core::any::type_name::(), - core::any::type_name::() - ); - self.map.insert(id, t); - } - - /// Returns the count of elements in this map. - #[must_use] - #[inline] - pub fn len(&self) -> usize { - self.map.len() - } - - /// Returns `true` if this map is empty. - #[must_use] - pub fn is_empty(&self) -> bool { - self.map.is_empty() - } - - /// Returns if the map contains the given type. - #[must_use] - #[inline] - pub fn contains(&self) -> bool - where - T: $trait_name, - { - self.map.contains_key(&unpack_type_id(TypeId::of::())) - } - - /// Create a new [`SerdeAnyMap`]. - #[must_use] - pub fn new() -> Self { - SerdeAnyMap { - map: HashMap::default(), - } - } - } - - impl Default for SerdeAnyMap { - fn default() -> Self { - Self::new() - } - } - - /// A serializable [`HashMap`] wrapper for [`crate::serdeany::SerdeAny`] types, addressable by name. - #[allow(clippy::unsafe_derive_deserialize)] - #[allow(unused_qualifications)] - #[derive(Debug, Serialize, Deserialize)] - pub struct NamedSerdeAnyMap { - map: HashMap>>, - } - - // Cloning by serializing and deserializing. It ain't fast, but it's honest work. - // We unwrap postcard, it should not have a reason to fail. - impl Clone for NamedSerdeAnyMap { - fn clone(&self) -> Self { - let serialized = postcard::to_allocvec(&self).unwrap(); - postcard::from_bytes(&serialized).unwrap() - } - } - - #[allow(unused_qualifications)] - impl NamedSerdeAnyMap { - /// Get an element by name - #[must_use] - #[inline] - pub fn get(&self, name: &str) -> Option<&T> - where - T: $trait_name, - { - match self.map.get(&unpack_type_id(TypeId::of::())) { - None => None, - Some(h) => h - .get(&hash_std(name.as_bytes())) - .map(|x| x.as_any().downcast_ref::().unwrap()), - } - } - - /// Get an element of a given type contained in this map by [`TypeId`]. - #[must_use] - #[allow(unused_qualifications)] - #[inline] - pub fn by_typeid(&self, name: &str, typeid: &TypeId) -> Option<&dyn $trait_name> { - match self.map.get(&unpack_type_id(*typeid)) { - None => None, - Some(h) => h - .get(&hash_std(name.as_bytes())) - .map(AsRef::as_ref), - } - } - - /// Get an element of a given type contained in this map by [`TypeId`], as mut. - #[must_use] - #[inline] - pub fn get_mut(&mut self, name: &str) -> Option<&mut T> - where - T: $trait_name, - { - match self.map.get_mut(&unpack_type_id(TypeId::of::())) { - None => None, - Some(h) => h - .get_mut(&hash_std(name.as_bytes())) - .map(|x| x.as_any_mut().downcast_mut::().unwrap()), - } - } - - /// Get an element of a given type contained in this map by [`TypeId`], as mut. - #[must_use] - #[inline] - pub fn by_typeid_mut( - &mut self, - name: &str, - typeid: &TypeId, - ) -> Option<&mut dyn $trait_name> { - match self.map.get_mut(&unpack_type_id(*typeid)) { - None => None, - Some(h) => h - .get_mut(&hash_std(name.as_bytes())) - .map(AsMut::as_mut), - } - } - - /// Get all elements of a type contained in this map. - #[must_use] - #[allow(unused_qualifications)] - #[inline] - pub fn get_all( - &self, - ) -> Option< - core::iter::Map< - Values<'_, u64, Box>, - fn(&Box) -> &T, - >, - > - where - T: $trait_name, - { - #[allow(clippy::manual_map)] - match self.map.get(&unpack_type_id(TypeId::of::())) { - None => None, - Some(h) => { - Some(h.values().map(|x| x.as_any().downcast_ref::().unwrap())) - } - } - } - - /// Get all elements of a given type contained in this map by [`TypeId`]. - #[must_use] - #[allow(unused_qualifications)] - #[inline] - pub fn all_by_typeid( - &self, - typeid: &TypeId, - ) -> Option< - core::iter::Map< - Values<'_, u64, Box>, - fn(&Box) -> &dyn $trait_name, - >, - > { - #[allow(clippy::manual_map)] - match self.map.get(&unpack_type_id(*typeid)) { - None => None, - Some(h) => Some(h.values().map(|x| x.as_ref())), - } - } - - /// Get all elements contained in this map, as mut. - #[inline] - #[allow(unused_qualifications)] - pub fn get_all_mut( - &mut self, - ) -> Option< - core::iter::Map< - ValuesMut<'_, u64, Box>, - fn(&mut Box) -> &mut T, - >, - > - where - T: $trait_name, - { - #[allow(clippy::manual_map)] - match self.map.get_mut(&unpack_type_id(TypeId::of::())) { - None => None, - Some(h) => Some( - h.values_mut() - .map(|x| x.as_any_mut().downcast_mut::().unwrap()), - ), - } - } - - /// Get all [`TypeId`]`s` contained in this map, as mut. - #[inline] - #[allow(unused_qualifications)] - pub fn all_by_typeid_mut( - &mut self, - typeid: &TypeId, - ) -> Option< - core::iter::Map< - ValuesMut<'_, u64, Box>, - fn(&mut Box) -> &mut dyn $trait_name, - >, - > { - #[allow(clippy::manual_map)] - match self.map.get_mut(&unpack_type_id(*typeid)) { - None => None, - Some(h) => Some(h.values_mut().map(|x| x.as_mut())), - } - } - - /// Get all [`TypeId`]`s` contained in this map. - #[inline] - #[allow(unused_qualifications)] - pub fn all_typeids( - &self, - ) -> core::iter::Map< - Keys<'_, u128, HashMap>>, - fn(&u128) -> TypeId, - > { - self.map.keys().map(|x| pack_type_id(*x)) - } - - /// Run `func` for each element in this map. - #[inline] - #[allow(unused_qualifications)] - pub fn for_each) -> Result<(), Error>>( - &self, - func: &mut F, - ) -> Result<(), Error> { - for (id, h) in self.map.iter() { - for x in h.values() { - func(&pack_type_id(*id), x)?; - } - } - Ok(()) - } - - /// Run `func` for each element in this map, getting a mutable borrow. - #[inline] - pub fn for_each_mut< - F: FnMut(&TypeId, &mut Box) -> Result<(), Error>, - >( - &mut self, - func: &mut F, - ) -> Result<(), Error> { - for (id, h) in self.map.iter_mut() { - for x in h.values_mut() { - func(&pack_type_id(*id), x)?; - } - } - Ok(()) - } - - /// Insert an element into this map. - #[inline] - #[allow(unused_qualifications)] - pub fn insert(&mut self, val: T, name: &str) - where - T: $trait_name, - { - let id = unpack_type_id(TypeId::of::()); - assert!( - unsafe { - REGISTRY - .deserializers - .as_ref() - .expect("Empty types registry") - .get(&id) - .is_some() - }, - "Type {} was inserted without registration! Call {}::register or use serde_autoreg.", - core::any::type_name::(), - core::any::type_name::() - ); - if !self.map.contains_key(&id) { - self.map.insert(id, HashMap::default()); - } - self.map - .get_mut(&id) - .unwrap() - .insert(hash_std(name.as_bytes()), Box::new(val)); - } - - /// Returns the `len` of this map. - #[must_use] - #[inline] - pub fn len(&self) -> usize { - self.map.len() - } - - /// Returns `true` if this map is empty. - #[must_use] - pub fn is_empty(&self) -> bool { - self.map.is_empty() - } - - /// Returns if the element with a given type is contained in this map. - #[must_use] - #[inline] - pub fn contains_type(&self) -> bool - where - T: $trait_name, - { - self.map.contains_key(&unpack_type_id(TypeId::of::())) - } - - /// Returns if the element by a given `name` is contained in this map. - #[must_use] - #[inline] - pub fn contains(&self, name: &str) -> bool - where - T: $trait_name, - { - match self.map.get(&unpack_type_id(TypeId::of::())) { - None => false, - Some(h) => h.contains_key(&hash_std(name.as_bytes())), - } - } - - /// Create a new `SerdeAny` map. - #[must_use] - pub fn new() -> Self { - Self { - map: HashMap::default(), - } - } - } - - impl Default for NamedSerdeAnyMap { - fn default() -> Self { - Self::new() - } - } - } - - #[allow(unused_qualifications)] - impl Serialize for dyn $trait_name { - fn serialize(&self, se: S) -> Result - where - S: Serializer, - { - use serde::ser::SerializeSeq; - - let id = $crate::anymap::unpack_type_id(self.type_id()); - let mut seq = se.serialize_seq(Some(2))?; - seq.serialize_element(&id)?; - seq.serialize_element(&$crate::serdeany::Wrap(self))?; - seq.end() - } - } - - #[allow(unused_qualifications)] - impl<'de> Deserialize<'de> for Box { - fn deserialize(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - deserializer.deserialize_seq($mod_name::BoxDynVisitor {}) - } - } + use hashbrown::{ + hash_map::{Keys, Values, ValuesMut}, + HashMap, }; + use postcard; + use serde::{Deserialize, Serialize}; + + use crate::{ + anymap::{pack_type_id, unpack_type_id}, + hash_std, + serdeany::{DeserializeCallback, DeserializeCallbackSeed}, + Error, + }; + + /// Visitor object used internally for the [`crate::serdeany::SerdeAny`] registry. + #[derive(Debug)] + pub struct BoxDynVisitor {} + #[allow(unused_qualifications)] + impl<'de> serde::de::Visitor<'de> for BoxDynVisitor { + type Value = Box; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Expecting a serialized trait object") + } + + fn visit_seq(self, mut visitor: V) -> Result + where + V: serde::de::SeqAccess<'de>, + { + let id: u128 = visitor.next_element()?.unwrap(); + let cb = unsafe { + *REGISTRY + .deserializers + .as_ref() + .expect("Empty types registry") + .get(&id) + .expect("Cannot deserialize an unregistered type") + }; + let seed = DeserializeCallbackSeed:: { cb }; + let obj: Self::Value = visitor.next_element_seed(seed)?.unwrap(); + Ok(obj) + } + } + + #[allow(unused_qualifications)] + struct Registry { + deserializers: Option>>, + finalized: bool, + } + + #[allow(unused_qualifications)] + impl Registry { + pub fn register(&mut self) + where + T: crate::serdeany::SerdeAny + Serialize + serde::de::DeserializeOwned, + { + assert!(!self.finalized, "Registry is already finalized!"); + + let deserializers = self.deserializers.get_or_insert_with(HashMap::default); + deserializers.insert(unpack_type_id(TypeId::of::()), |de| { + Ok(Box::new(erased_serde::deserialize::(de)?)) + }); + } + + pub fn finalize(&mut self) { + self.finalized = true; + } + } + + static mut REGISTRY: Registry = Registry { + deserializers: None, + finalized: false, + }; + + /// This sugar must be used to register all the structs which + /// have trait objects that can be serialized and deserialized in the program + #[derive(Debug)] + pub struct RegistryBuilder {} + + #[allow(unused_qualifications)] + impl RegistryBuilder { + /// Register a given struct type for trait object (de)serialization + /// + /// # Safety + /// This may never be called concurrently or at the same time as `finalize`. + /// It dereferences the `REGISTRY` hashmap and adds the given type to it. + pub unsafe fn register() + where + T: crate::serdeany::SerdeAny + Serialize + serde::de::DeserializeOwned, + { + unsafe { + REGISTRY.register::(); + } + } + + /// Finalize the registry, no more registrations are allowed after this call + /// + /// # Safety + /// This may never be called concurrently or at the same time as `register`. + /// It dereferences the `REGISTRY` hashmap and adds the given type to it. + pub fn finalize() { + unsafe { + REGISTRY.finalize(); + } + } + } + + /// A (de)serializable anymap containing (de)serializable trait objects registered + /// in the registry + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Debug, Serialize, Deserialize)] + pub struct SerdeAnyMap { + map: HashMap>, + } + + // Cloning by serializing and deserializing. It ain't fast, but it's honest work. + // We unwrap postcard, it should not have a reason to fail. + impl Clone for SerdeAnyMap { + fn clone(&self) -> Self { + let serialized = postcard::to_allocvec(&self).unwrap(); + postcard::from_bytes(&serialized).unwrap() + } + } + + /* + #[cfg(feature = "anymap_debug")] + impl fmt::Debug for SerdeAnyMap { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let json = serde_json::to_string(&self); + write!(f, "SerdeAnyMap: [{:?}]", json) + } + } + + #[cfg(not(feature = "anymap_debug"))] + impl fmt::Debug for SerdeAnyMap { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "SerdeAnymap with {} elements", self.len()) + } + }*/ + + #[allow(unused_qualifications)] + impl SerdeAnyMap { + /// Get an element from the map. + #[must_use] + #[inline] + pub fn get(&self) -> Option<&T> + where + T: crate::serdeany::SerdeAny, + { + self.map + .get(&unpack_type_id(TypeId::of::())) + .map(|x| x.as_ref().as_any().downcast_ref::().unwrap()) + } + + /// Get a mutable borrow for an element in the map. + #[must_use] + #[inline] + pub fn get_mut(&mut self) -> Option<&mut T> + where + T: crate::serdeany::SerdeAny, + { + self.map + .get_mut(&unpack_type_id(TypeId::of::())) + .map(|x| x.as_mut().as_any_mut().downcast_mut::().unwrap()) + } + + /// Remove an element in the map. Returns the removed element. + #[must_use] + #[inline] + pub fn remove(&mut self) -> Option> + where + T: crate::serdeany::SerdeAny, + { + self.map + .remove(&unpack_type_id(TypeId::of::())) + .map(|x| x.as_any_boxed().downcast::().unwrap()) + } + + /// Insert an element into the map. + #[inline] + pub fn insert(&mut self, t: T) + where + T: crate::serdeany::SerdeAny, + { + self.insert_boxed(Box::new(t)); + } + + /// Insert a boxed element into the map. + #[inline] + pub fn insert_boxed(&mut self, t: Box) + where + T: crate::serdeany::SerdeAny, + { + let id = unpack_type_id(TypeId::of::()); + assert!( + unsafe { + REGISTRY + .deserializers + .as_ref() + .expect("Empty types registry") + .get(&id) + .is_some() + }, + "Type {} was inserted without registration! Call {}::register or use serde_autoreg.", + core::any::type_name::(), + core::any::type_name::() + ); + self.map.insert(id, t); + } + + /// Returns the count of elements in this map. + #[must_use] + #[inline] + pub fn len(&self) -> usize { + self.map.len() + } + + /// Returns `true` if this map is empty. + #[must_use] + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Returns if the map contains the given type. + #[must_use] + #[inline] + pub fn contains(&self) -> bool + where + T: crate::serdeany::SerdeAny, + { + self.map.contains_key(&unpack_type_id(TypeId::of::())) + } + + /// Create a new [`SerdeAnyMap`]. + #[must_use] + pub fn new() -> Self { + SerdeAnyMap { + map: HashMap::default(), + } + } + } + + impl Default for SerdeAnyMap { + fn default() -> Self { + Self::new() + } + } + + /// A serializable [`HashMap`] wrapper for [`crate::serdeany::SerdeAny`] types, addressable by name. + #[allow(clippy::unsafe_derive_deserialize)] + #[allow(unused_qualifications)] + #[derive(Debug, Serialize, Deserialize)] + pub struct NamedSerdeAnyMap { + map: HashMap>>, + } + + // Cloning by serializing and deserializing. It ain't fast, but it's honest work. + // We unwrap postcard, it should not have a reason to fail. + impl Clone for NamedSerdeAnyMap { + fn clone(&self) -> Self { + let serialized = postcard::to_allocvec(&self).unwrap(); + postcard::from_bytes(&serialized).unwrap() + } + } + + #[allow(unused_qualifications)] + impl NamedSerdeAnyMap { + /// Get an element by name + #[must_use] + #[inline] + pub fn get(&self, name: &str) -> Option<&T> + where + T: crate::serdeany::SerdeAny, + { + match self.map.get(&unpack_type_id(TypeId::of::())) { + None => None, + Some(h) => h + .get(&hash_std(name.as_bytes())) + .map(|x| x.as_any().downcast_ref::().unwrap()), + } + } + + /// Get an element of a given type contained in this map by [`TypeId`]. + #[must_use] + #[allow(unused_qualifications)] + #[inline] + pub fn by_typeid( + &self, + name: &str, + typeid: &TypeId, + ) -> Option<&dyn crate::serdeany::SerdeAny> { + match self.map.get(&unpack_type_id(*typeid)) { + None => None, + Some(h) => h.get(&hash_std(name.as_bytes())).map(AsRef::as_ref), + } + } + + /// Get an element of a given type contained in this map by [`TypeId`], as mut. + #[must_use] + #[inline] + pub fn get_mut(&mut self, name: &str) -> Option<&mut T> + where + T: crate::serdeany::SerdeAny, + { + match self.map.get_mut(&unpack_type_id(TypeId::of::())) { + None => None, + Some(h) => h + .get_mut(&hash_std(name.as_bytes())) + .map(|x| x.as_any_mut().downcast_mut::().unwrap()), + } + } + + /// Get an element of a given type contained in this map by [`TypeId`], as mut. + #[must_use] + #[inline] + pub fn by_typeid_mut( + &mut self, + name: &str, + typeid: &TypeId, + ) -> Option<&mut dyn crate::serdeany::SerdeAny> { + match self.map.get_mut(&unpack_type_id(*typeid)) { + None => None, + Some(h) => h.get_mut(&hash_std(name.as_bytes())).map(AsMut::as_mut), + } + } + + /// Get all elements of a type contained in this map. + #[must_use] + #[allow(unused_qualifications)] + #[inline] + #[allow(clippy::type_complexity)] + pub fn get_all( + &self, + ) -> Option< + core::iter::Map< + Values<'_, u64, Box>, + fn(&Box) -> &T, + >, + > + where + T: crate::serdeany::SerdeAny, + { + #[allow(clippy::manual_map)] + match self.map.get(&unpack_type_id(TypeId::of::())) { + None => None, + Some(h) => Some(h.values().map(|x| x.as_any().downcast_ref::().unwrap())), + } + } + + /// Get all elements of a given type contained in this map by [`TypeId`]. + #[must_use] + #[allow(unused_qualifications)] + #[inline] + #[allow(clippy::type_complexity)] + pub fn all_by_typeid( + &self, + typeid: &TypeId, + ) -> Option< + core::iter::Map< + Values<'_, u64, Box>, + fn(&Box) -> &dyn crate::serdeany::SerdeAny, + >, + > { + #[allow(clippy::manual_map)] + match self.map.get(&unpack_type_id(*typeid)) { + None => None, + Some(h) => Some(h.values().map(|x| x.as_ref())), + } + } + + /// Get all elements contained in this map, as mut. + #[inline] + #[allow(unused_qualifications)] + #[allow(clippy::type_complexity)] + pub fn get_all_mut( + &mut self, + ) -> Option< + core::iter::Map< + ValuesMut<'_, u64, Box>, + fn(&mut Box) -> &mut T, + >, + > + where + T: crate::serdeany::SerdeAny, + { + #[allow(clippy::manual_map)] + match self.map.get_mut(&unpack_type_id(TypeId::of::())) { + None => None, + Some(h) => Some( + h.values_mut() + .map(|x| x.as_any_mut().downcast_mut::().unwrap()), + ), + } + } + + /// Get all [`TypeId`]`s` contained in this map, as mut. + #[inline] + #[allow(unused_qualifications)] + #[allow(clippy::type_complexity)] + pub fn all_by_typeid_mut( + &mut self, + typeid: &TypeId, + ) -> Option< + core::iter::Map< + ValuesMut<'_, u64, Box>, + fn(&mut Box) -> &mut dyn crate::serdeany::SerdeAny, + >, + > { + #[allow(clippy::manual_map)] + match self.map.get_mut(&unpack_type_id(*typeid)) { + None => None, + Some(h) => Some(h.values_mut().map(|x| x.as_mut())), + } + } + + /// Get all [`TypeId`]`s` contained in this map. + #[inline] + #[allow(unused_qualifications)] + #[allow(clippy::type_complexity)] + pub fn all_typeids( + &self, + ) -> core::iter::Map< + Keys<'_, u128, HashMap>>, + fn(&u128) -> TypeId, + > { + self.map.keys().map(|x| pack_type_id(*x)) + } + + /// Run `func` for each element in this map. + #[inline] + #[allow(unused_qualifications)] + pub fn for_each< + F: FnMut(&TypeId, &Box) -> Result<(), Error>, + >( + &self, + func: &mut F, + ) -> Result<(), Error> { + for (id, h) in &self.map { + for x in h.values() { + func(&pack_type_id(*id), x)?; + } + } + Ok(()) + } + + /// Run `func` for each element in this map, getting a mutable borrow. + #[inline] + pub fn for_each_mut< + F: FnMut(&TypeId, &mut Box) -> Result<(), Error>, + >( + &mut self, + func: &mut F, + ) -> Result<(), Error> { + for (id, h) in &mut self.map { + for x in h.values_mut() { + func(&pack_type_id(*id), x)?; + } + } + Ok(()) + } + + /// Insert an element into this map. + #[inline] + #[allow(unused_qualifications)] + pub fn insert(&mut self, val: T, name: &str) + where + T: crate::serdeany::SerdeAny, + { + let id = unpack_type_id(TypeId::of::()); + assert!( + unsafe { + REGISTRY + .deserializers + .as_ref() + .expect("Empty types registry") + .get(&id) + .is_some() + }, + "Type {} was inserted without registration! Call {}::register or use serde_autoreg.", + core::any::type_name::(), + core::any::type_name::() + ); + if !self.map.contains_key(&id) { + self.map.insert(id, HashMap::default()); + } + self.map + .get_mut(&id) + .unwrap() + .insert(hash_std(name.as_bytes()), Box::new(val)); + } + + /// Returns the `len` of this map. + #[must_use] + #[inline] + pub fn len(&self) -> usize { + self.map.len() + } + + /// Returns `true` if this map is empty. + #[must_use] + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Returns if the element with a given type is contained in this map. + #[must_use] + #[inline] + pub fn contains_type(&self) -> bool + where + T: crate::serdeany::SerdeAny, + { + self.map.contains_key(&unpack_type_id(TypeId::of::())) + } + + /// Returns if the element by a given `name` is contained in this map. + #[must_use] + #[inline] + pub fn contains(&self, name: &str) -> bool + where + T: crate::serdeany::SerdeAny, + { + match self.map.get(&unpack_type_id(TypeId::of::())) { + None => false, + Some(h) => h.contains_key(&hash_std(name.as_bytes())), + } + } + + /// Create a new `SerdeAny` map. + #[must_use] + pub fn new() -> Self { + Self { + map: HashMap::default(), + } + } + } + + impl Default for NamedSerdeAnyMap { + fn default() -> Self { + Self::new() + } + } } -create_serde_registry_for_trait!(serdeany_registry, crate::serdeany::SerdeAny); -pub use serdeany_registry::*; +#[allow(unused_qualifications)] +impl Serialize for dyn crate::serdeany::SerdeAny { + fn serialize(&self, se: S) -> Result + where + S: Serializer, + { + use serde::ser::SerializeSeq; + + let id = crate::anymap::unpack_type_id(self.type_id()); + let mut seq = se.serialize_seq(Some(2))?; + seq.serialize_element(&id)?; + seq.serialize_element(&crate::serdeany::Wrap(self))?; + seq.end() + } +} + +#[allow(unused_qualifications)] +impl<'de> Deserialize<'de> for Box { + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(serdeany_registry::BoxDynVisitor {}) + } +} /// Register a `SerdeAny` type in the [`RegistryBuilder`] ///