Merge branch 'main' of github.com:AFLplusplus/libAFLrs into main
This commit is contained in:
commit
d7661ce9f8
@ -10,6 +10,7 @@ edition = "2018"
|
|||||||
criterion = "0.3" # Benchmarking
|
criterion = "0.3" # Benchmarking
|
||||||
ahash = "0.6.1" # another hash
|
ahash = "0.6.1" # another hash
|
||||||
fxhash = "0.2.1" # yet another hash
|
fxhash = "0.2.1" # yet another hash
|
||||||
|
xxhash-rust = { version = "0.8.0", features = ["const_xxh3", "xxh3"] } # xxh3 hashing for rust
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "rand_speeds"
|
name = "rand_speeds"
|
||||||
@ -29,7 +30,7 @@ std = []
|
|||||||
hashbrown = { version = "0.9", features = ["serde"] } # A faster hashmap, nostd compatible
|
hashbrown = { version = "0.9", features = ["serde"] } # A faster hashmap, nostd compatible
|
||||||
libc = "0.2" # For (*nix) libc
|
libc = "0.2" # For (*nix) libc
|
||||||
num = "*"
|
num = "*"
|
||||||
xxhash-rust = { version = "0.8.0-beta.5", features = ["const_xxh3", "xxh3"] } # xxh3 hashing for rust
|
xxhash-rust = { version = "0.8.0", features = ["xxh3"] } # xxh3 hashing for rust
|
||||||
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
||||||
erased-serde = "0.3.12"
|
erased-serde = "0.3.12"
|
||||||
postcard = "0.5.1" # no_std compatible serde serialization fromat
|
postcard = "0.5.1" # no_std compatible serde serialization fromat
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use core::any::Any;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::any::Any;
|
|
||||||
use num::Integer;
|
use num::Integer;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -10,12 +10,12 @@ pub mod executors;
|
|||||||
pub mod feedbacks;
|
pub mod feedbacks;
|
||||||
pub mod generators;
|
pub mod generators;
|
||||||
pub mod inputs;
|
pub mod inputs;
|
||||||
|
pub mod metamap;
|
||||||
pub mod mutators;
|
pub mod mutators;
|
||||||
pub mod observers;
|
pub mod observers;
|
||||||
|
pub mod serde_anymap;
|
||||||
pub mod stages;
|
pub mod stages;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod serde_anymap;
|
|
||||||
pub mod metamap;
|
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
@ -1,62 +1,92 @@
|
|||||||
use hashbrown::HashMap;
|
use alloc::boxed::Box;
|
||||||
use hashbrown::hash_map::{ValuesMut, Values};
|
use alloc::vec::Vec;
|
||||||
|
use core::any::{Any, TypeId};
|
||||||
use core::slice::{Iter, IterMut};
|
use core::slice::{Iter, IterMut};
|
||||||
use core::any::{TypeId, Any};
|
use hashbrown::hash_map::{Values, ValuesMut};
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
pub struct MetaMap {
|
pub struct MetaMap {
|
||||||
map: HashMap<TypeId, Box<dyn Any>>
|
map: HashMap<TypeId, Box<dyn Any>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetaMap {
|
impl MetaMap {
|
||||||
pub fn get<T>(&self) -> Option<&T> where T: Any {
|
pub fn get<T>(&self) -> Option<&T>
|
||||||
self.map.get(&TypeId::of::<T>()).map(|x| x.as_ref().downcast_ref::<T>().unwrap())
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
|
self.map
|
||||||
|
.get(&TypeId::of::<T>())
|
||||||
|
.map(|x| x.as_ref().downcast_ref::<T>().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut<T>(&mut self) -> Option<&mut T> where T: Any {
|
pub fn get_mut<T>(&mut self) -> Option<&mut T>
|
||||||
self.map.get_mut(&TypeId::of::<T>()).map(|x| x.as_mut().downcast_mut::<T>().unwrap())
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
|
self.map
|
||||||
|
.get_mut(&TypeId::of::<T>())
|
||||||
|
.map(|x| x.as_mut().downcast_mut::<T>().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<T>(&mut self, t: T) where T: Any {
|
pub fn insert<T>(&mut self, t: T)
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.map.insert(TypeId::of::<T>(), Box::new(t));
|
self.map.insert(TypeId::of::<T>(), Box::new(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.map.len()
|
self.map.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains<T>(&self) -> bool where T: Any {
|
pub fn contains<T>(&self) -> bool
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.map.contains_key(&TypeId::of::<T>())
|
self.map.contains_key(&TypeId::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { map: HashMap::default() }
|
Self {
|
||||||
|
map: HashMap::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MultiMetaMap {
|
pub struct MultiMetaMap {
|
||||||
map: HashMap<TypeId, Vec<Box<dyn Any>>>
|
map: HashMap<TypeId, Vec<Box<dyn Any>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiMetaMap {
|
impl MultiMetaMap {
|
||||||
pub fn get<T>(&self) -> Option<core::iter::Map<Iter<'_, Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>> where T: Any {
|
pub fn get<T>(&self) -> Option<core::iter::Map<Iter<'_, Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get(&TypeId::of::<T>()) {
|
match self.map.get(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(v) => {
|
Some(v) => Some(v.iter().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
|
||||||
Some(v.iter().map(|x| x.as_ref().downcast_ref::<T>().unwrap()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut<T>(&mut self) -> Option<core::iter::Map<IterMut<'_, Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>> where T: Any {
|
pub fn get_mut<T>(
|
||||||
|
&mut self,
|
||||||
|
) -> Option<core::iter::Map<IterMut<'_, Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get_mut(&TypeId::of::<T>()) {
|
match self.map.get_mut(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(v) => {
|
Some(v) => Some(
|
||||||
Some(v.iter_mut().map(|x| x.as_mut().downcast_mut::<T>().unwrap()))
|
v.iter_mut()
|
||||||
}
|
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<T>(&mut self, t: T) where T: Any {
|
pub fn insert<T>(&mut self, t: T)
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
let typeid = TypeId::of::<T>();
|
let typeid = TypeId::of::<T>();
|
||||||
if !self.map.contains_key(&typeid) {
|
if !self.map.contains_key(&typeid) {
|
||||||
self.map.insert(typeid, vec![Box::new(t)]);
|
self.map.insert(typeid, vec![Box::new(t)]);
|
||||||
@ -64,104 +94,149 @@ impl MultiMetaMap {
|
|||||||
self.map.get_mut(&typeid).unwrap().push(Box::new(t));
|
self.map.get_mut(&typeid).unwrap().push(Box::new(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.map.len()
|
self.map.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains<T>(&self) -> bool where T: Any {
|
pub fn contains<T>(&self) -> bool
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.map.contains_key(&TypeId::of::<T>())
|
self.map.contains_key(&TypeId::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { map: HashMap::default() }
|
Self {
|
||||||
|
map: HashMap::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct MetaInstanceMap {
|
pub struct MetaInstanceMap {
|
||||||
map: HashMap<TypeId, HashMap<*const (), Box<dyn Any>>>
|
map: HashMap<TypeId, HashMap<*const (), Box<dyn Any>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetaInstanceMap {
|
impl MetaInstanceMap {
|
||||||
pub fn get<T, U>(&self, instance: &U) -> Option<&T> where T: Any {
|
pub fn get<T, U>(&self, instance: &U) -> Option<&T>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.get_ptr::<T>(instance as *const _ as *const ())
|
self.get_ptr::<T>(instance as *const _ as *const ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ptr<T>(&self, instance: *const ()) -> Option<&T> where T: Any {
|
pub fn get_ptr<T>(&self, instance: *const ()) -> Option<&T>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get(&TypeId::of::<T>()) {
|
match self.map.get(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => {
|
Some(h) => h
|
||||||
h.get(&instance).map(|x| x.as_ref().downcast_ref::<T>().unwrap())
|
.get(&instance)
|
||||||
}
|
.map(|x| x.as_ref().downcast_ref::<T>().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut<T, U>(&mut self, instance: &U) -> Option<&mut T> where T: Any {
|
pub fn get_mut<T, U>(&mut self, instance: &U) -> Option<&mut T>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.get_mut_ptr::<T>(instance as *const _ as *const ())
|
self.get_mut_ptr::<T>(instance as *const _ as *const ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_ptr<T>(&mut self, instance: *const ()) -> Option<&mut T> where T: Any {
|
pub fn get_mut_ptr<T>(&mut self, instance: *const ()) -> Option<&mut T>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get_mut(&TypeId::of::<T>()) {
|
match self.map.get_mut(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => {
|
Some(h) => h
|
||||||
h.get_mut(&instance).map(|x| x.as_mut().downcast_mut::<T>().unwrap())
|
.get_mut(&instance)
|
||||||
}
|
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all<T>(&self) -> Option<core::iter::Map<Values<'_, *const (), Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>> where T: Any {
|
pub fn get_all<T>(
|
||||||
|
&self,
|
||||||
|
) -> Option<core::iter::Map<Values<'_, *const (), Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get(&TypeId::of::<T>()) {
|
match self.map.get(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => {
|
Some(h) => Some(h.values().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
|
||||||
Some(h.values().map(|x| x.as_ref().downcast_ref::<T>().unwrap()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_mut<T>(&mut self) -> Option<core::iter::Map<ValuesMut<'_, *const (), Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>> where T: Any {
|
pub fn get_all_mut<T>(
|
||||||
|
&mut self,
|
||||||
|
) -> Option<
|
||||||
|
core::iter::Map<ValuesMut<'_, *const (), Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>,
|
||||||
|
>
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get_mut(&TypeId::of::<T>()) {
|
match self.map.get_mut(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => {
|
Some(h) => Some(
|
||||||
Some(h.values_mut().map(|x| x.as_mut().downcast_mut::<T>().unwrap()))
|
h.values_mut()
|
||||||
}
|
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<T, U>(&mut self, t: T, instance: &U) where T: Any {
|
pub fn insert<T, U>(&mut self, t: T, instance: &U)
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.insert_ptr(t, instance as *const _ as *const ())
|
self.insert_ptr(t, instance as *const _ as *const ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_ptr<T>(&mut self, t: T, instance: *const ()) where T: Any {
|
pub fn insert_ptr<T>(&mut self, t: T, instance: *const ())
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
let typeid = TypeId::of::<T>();
|
let typeid = TypeId::of::<T>();
|
||||||
if !self.map.contains_key(&typeid) {
|
if !self.map.contains_key(&typeid) {
|
||||||
self.map.insert(typeid, HashMap::default());
|
self.map.insert(typeid, HashMap::default());
|
||||||
}
|
}
|
||||||
self.map.get_mut(&typeid).unwrap().insert(instance, Box::new(t));
|
self.map
|
||||||
|
.get_mut(&typeid)
|
||||||
|
.unwrap()
|
||||||
|
.insert(instance, Box::new(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.map.len()
|
self.map.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_type<T>(&self) -> bool where T: Any {
|
pub fn contains_type<T>(&self) -> bool
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.map.contains_key(&TypeId::of::<T>())
|
self.map.contains_key(&TypeId::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains<T, U>(&self, instance: &U) -> bool where T: Any {
|
pub fn contains<T, U>(&self, instance: &U) -> bool
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
self.contains_ptr::<T>(instance as *const _ as *const ())
|
self.contains_ptr::<T>(instance as *const _ as *const ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_ptr<T>(&self, instance: *const ()) -> bool where T: Any {
|
pub fn contains_ptr<T>(&self, instance: *const ()) -> bool
|
||||||
|
where
|
||||||
|
T: Any,
|
||||||
|
{
|
||||||
match self.map.get(&TypeId::of::<T>()) {
|
match self.map.get(&TypeId::of::<T>()) {
|
||||||
None => false,
|
None => false,
|
||||||
Some(h) => {
|
Some(h) => h.contains_key(&instance),
|
||||||
h.contains_key(&instance)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { map: HashMap::default() }
|
Self {
|
||||||
|
map: HashMap::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use core::any::{Any, TypeId};
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::any::{TypeId, Any};
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
pub fn pack_type_id(id: u64) -> TypeId {
|
pub fn pack_type_id(id: u64) -> TypeId {
|
||||||
unsafe {
|
unsafe { *(&id as *const u64 as *const TypeId) }
|
||||||
*(&id as *const u64 as *const TypeId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpack_type_id(id: TypeId) -> u64 {
|
pub fn unpack_type_id(id: TypeId) -> u64 {
|
||||||
unsafe {
|
unsafe { *(&id as *const _ as *const u64) }
|
||||||
*(&id as *const _ as *const u64)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SerdeAny : Any + erased_serde::Serialize {
|
pub trait SerdeAny: Any + erased_serde::Serialize {
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeserializeCallback = fn(&mut dyn erased_serde::Deserializer) -> Result<Box<dyn SerdeAny>, erased_serde::Error>;
|
type DeserializeCallback =
|
||||||
|
fn(&mut dyn erased_serde::Deserializer) -> Result<Box<dyn SerdeAny>, erased_serde::Error>;
|
||||||
|
|
||||||
struct Wrap<'a, T: ?Sized>(pub &'a T);
|
struct Wrap<'a, T: ?Sized>(pub &'a T);
|
||||||
impl<'a, T> Serialize for Wrap<'a, T>
|
impl<'a, T> Serialize for Wrap<'a, T>
|
||||||
@ -39,7 +37,8 @@ where
|
|||||||
|
|
||||||
impl<'a> serde::Serialize for dyn SerdeAny + 'a {
|
impl<'a> serde::Serialize for dyn SerdeAny + 'a {
|
||||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
||||||
where S: serde::Serializer
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
use serde::ser::SerializeSeq;
|
use serde::ser::SerializeSeq;
|
||||||
|
|
||||||
@ -55,7 +54,7 @@ struct DeserializeCallbackSeed {
|
|||||||
pub cb: DeserializeCallback,
|
pub cb: DeserializeCallback,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> serde::de::DeserializeSeed<'de> for DeserializeCallbackSeed{
|
impl<'de> serde::de::DeserializeSeed<'de> for DeserializeCallbackSeed {
|
||||||
type Value = Box<dyn SerdeAny>;
|
type Value = Box<dyn SerdeAny>;
|
||||||
|
|
||||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
@ -74,13 +73,20 @@ impl<'de> serde::de::Visitor<'de> for BoxAnyVisitor {
|
|||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter.write_str("Expecting a serialized SerdeAny trait object (Box<dyn SerdeAny>)")
|
formatter.write_str("Expecting a serialized SerdeAny trait object (Box<dyn SerdeAny>)")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(self, mut visitor: V) -> Result<Box<dyn SerdeAny>, V::Error>
|
fn visit_seq<V>(self, mut visitor: V) -> Result<Box<dyn SerdeAny>, V::Error>
|
||||||
where
|
where
|
||||||
V: serde::de::SeqAccess<'de>,
|
V: serde::de::SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let id: u64 = visitor.next_element()?.unwrap();
|
let id: u64 = visitor.next_element()?.unwrap();
|
||||||
let cb = unsafe { *REGISTRY.deserializers.as_ref().unwrap().get(&id).expect("Cannot deserialize an unregistered SerdeAny") };
|
let cb = unsafe {
|
||||||
|
*REGISTRY
|
||||||
|
.deserializers
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.get(&id)
|
||||||
|
.expect("Cannot deserialize an unregistered SerdeAny")
|
||||||
|
};
|
||||||
let seed = DeserializeCallbackSeed { cb: cb };
|
let seed = DeserializeCallbackSeed { cb: cb };
|
||||||
let obj: Box<dyn SerdeAny> = visitor.next_element_seed(seed)?.unwrap();
|
let obj: Box<dyn SerdeAny> = visitor.next_element_seed(seed)?.unwrap();
|
||||||
Ok(obj)
|
Ok(obj)
|
||||||
@ -98,34 +104,45 @@ impl<'de> Deserialize<'de> for Box<dyn SerdeAny> {
|
|||||||
|
|
||||||
pub struct Registry {
|
pub struct Registry {
|
||||||
deserializers: Option<HashMap<u64, DeserializeCallback>>,
|
deserializers: Option<HashMap<u64, DeserializeCallback>>,
|
||||||
finalized: bool
|
finalized: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Registry {
|
impl Registry {
|
||||||
pub fn register<T>(&mut self) where T: SerdeAny + Serialize + serde::de::DeserializeOwned {
|
pub fn register<T>(&mut self)
|
||||||
|
where
|
||||||
|
T: SerdeAny + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
if self.finalized {
|
if self.finalized {
|
||||||
panic!("Global Registry of SerdeAny types is already finalized!");
|
panic!("Global Registry of SerdeAny types is already finalized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let deserializers = self.deserializers.get_or_insert_with(|| HashMap::default());
|
let deserializers = self.deserializers.get_or_insert_with(|| HashMap::default());
|
||||||
deserializers.insert(unpack_type_id(TypeId::of::<T>()), |de| Ok(Box::new(erased_serde::deserialize::<T>(de)?)));
|
deserializers.insert(unpack_type_id(TypeId::of::<T>()), |de| {
|
||||||
|
Ok(Box::new(erased_serde::deserialize::<T>(de)?))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finalize(&mut self) {
|
pub fn finalize(&mut self) {
|
||||||
self.finalized = true;
|
self.finalized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut REGISTRY: Registry = Registry { deserializers: None, finalized: false };
|
static mut REGISTRY: Registry = Registry {
|
||||||
|
deserializers: None,
|
||||||
|
finalized: false,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct RegistryBuilder {}
|
pub struct RegistryBuilder {}
|
||||||
impl RegistryBuilder {
|
impl RegistryBuilder {
|
||||||
pub fn register<T>() where T: SerdeAny + Serialize + serde::de::DeserializeOwned {
|
pub fn register<T>()
|
||||||
|
where
|
||||||
|
T: SerdeAny + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
REGISTRY.register::<T>();
|
REGISTRY.register::<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finalize() {
|
pub fn finalize() {
|
||||||
unsafe {
|
unsafe {
|
||||||
REGISTRY.finalize();
|
REGISTRY.finalize();
|
||||||
@ -135,31 +152,50 @@ impl RegistryBuilder {
|
|||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
pub struct SerdeAnyMap {
|
pub struct SerdeAnyMap {
|
||||||
map: HashMap<u64, Box<dyn SerdeAny>>
|
map: HashMap<u64, Box<dyn SerdeAny>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerdeAnyMap {
|
impl SerdeAnyMap {
|
||||||
pub fn get<T>(&self) -> Option<&T> where T: SerdeAny {
|
pub fn get<T>(&self) -> Option<&T>
|
||||||
self.map.get(&unpack_type_id(TypeId::of::<T>())).map(|x| x.as_ref().as_any().downcast_ref::<T>().unwrap())
|
where
|
||||||
|
T: SerdeAny,
|
||||||
|
{
|
||||||
|
self.map
|
||||||
|
.get(&unpack_type_id(TypeId::of::<T>()))
|
||||||
|
.map(|x| x.as_ref().as_any().downcast_ref::<T>().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut<T>(&mut self) -> Option<&mut T> where T: SerdeAny {
|
pub fn get_mut<T>(&mut self) -> Option<&mut T>
|
||||||
self.map.get_mut(&unpack_type_id(TypeId::of::<T>())).map(|x| x.as_mut().as_any_mut().downcast_mut::<T>().unwrap())
|
where
|
||||||
|
T: SerdeAny,
|
||||||
|
{
|
||||||
|
self.map
|
||||||
|
.get_mut(&unpack_type_id(TypeId::of::<T>()))
|
||||||
|
.map(|x| x.as_mut().as_any_mut().downcast_mut::<T>().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<T>(&mut self, t: T) where T: SerdeAny {
|
pub fn insert<T>(&mut self, t: T)
|
||||||
self.map.insert(unpack_type_id(TypeId::of::<T>()), Box::new(t));
|
where
|
||||||
|
T: SerdeAny,
|
||||||
|
{
|
||||||
|
self.map
|
||||||
|
.insert(unpack_type_id(TypeId::of::<T>()), Box::new(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.map.len()
|
self.map.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains<T>(&self) -> bool where T: SerdeAny {
|
pub fn contains<T>(&self) -> bool
|
||||||
|
where
|
||||||
|
T: SerdeAny,
|
||||||
|
{
|
||||||
self.map.contains_key(&unpack_type_id(TypeId::of::<T>()))
|
self.map.contains_key(&unpack_type_id(TypeId::of::<T>()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
SerdeAnyMap { map: HashMap::default() }
|
SerdeAnyMap {
|
||||||
|
map: HashMap::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use alloc::rc::Rc;
|
|||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use core::debug_assert;
|
use core::debug_assert;
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use xxhash_rust::const_xxh3::xxh3_64_with_seed;
|
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
@ -339,5 +339,4 @@ mod tests {
|
|||||||
assert_eq!(next_pow2(1000), 1024);
|
assert_eq!(next_pow2(1000), 1024);
|
||||||
assert_eq!(next_pow2(0xFFFFFFFF as u64), (0xFFFFFFFF as u64) + 1);
|
assert_eq!(next_pow2(0xFFFFFFFF as u64), (0xFFFFFFFF as u64) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user