bevy/crates/bevy_reflect/src/serde/ser.rs
Jakob Hellermann 218b0fd3b6 bevy_reflect: put serialize into external ReflectSerialize type (#4782)
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()`
2022-06-20 17:18:58 +00:00

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()
}
}