use crate::{FromType, Reflect, TypeRegistry};
use alloc::boxed::Box;
use serde::{Serialize, Serializer};
pub trait SerializeWithRegistry {
fn serialize<S>(&self, serializer: S, registry: &TypeRegistry) -> Result<S::Ok, S::Error>
where
S: Serializer;
}
#[derive(Clone)]
pub struct ReflectSerializeWithRegistry {
serialize: for<'a> fn(
value: &'a dyn Reflect,
registry: &'a TypeRegistry,
) -> Box<dyn erased_serde::Serialize + 'a>,
}
impl ReflectSerializeWithRegistry {
pub fn serialize<S>(
&self,
value: &dyn Reflect,
serializer: S,
registry: &TypeRegistry,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
((self.serialize)(value, registry)).serialize(serializer)
}
}
impl<T: Reflect + SerializeWithRegistry> FromType<T> for ReflectSerializeWithRegistry {
fn from_type() -> Self {
Self {
serialize: |value: &dyn Reflect, registry| {
let value = value.downcast_ref::<T>().unwrap_or_else(|| {
panic!(
"Expected value to be of type {} but received {}",
core::any::type_name::<T>(),
value.reflect_type_path()
)
});
Box::new(SerializableWithRegistry { value, registry })
},
}
}
}
struct SerializableWithRegistry<'a, T: SerializeWithRegistry> {
value: &'a T,
registry: &'a TypeRegistry,
}
impl<'a, T: SerializeWithRegistry> Serialize for SerializableWithRegistry<'a, T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.value.serialize(serializer, self.registry)
}
}