Allow providing CustomInternalSchemaData instead of only adding data for
forcing as array.
This commit is contained in:
parent
5ad2351c2a
commit
2800e77ef9
@ -1866,12 +1866,12 @@ mod tests {
|
||||
|
||||
let atr = AppTypeRegistry::default();
|
||||
{
|
||||
use crate::schemas::ReflectJsonSchemaForceAsArray;
|
||||
use crate::schemas::RegisterReflectJsonSchemas;
|
||||
|
||||
let mut register = atr.write();
|
||||
register.register::<NestedStruct>();
|
||||
register.register::<bevy_math::Vec3>();
|
||||
register.register_type_data::<bevy_math::Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
register.register_force_as_array::<bevy_math::Vec3>();
|
||||
}
|
||||
let mut world = World::new();
|
||||
world.insert_resource(atr);
|
||||
|
||||
@ -7,12 +7,16 @@ use bevy_ecs::{
|
||||
};
|
||||
use bevy_platform::collections::HashMap;
|
||||
use bevy_reflect::{
|
||||
prelude::ReflectDefault, FromType, Reflect, ReflectDeserialize, ReflectSerialize, TypeData,
|
||||
TypeRegistration,
|
||||
prelude::ReflectDefault, FromType, GetTypeRegistration, Reflect, ReflectDeserialize,
|
||||
ReflectSerialize, TypeData, TypePath, TypeRegistration,
|
||||
};
|
||||
use core::any::TypeId;
|
||||
|
||||
use crate::schemas::{json_schema::JsonSchemaBevyType, open_rpc::OpenRpcDocument};
|
||||
use crate::schemas::{
|
||||
json_schema::JsonSchemaBevyType,
|
||||
open_rpc::OpenRpcDocument,
|
||||
reflect_info::{FieldsInformation, InternalSchemaType},
|
||||
};
|
||||
|
||||
pub mod json_schema;
|
||||
pub mod open_rpc;
|
||||
@ -27,13 +31,23 @@ pub struct SchemaTypesMetadata {
|
||||
pub type_data_map: HashMap<TypeId, Cow<'static, str>>,
|
||||
}
|
||||
|
||||
/// Reflect-compatible custom JSON Schema for this type
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectJsonSchemaForceAsArray;
|
||||
/// Custom internal schema data.
|
||||
#[derive(Debug, Resource, Reflect, Clone)]
|
||||
#[reflect(Resource)]
|
||||
pub struct CustomInternalSchemaData(pub InternalSchemaType);
|
||||
|
||||
impl<T: Reflect> FromType<T> for ReflectJsonSchemaForceAsArray {
|
||||
fn from_type() -> Self {
|
||||
ReflectJsonSchemaForceAsArray
|
||||
impl CustomInternalSchemaData {
|
||||
/// Creates a new `CustomInternalSchema` with a forced array type. Works for structs only.
|
||||
pub fn force_array<T: GetTypeRegistration>() -> Option<Self> {
|
||||
match T::get_type_registration().type_info() {
|
||||
bevy_reflect::TypeInfo::Struct(struct_info) => Some(CustomInternalSchemaData(
|
||||
InternalSchemaType::FieldsHolder(FieldsInformation::new(
|
||||
struct_info.iter(),
|
||||
reflect_info::FieldType::ForceUnnamed,
|
||||
)),
|
||||
)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,62 +57,76 @@ pub(crate) trait RegisterReflectJsonSchemas {
|
||||
fn register_schema_base_types(&mut self) {
|
||||
#[cfg(feature = "bevy_math")]
|
||||
{
|
||||
self.register_type_data_internal::<bevy_math::Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::DVec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I8Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U8Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I16Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U16Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::IVec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::UVec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I64Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U64Vec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::BVec2, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_force_as_array::<bevy_math::Vec2>();
|
||||
self.register_force_as_array::<bevy_math::DVec2>();
|
||||
self.register_force_as_array::<bevy_math::I8Vec2>();
|
||||
self.register_force_as_array::<bevy_math::U8Vec2>();
|
||||
self.register_force_as_array::<bevy_math::I16Vec2>();
|
||||
self.register_force_as_array::<bevy_math::U16Vec2>();
|
||||
self.register_force_as_array::<bevy_math::IVec2>();
|
||||
self.register_force_as_array::<bevy_math::UVec2>();
|
||||
self.register_force_as_array::<bevy_math::I64Vec2>();
|
||||
self.register_force_as_array::<bevy_math::U64Vec2>();
|
||||
self.register_force_as_array::<bevy_math::BVec2>();
|
||||
|
||||
self.register_type_data_internal::<bevy_math::Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::DVec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I8Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U8Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I16Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U16Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::IVec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::UVec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I64Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U64Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::BVec3, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_force_as_array::<bevy_math::Vec3>();
|
||||
self.register_force_as_array::<bevy_math::DVec3>();
|
||||
self.register_force_as_array::<bevy_math::I8Vec3>();
|
||||
self.register_force_as_array::<bevy_math::U8Vec3>();
|
||||
self.register_force_as_array::<bevy_math::I16Vec3>();
|
||||
self.register_force_as_array::<bevy_math::U16Vec3>();
|
||||
self.register_force_as_array::<bevy_math::IVec3>();
|
||||
self.register_force_as_array::<bevy_math::UVec3>();
|
||||
self.register_force_as_array::<bevy_math::I64Vec3>();
|
||||
self.register_force_as_array::<bevy_math::U64Vec3>();
|
||||
self.register_force_as_array::<bevy_math::BVec3>();
|
||||
|
||||
self.register_type_data_internal::<bevy_math::Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::DVec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I8Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U8Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I16Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U16Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::IVec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::UVec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::I64Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::U64Vec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::BVec4, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_force_as_array::<bevy_math::Vec4>();
|
||||
self.register_force_as_array::<bevy_math::DVec4>();
|
||||
self.register_force_as_array::<bevy_math::I8Vec4>();
|
||||
self.register_force_as_array::<bevy_math::U8Vec4>();
|
||||
self.register_force_as_array::<bevy_math::I16Vec4>();
|
||||
self.register_force_as_array::<bevy_math::U16Vec4>();
|
||||
self.register_force_as_array::<bevy_math::IVec4>();
|
||||
self.register_force_as_array::<bevy_math::UVec4>();
|
||||
self.register_force_as_array::<bevy_math::I64Vec4>();
|
||||
self.register_force_as_array::<bevy_math::U64Vec4>();
|
||||
self.register_force_as_array::<bevy_math::BVec4>();
|
||||
|
||||
self.register_type_data_internal::<bevy_math::Quat, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_type_data_internal::<bevy_math::DQuat, ReflectJsonSchemaForceAsArray>();
|
||||
self.register_force_as_array::<bevy_math::Quat>();
|
||||
self.register_force_as_array::<bevy_math::DQuat>();
|
||||
}
|
||||
self.register_type_internal::<OpenRpcDocument>();
|
||||
self.register_type_data_internal::<OpenRpcDocument, ReflectJsonSchema>();
|
||||
}
|
||||
/// Registers a type by value.
|
||||
fn register_data_type_by_value<T, D>(&mut self, data: D)
|
||||
where
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
D: TypeData;
|
||||
fn register_type_internal<T>(&mut self)
|
||||
where
|
||||
T: bevy_reflect::GetTypeRegistration;
|
||||
T: GetTypeRegistration;
|
||||
|
||||
fn register_type_data_internal<T, D>(&mut self)
|
||||
where
|
||||
T: Reflect + bevy_reflect::TypePath + bevy_reflect::GetTypeRegistration,
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
D: TypeData + FromType<T>;
|
||||
fn register_force_as_array<T>(&mut self)
|
||||
where
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
{
|
||||
let Some(data) = CustomInternalSchemaData::force_array::<T>() else {
|
||||
return;
|
||||
};
|
||||
self.register_data_type_by_value::<T, CustomInternalSchemaData>(data);
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterReflectJsonSchemas for bevy_reflect::TypeRegistry {
|
||||
fn register_type_data_internal<T, D>(&mut self)
|
||||
where
|
||||
T: Reflect + bevy_reflect::TypePath + bevy_reflect::GetTypeRegistration,
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
D: TypeData + FromType<T>,
|
||||
{
|
||||
if !self.contains(TypeId::of::<T>()) {
|
||||
@ -109,15 +137,25 @@ impl RegisterReflectJsonSchemas for bevy_reflect::TypeRegistry {
|
||||
|
||||
fn register_type_internal<T>(&mut self)
|
||||
where
|
||||
T: bevy_reflect::GetTypeRegistration,
|
||||
T: GetTypeRegistration,
|
||||
{
|
||||
self.register::<T>();
|
||||
}
|
||||
|
||||
fn register_data_type_by_value<T, D>(&mut self, data: D)
|
||||
where
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
D: TypeData,
|
||||
{
|
||||
self.get_mut(TypeId::of::<T>())
|
||||
.expect("SHOULD NOT HAPPENED")
|
||||
.insert(data);
|
||||
}
|
||||
}
|
||||
impl RegisterReflectJsonSchemas for bevy_app::App {
|
||||
fn register_type_data_internal<T, D>(&mut self)
|
||||
where
|
||||
T: Reflect + bevy_reflect::TypePath + bevy_reflect::GetTypeRegistration,
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
D: TypeData + FromType<T>,
|
||||
{
|
||||
self.register_type::<T>();
|
||||
@ -126,10 +164,22 @@ impl RegisterReflectJsonSchemas for bevy_app::App {
|
||||
|
||||
fn register_type_internal<T>(&mut self)
|
||||
where
|
||||
T: bevy_reflect::GetTypeRegistration,
|
||||
T: GetTypeRegistration,
|
||||
{
|
||||
self.register_type::<T>();
|
||||
}
|
||||
|
||||
fn register_data_type_by_value<T, D>(&mut self, data: D)
|
||||
where
|
||||
T: Reflect + TypePath + GetTypeRegistration,
|
||||
D: TypeData,
|
||||
{
|
||||
let sub_app = self.main_mut();
|
||||
let world = sub_app.world_mut();
|
||||
let registry = world.resource_mut::<bevy_ecs::reflect::AppTypeRegistry>();
|
||||
let mut r = registry.write();
|
||||
r.register_data_type_by_value::<T, D>(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// Reflect-compatible custom JSON Schema for this type
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
use crate::schemas::json_schema::{
|
||||
JsonSchemaBevyType, JsonSchemaVariant, SchemaKind, SchemaType, SchemaTypeVariant,
|
||||
};
|
||||
use crate::schemas::{ReflectJsonSchemaForceAsArray, SchemaTypesMetadata};
|
||||
use crate::schemas::{CustomInternalSchemaData, SchemaTypesMetadata};
|
||||
use alloc::borrow::Cow;
|
||||
use alloc::sync::Arc;
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
@ -298,8 +298,8 @@ impl From<&TypePathTable> for TypeReferenceId {
|
||||
}
|
||||
|
||||
/// Information about the field type.
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
|
||||
pub(crate) enum FieldType {
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default, Reflect)]
|
||||
pub enum FieldType {
|
||||
/// Named field type.
|
||||
Named,
|
||||
/// Unnamed field type.
|
||||
@ -310,8 +310,8 @@ pub(crate) enum FieldType {
|
||||
}
|
||||
|
||||
/// Information about the attributes of a field.
|
||||
#[derive(Clone, Debug, Deref, DerefMut, Default)]
|
||||
pub(crate) struct FieldsInformation {
|
||||
#[derive(Clone, Debug, Deref, DerefMut, Default, Reflect)]
|
||||
pub struct FieldsInformation {
|
||||
/// Fields information.
|
||||
#[deref]
|
||||
fields: Vec<SchemaFieldData>,
|
||||
@ -319,6 +319,19 @@ pub(crate) struct FieldsInformation {
|
||||
fields_type: FieldType,
|
||||
}
|
||||
|
||||
impl FieldsInformation {
|
||||
/// Creates a new instance of `FieldsInformation`.
|
||||
pub fn new<'a, 'b, T>(iterator: Iter<'a, T>, fields_type: FieldType) -> Self
|
||||
where
|
||||
SchemaFieldData: From<&'a T>,
|
||||
{
|
||||
FieldsInformation {
|
||||
fields: get_fields_information(iterator),
|
||||
fields_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deref)]
|
||||
/// Information about the attributes of a field.
|
||||
pub(crate) struct AttributesInformation(Arc<TypeIdMap<Box<dyn Reflect>>>);
|
||||
@ -385,30 +398,20 @@ fn try_get_regex_for_type(id: TypeId) -> Option<Cow<'static, str>> {
|
||||
}
|
||||
|
||||
/// Represents the data of a field in a schema.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct SchemaFieldData {
|
||||
#[derive(Clone, Reflect, Debug)]
|
||||
pub struct SchemaFieldData {
|
||||
/// Name of the field.
|
||||
pub name: Option<Cow<'static, str>>,
|
||||
/// Index of the field. Can be provided for named fields when the data is obtained from containing struct definition.
|
||||
pub index: Option<usize>,
|
||||
/// Description of the field.
|
||||
pub description: Option<Cow<'static, str>>,
|
||||
/// Attributes of the field.
|
||||
pub attributes: AttributesInformation,
|
||||
/// Custom of the field.
|
||||
pub range: Option<MinMaxValues>,
|
||||
/// Type of the field.
|
||||
pub type_id: TypeId,
|
||||
}
|
||||
|
||||
impl Debug for SchemaFieldData {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("SchemaFieldData")
|
||||
.field("name", &self.name)
|
||||
.field("index", &self.index)
|
||||
.field("description", &self.description)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl SchemaFieldData {
|
||||
/// Returns the name of the field.
|
||||
pub fn to_name(&self) -> Cow<'static, str> {
|
||||
@ -810,11 +813,28 @@ impl From<TypeId> for MinMaxValues {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Enum representing the internal schema type information for different Rust types.
|
||||
#[derive(Clone, Debug, Reflect)]
|
||||
pub enum SchemaEnumType {
|
||||
/// Represents a constant value.
|
||||
Const,
|
||||
/// Represents a set of fields with their respective types.
|
||||
Fields(FieldsInformation),
|
||||
}
|
||||
|
||||
/// Represents a variant of an enum type.
|
||||
#[derive(Clone, Debug, Reflect)]
|
||||
pub struct EnumVariantInfo {
|
||||
/// Field data for the enum variant.
|
||||
pub field_data: SchemaFieldData,
|
||||
/// Information about the enum variant.
|
||||
pub info: SchemaEnumType,
|
||||
}
|
||||
|
||||
/// Enum representing the internal schema type information for different Rust types.
|
||||
/// This enum categorizes how different types should be represented in JSON schema.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum InternalSchemaType {
|
||||
#[derive(Clone, Debug, Reflect)]
|
||||
pub enum InternalSchemaType {
|
||||
/// Represents array-like types (Vec, arrays, lists, sets).
|
||||
Array {
|
||||
/// Element type information for the array.
|
||||
@ -825,13 +845,13 @@ pub(crate) enum InternalSchemaType {
|
||||
max_size: Option<u64>,
|
||||
},
|
||||
/// Holds all variants of an enum type.
|
||||
EnumHolder(Vec<VariantInfo>),
|
||||
EnumHolder(Vec<EnumVariantInfo>),
|
||||
/// Holds named fields for struct, tuple, and tuple struct types.
|
||||
FieldsHolder(FieldsInformation),
|
||||
/// Represents an Optional type (e.g., `Option<T>`).
|
||||
Optional {
|
||||
/// Generic information about the wrapped type `T` in `Option<T>`.
|
||||
generic: GenericInfo,
|
||||
/// Type information for the wrapped type `T` in `Option<T>`.
|
||||
generic: TypeId,
|
||||
},
|
||||
/// Represents a Map type (e.g., `HashMap`<K, V>).
|
||||
Map {
|
||||
@ -867,6 +887,9 @@ impl InternalSchemaType {
|
||||
value: &TypeRegistration,
|
||||
registry: &TypeRegistry,
|
||||
) -> InternalSchemaType {
|
||||
if let Some(data) = value.data::<CustomInternalSchemaData>() {
|
||||
return data.0.clone();
|
||||
}
|
||||
if let Some(primitive) =
|
||||
SchemaType::try_get_primitive_type_from_type_id(value.type_info().type_id())
|
||||
{
|
||||
@ -879,14 +902,9 @@ impl InternalSchemaType {
|
||||
match value.type_info() {
|
||||
TypeInfo::Struct(struct_info) => {
|
||||
let fields = get_fields_information(struct_info.iter());
|
||||
let fields_type = if value.data::<ReflectJsonSchemaForceAsArray>().is_some() {
|
||||
FieldType::ForceUnnamed
|
||||
} else {
|
||||
FieldType::Named
|
||||
};
|
||||
InternalSchemaType::FieldsHolder(FieldsInformation {
|
||||
fields,
|
||||
fields_type,
|
||||
fields_type: FieldType::Named,
|
||||
})
|
||||
}
|
||||
TypeInfo::TupleStruct(info) => {
|
||||
@ -916,8 +934,10 @@ impl InternalSchemaType {
|
||||
fields_type: FieldType::Unnamed,
|
||||
}),
|
||||
TypeInfo::Enum(enum_info) => match enum_info.try_get_optional() {
|
||||
Some(e) => InternalSchemaType::Optional { generic: e.clone() },
|
||||
None => InternalSchemaType::EnumHolder(enum_info.iter().cloned().collect()),
|
||||
Some(e) => InternalSchemaType::Optional {
|
||||
generic: e.ty().id(),
|
||||
},
|
||||
None => InternalSchemaType::EnumHolder(get_enum_information(enum_info.iter())),
|
||||
},
|
||||
|
||||
TypeInfo::List(list_info) => InternalSchemaType::Array {
|
||||
@ -960,23 +980,15 @@ impl InternalSchemaType {
|
||||
}
|
||||
}
|
||||
InternalSchemaType::EnumHolder(variant_infos) => {
|
||||
for variant_info in variant_infos {
|
||||
let subschema = match variant_info {
|
||||
VariantInfo::Struct(struct_variant_info) => {
|
||||
InternalSchemaType::FieldsHolder(FieldsInformation {
|
||||
fields: get_fields_information(struct_variant_info.iter()),
|
||||
fields_type: FieldType::Named,
|
||||
})
|
||||
for variant_info in variant_infos.iter() {
|
||||
let variant_dependencies = match &variant_info.info {
|
||||
SchemaEnumType::Const => continue,
|
||||
SchemaEnumType::Fields(fields_information) => {
|
||||
InternalSchemaType::FieldsHolder(fields_information.clone())
|
||||
.get_dependencies(registry)
|
||||
}
|
||||
VariantInfo::Tuple(tuple_variant_info) => {
|
||||
InternalSchemaType::FieldsHolder(FieldsInformation {
|
||||
fields: get_fields_information(tuple_variant_info.iter()),
|
||||
fields_type: FieldType::Unnamed,
|
||||
})
|
||||
}
|
||||
VariantInfo::Unit(_) => continue,
|
||||
};
|
||||
dependencies.extend(subschema.get_dependencies(registry));
|
||||
dependencies.extend(variant_dependencies);
|
||||
}
|
||||
}
|
||||
InternalSchemaType::FieldsHolder(fields_information) => {
|
||||
@ -995,7 +1007,7 @@ impl InternalSchemaType {
|
||||
}
|
||||
}
|
||||
InternalSchemaType::Optional { generic } => {
|
||||
if let Some(reg) = registry.get(generic.type_id()) {
|
||||
if let Some(reg) = registry.get(*generic) {
|
||||
if SchemaType::try_get_primitive_type_from_type_id(reg.type_id()).is_none() {
|
||||
let subschema = InternalSchemaType::from_type_registration(reg, registry);
|
||||
if !subschema.is_optional() {
|
||||
@ -1157,13 +1169,13 @@ pub trait AttributeInfoReflect {
|
||||
|
||||
impl From<&UnnamedField> for SchemaFieldData {
|
||||
fn from(value: &UnnamedField) -> Self {
|
||||
let attributes: AttributesInformation = value.custom_attributes().into();
|
||||
let range = value.custom_attributes().get_range_by_id(value.type_id());
|
||||
#[cfg(feature = "documentation")]
|
||||
let description = value.docs().map(|s| Cow::Owned(s.to_owned()));
|
||||
#[cfg(not(feature = "documentation"))]
|
||||
let description = None;
|
||||
SchemaFieldData {
|
||||
attributes,
|
||||
range,
|
||||
name: None,
|
||||
index: Some(value.index()),
|
||||
description,
|
||||
@ -1173,7 +1185,7 @@ impl From<&UnnamedField> for SchemaFieldData {
|
||||
}
|
||||
impl From<&NamedField> for SchemaFieldData {
|
||||
fn from(value: &NamedField) -> Self {
|
||||
let attributes: AttributesInformation = value.custom_attributes().into();
|
||||
let range = value.custom_attributes().get_range_by_id(value.type_id());
|
||||
#[cfg(feature = "documentation")]
|
||||
let description = value.docs().map(|s| Cow::Owned(s.to_owned()));
|
||||
#[cfg(not(feature = "documentation"))]
|
||||
@ -1182,7 +1194,7 @@ impl From<&NamedField> for SchemaFieldData {
|
||||
name: Some(value.name().into()),
|
||||
index: None,
|
||||
description,
|
||||
attributes,
|
||||
range,
|
||||
type_id: value.type_id(),
|
||||
}
|
||||
}
|
||||
@ -1190,6 +1202,7 @@ impl From<&NamedField> for SchemaFieldData {
|
||||
|
||||
impl From<&VariantInfo> for SchemaFieldData {
|
||||
fn from(value: &VariantInfo) -> Self {
|
||||
let range = value.custom_attributes().get_range_by_id(value.type_id());
|
||||
#[cfg(feature = "documentation")]
|
||||
let description = value.docs().map(|s| Cow::Owned(s.to_owned()));
|
||||
#[cfg(not(feature = "documentation"))]
|
||||
@ -1198,12 +1211,38 @@ impl From<&VariantInfo> for SchemaFieldData {
|
||||
name: Some(value.name().to_owned().into()),
|
||||
index: None,
|
||||
description,
|
||||
attributes: value.custom_attributes().into(),
|
||||
range,
|
||||
type_id: value.type_id(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_enum_information<'a>(iterator: Iter<'a, VariantInfo>) -> Vec<EnumVariantInfo> {
|
||||
iterator
|
||||
.map(|variant| {
|
||||
let info = match variant {
|
||||
VariantInfo::Struct(struct_variant_info) => {
|
||||
SchemaEnumType::Fields(FieldsInformation {
|
||||
fields: get_fields_information(struct_variant_info.iter()),
|
||||
fields_type: FieldType::Named,
|
||||
})
|
||||
}
|
||||
VariantInfo::Tuple(tuple_variant_info) => {
|
||||
SchemaEnumType::Fields(FieldsInformation {
|
||||
fields: get_fields_information(tuple_variant_info.iter()),
|
||||
fields_type: FieldType::Unnamed,
|
||||
})
|
||||
}
|
||||
VariantInfo::Unit(_) => SchemaEnumType::Const,
|
||||
};
|
||||
EnumVariantInfo {
|
||||
info,
|
||||
field_data: variant.into(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_fields_information<'a, 'b, T>(iterator: Iter<'a, T>) -> Vec<SchemaFieldData>
|
||||
where
|
||||
SchemaFieldData: From<&'a T>,
|
||||
@ -1218,36 +1257,29 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn variant_to_definition(
|
||||
variant: &VariantInfo,
|
||||
variant: &EnumVariantInfo,
|
||||
registry: &TypeRegistry,
|
||||
) -> JsonSchemaBevyType {
|
||||
let field_data: SchemaFieldData = variant.into();
|
||||
let mut schema = JsonSchemaBevyType {
|
||||
description: field_data.to_description(),
|
||||
description: variant.field_data.to_description(),
|
||||
kind: Some(SchemaKind::Value),
|
||||
schema_type: Some(SchemaTypeVariant::Single(SchemaType::Object)),
|
||||
additional_properties: Some(JsonSchemaVariant::BoolValue(false)),
|
||||
..Default::default()
|
||||
};
|
||||
let fields_info = match variant {
|
||||
VariantInfo::Unit(unit_variant_info) => {
|
||||
schema.const_value = Some(unit_variant_info.name().to_string().into());
|
||||
let name = variant.field_data.name.as_ref().expect("").to_string();
|
||||
let fields_info = match &variant.info {
|
||||
SchemaEnumType::Const => {
|
||||
schema.const_value = Some(name.into());
|
||||
schema.schema_type = Some(SchemaTypeVariant::Single(SchemaType::String));
|
||||
schema.additional_properties = None;
|
||||
return schema;
|
||||
}
|
||||
VariantInfo::Struct(struct_variant_info) => FieldsInformation {
|
||||
fields: get_fields_information(struct_variant_info.iter()),
|
||||
fields_type: FieldType::Named,
|
||||
},
|
||||
VariantInfo::Tuple(tuple_variant_info) => FieldsInformation {
|
||||
fields: get_fields_information(tuple_variant_info.iter()),
|
||||
fields_type: FieldType::Unnamed,
|
||||
},
|
||||
SchemaEnumType::Fields(fields_information) => fields_information,
|
||||
};
|
||||
let mut subschema = JsonSchemaBevyType::default();
|
||||
registry.update_schema_with_fields_info(&mut subschema, &fields_info);
|
||||
schema.properties = [(variant.name().into(), subschema.into())].into();
|
||||
registry.update_schema_with_fields_info(&mut subschema, fields_info);
|
||||
schema.properties = [(name.into(), subschema.into())].into();
|
||||
schema
|
||||
}
|
||||
|
||||
@ -1444,7 +1476,7 @@ impl TypeDefinitionBuilder for TypeRegistry {
|
||||
InternalSchemaType::Optional { generic } => {
|
||||
id = None;
|
||||
let optional_schema = self
|
||||
.build_schema_reference_for_type_id(generic.type_id(), None)
|
||||
.build_schema_reference_for_type_id(generic, None)
|
||||
.unwrap_or_default();
|
||||
|
||||
schema.ref_type = None;
|
||||
@ -1529,16 +1561,10 @@ impl TypeDefinitionBuilder for TypeRegistry {
|
||||
});
|
||||
schema.kind = Some(data.schema_kind);
|
||||
}
|
||||
if let Some(field_range) = field_data
|
||||
.as_ref()
|
||||
.and_then(|d| d.attributes.get_range_by_id(type_id))
|
||||
{
|
||||
if let Some(field_range) = field_data.as_ref().and_then(|d| d.range) {
|
||||
range = range.with(field_range);
|
||||
}
|
||||
if let Some(field_range) = p_field_data
|
||||
.as_ref()
|
||||
.and_then(|d| d.attributes.get_range_by_id(type_id))
|
||||
{
|
||||
if let Some(field_range) = p_field_data.as_ref().and_then(|d| d.range) {
|
||||
range = range.with(field_range);
|
||||
}
|
||||
|
||||
@ -1584,7 +1610,7 @@ impl TypeDefinitionBuilder for TypeRegistry {
|
||||
}
|
||||
InternalSchemaType::Optional { generic } => {
|
||||
let schema_optional = self
|
||||
.build_schema_reference_for_type_id(generic.ty().id(), None)
|
||||
.build_schema_reference_for_type_id(generic, None)
|
||||
.unwrap_or_default();
|
||||
schema.ref_type = None;
|
||||
schema.one_of = vec![
|
||||
@ -1749,10 +1775,12 @@ pub(super) mod tests {
|
||||
}
|
||||
let atr = AppTypeRegistry::default();
|
||||
{
|
||||
use crate::schemas::RegisterReflectJsonSchemas;
|
||||
|
||||
let mut register = atr.write();
|
||||
register.register::<bevy_math::Vec3>();
|
||||
register.register::<Foo>();
|
||||
register.register_type_data::<bevy_math::Vec3, ReflectJsonSchemaForceAsArray>();
|
||||
register.register_force_as_array::<bevy_math::Vec3>();
|
||||
}
|
||||
let type_registry = atr.read();
|
||||
let (_, schema) = type_registry
|
||||
|
||||
Loading…
Reference in New Issue
Block a user