
builds on top of #4780 # Objective `Reflect` and `Serialize` are currently very tied together because `Reflect` has a `fn serialize(&self) -> Option<Serializable<'_>>` method. Because of that, we can either implement `Reflect` for types like `Option<T>` with `T: Serialize` and have `fn serialize` be implemented, or without the bound but having `fn serialize` return `None`. By separating `ReflectSerialize` into a separate type (like how it already is for `ReflectDeserialize`, `ReflectDefault`), we could separately `.register::<Option<T>>()` and `.register_data::<Option<T>, ReflectSerialize>()` only if the type `T: Serialize`. This PR does not change the registration but allows it to be changed in a future PR. ## Solution - add the type ```rust struct ReflectSerialize { .. } impl<T: Reflect + Serialize> FromType<T> for ReflectSerialize { .. } ``` - remove `#[reflect(Serialize)]` special casing. - when serializing reflect value types, look for `ReflectSerialize` in the `TypeRegistry` instead of calling `value.serialize()`
369 lines
10 KiB
Rust
369 lines
10 KiB
Rust
use crate::{
|
|
serde::type_fields, Array, List, Map, Reflect, ReflectRef, ReflectSerialize, Struct, Tuple,
|
|
TupleStruct, TypeRegistry,
|
|
};
|
|
use serde::{
|
|
ser::{SerializeMap, SerializeSeq},
|
|
Serialize,
|
|
};
|
|
|
|
pub enum Serializable<'a> {
|
|
Owned(Box<dyn erased_serde::Serialize + 'a>),
|
|
Borrowed(&'a dyn erased_serde::Serialize),
|
|
}
|
|
|
|
impl<'a> Serializable<'a> {
|
|
#[allow(clippy::should_implement_trait)]
|
|
pub fn borrow(&self) -> &dyn erased_serde::Serialize {
|
|
match self {
|
|
Serializable::Borrowed(serialize) => serialize,
|
|
Serializable::Owned(serialize) => serialize,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_serializable<'a, E: serde::ser::Error>(
|
|
reflect_value: &'a dyn Reflect,
|
|
type_registry: &TypeRegistry,
|
|
) -> Result<Serializable<'a>, E> {
|
|
let reflect_serialize = type_registry
|
|
.get_type_data::<ReflectSerialize>(reflect_value.type_id())
|
|
.ok_or_else(|| {
|
|
serde::ser::Error::custom(format_args!(
|
|
"Type '{}' did not register ReflectSerialize",
|
|
reflect_value.type_name()
|
|
))
|
|
})?;
|
|
Ok(reflect_serialize.get_serializable(reflect_value))
|
|
}
|
|
|
|
pub struct ReflectSerializer<'a> {
|
|
pub value: &'a dyn Reflect,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> ReflectSerializer<'a> {
|
|
pub fn new(value: &'a dyn Reflect, registry: &'a TypeRegistry) -> Self {
|
|
ReflectSerializer { value, registry }
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for ReflectSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
match self.value.reflect_ref() {
|
|
ReflectRef::Struct(value) => StructSerializer {
|
|
struct_value: value,
|
|
registry: self.registry,
|
|
}
|
|
.serialize(serializer),
|
|
ReflectRef::TupleStruct(value) => TupleStructSerializer {
|
|
tuple_struct: value,
|
|
registry: self.registry,
|
|
}
|
|
.serialize(serializer),
|
|
ReflectRef::Tuple(value) => TupleSerializer {
|
|
tuple: value,
|
|
registry: self.registry,
|
|
}
|
|
.serialize(serializer),
|
|
ReflectRef::List(value) => ListSerializer {
|
|
list: value,
|
|
registry: self.registry,
|
|
}
|
|
.serialize(serializer),
|
|
ReflectRef::Array(value) => ArraySerializer {
|
|
array: value,
|
|
registry: self.registry,
|
|
}
|
|
.serialize(serializer),
|
|
ReflectRef::Map(value) => MapSerializer {
|
|
map: value,
|
|
registry: self.registry,
|
|
}
|
|
.serialize(serializer),
|
|
ReflectRef::Value(value) => ReflectValueSerializer {
|
|
registry: self.registry,
|
|
value,
|
|
}
|
|
.serialize(serializer),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct ReflectValueSerializer<'a> {
|
|
pub registry: &'a TypeRegistry,
|
|
pub value: &'a dyn Reflect,
|
|
}
|
|
|
|
impl<'a> Serialize for ReflectValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
state.serialize_entry(type_fields::TYPE, self.value.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::VALUE,
|
|
get_serializable::<S::Error>(self.value, self.registry)?.borrow(),
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct StructSerializer<'a> {
|
|
pub struct_value: &'a dyn Struct,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for StructSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
|
|
state.serialize_entry(type_fields::TYPE, self.struct_value.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::STRUCT,
|
|
&StructValueSerializer {
|
|
struct_value: self.struct_value,
|
|
registry: self.registry,
|
|
},
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct StructValueSerializer<'a> {
|
|
pub struct_value: &'a dyn Struct,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for StructValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(self.struct_value.field_len()))?;
|
|
for (index, value) in self.struct_value.iter_fields().enumerate() {
|
|
let key = self.struct_value.name_at(index).unwrap();
|
|
state.serialize_entry(key, &ReflectSerializer::new(value, self.registry))?;
|
|
}
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct TupleStructSerializer<'a> {
|
|
pub tuple_struct: &'a dyn TupleStruct,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for TupleStructSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
|
|
state.serialize_entry(type_fields::TYPE, self.tuple_struct.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::TUPLE_STRUCT,
|
|
&TupleStructValueSerializer {
|
|
tuple_struct: self.tuple_struct,
|
|
registry: self.registry,
|
|
},
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct TupleStructValueSerializer<'a> {
|
|
pub tuple_struct: &'a dyn TupleStruct,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for TupleStructValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_seq(Some(self.tuple_struct.field_len()))?;
|
|
for value in self.tuple_struct.iter_fields() {
|
|
state.serialize_element(&ReflectSerializer::new(value, self.registry))?;
|
|
}
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct TupleSerializer<'a> {
|
|
pub tuple: &'a dyn Tuple,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for TupleSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
|
|
state.serialize_entry(type_fields::TYPE, self.tuple.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::TUPLE,
|
|
&TupleValueSerializer {
|
|
tuple: self.tuple,
|
|
registry: self.registry,
|
|
},
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct TupleValueSerializer<'a> {
|
|
pub tuple: &'a dyn Tuple,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for TupleValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_seq(Some(self.tuple.field_len()))?;
|
|
for value in self.tuple.iter_fields() {
|
|
state.serialize_element(&ReflectSerializer::new(value, self.registry))?;
|
|
}
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct MapSerializer<'a> {
|
|
pub map: &'a dyn Map,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for MapSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
|
|
state.serialize_entry(type_fields::TYPE, self.map.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::MAP,
|
|
&MapValueSerializer {
|
|
map: self.map,
|
|
registry: self.registry,
|
|
},
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct MapValueSerializer<'a> {
|
|
pub map: &'a dyn Map,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for MapValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(self.map.len()))?;
|
|
for (key, value) in self.map.iter() {
|
|
state.serialize_entry(
|
|
&ReflectSerializer::new(key, self.registry),
|
|
&ReflectSerializer::new(value, self.registry),
|
|
)?;
|
|
}
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct ListSerializer<'a> {
|
|
pub list: &'a dyn List,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for ListSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
state.serialize_entry(type_fields::TYPE, self.list.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::LIST,
|
|
&ListValueSerializer {
|
|
list: self.list,
|
|
registry: self.registry,
|
|
},
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct ListValueSerializer<'a> {
|
|
pub list: &'a dyn List,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for ListValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_seq(Some(self.list.len()))?;
|
|
for value in self.list.iter() {
|
|
state.serialize_element(&ReflectSerializer::new(value, self.registry))?;
|
|
}
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct ArraySerializer<'a> {
|
|
pub array: &'a dyn Array,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for ArraySerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_map(Some(2))?;
|
|
state.serialize_entry(type_fields::TYPE, self.array.type_name())?;
|
|
state.serialize_entry(
|
|
type_fields::ARRAY,
|
|
&ArrayValueSerializer {
|
|
array: self.array,
|
|
registry: self.registry,
|
|
},
|
|
)?;
|
|
state.end()
|
|
}
|
|
}
|
|
|
|
pub struct ArrayValueSerializer<'a> {
|
|
pub array: &'a dyn Array,
|
|
pub registry: &'a TypeRegistry,
|
|
}
|
|
|
|
impl<'a> Serialize for ArrayValueSerializer<'a> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
let mut state = serializer.serialize_seq(Some(self.array.len()))?;
|
|
for value in self.array.iter() {
|
|
state.serialize_element(&ReflectSerializer::new(value, self.registry))?;
|
|
}
|
|
state.end()
|
|
}
|
|
}
|