Start populating schema definitons field
This commit is contained in:
parent
27366c9f4f
commit
5ea21b4705
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::schemas::{
|
use crate::schemas::{
|
||||||
reflect_info::{SchemaNumber, TypeReferenceId, TypeReferencePath},
|
reflect_info::{SchemaNumber, TypeInformation, TypeReferenceId, TypeReferencePath},
|
||||||
ReflectJsonSchema, SchemaTypesMetadata,
|
ReflectJsonSchema, SchemaTypesMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,13 +82,12 @@ impl TryFrom<(&TypeRegistration, &SchemaTypesMetadata)> for JsonSchemaBevyType {
|
|||||||
if let Some(s) = reg.data::<ReflectJsonSchema>() {
|
if let Some(s) = reg.data::<ReflectJsonSchema>() {
|
||||||
return Ok(s.0.clone());
|
return Ok(s.0.clone());
|
||||||
}
|
}
|
||||||
let base_schema = super::reflect_info::build_schema(reg);
|
let (_, mut typed_schema) = TypeInformation::from(reg)
|
||||||
|
.to_schema_type_info()
|
||||||
|
.to_definition();
|
||||||
|
|
||||||
let JsonSchemaVariant::Schema(mut typed_schema) = base_schema else {
|
|
||||||
return Err(InvalidJsonSchema::InvalidType);
|
|
||||||
};
|
|
||||||
typed_schema.reflect_type_data = metadata.get_registered_reflect_types(reg);
|
typed_schema.reflect_type_data = metadata.get_registered_reflect_types(reg);
|
||||||
Ok(*typed_schema)
|
Ok(typed_schema)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +141,8 @@ pub struct JsonSchemaBevyType {
|
|||||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||||
pub reflect_type_data: Vec<Cow<'static, str>>,
|
pub reflect_type_data: Vec<Cow<'static, str>>,
|
||||||
/// Bevy specific field, [`TypeInfo`] type mapping.
|
/// Bevy specific field, [`TypeInfo`] type mapping.
|
||||||
pub kind: SchemaKind,
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||||
|
pub kind: Option<SchemaKind>,
|
||||||
/// JSON Schema specific field.
|
/// JSON Schema specific field.
|
||||||
/// This keyword is used to reference a constant value.
|
/// This keyword is used to reference a constant value.
|
||||||
#[serde(rename = "const")]
|
#[serde(rename = "const")]
|
||||||
@ -245,7 +245,7 @@ pub struct JsonSchemaBevyType {
|
|||||||
#[serde(skip_serializing_if = "HashMap::is_empty", default)]
|
#[serde(skip_serializing_if = "HashMap::is_empty", default)]
|
||||||
#[reflect(ignore)]
|
#[reflect(ignore)]
|
||||||
#[serde(rename = "$defs")]
|
#[serde(rename = "$defs")]
|
||||||
pub definitions: HashMap<TypeReferenceId, Box<JsonSchemaVariant>>,
|
pub definitions: HashMap<TypeReferenceId, JsonSchemaVariant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents different types of JSON Schema values that can be used in schema definitions.
|
/// Represents different types of JSON Schema values that can be used in schema definitions.
|
||||||
@ -267,6 +267,12 @@ pub enum JsonSchemaVariant {
|
|||||||
Schema(#[reflect(ignore)] Box<JsonSchemaBevyType>),
|
Schema(#[reflect(ignore)] Box<JsonSchemaBevyType>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<JsonSchemaBevyType> for JsonSchemaVariant {
|
||||||
|
fn from(value: JsonSchemaBevyType) -> Self {
|
||||||
|
JsonSchemaVariant::Schema(Box::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Kind of json schema, maps [`TypeInfo`] type
|
/// Kind of json schema, maps [`TypeInfo`] type
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default, Reflect)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default, Reflect)]
|
||||||
pub enum SchemaKind {
|
pub enum SchemaKind {
|
||||||
@ -372,9 +378,7 @@ impl From<TypeId> for SchemaType {
|
|||||||
|| value.eq(&TypeId::of::<u64>())
|
|| value.eq(&TypeId::of::<u64>())
|
||||||
|| value.eq(&TypeId::of::<u128>())
|
|| value.eq(&TypeId::of::<u128>())
|
||||||
|| value.eq(&TypeId::of::<usize>())
|
|| value.eq(&TypeId::of::<usize>())
|
||||||
{
|
|| value.eq(&TypeId::of::<i8>())
|
||||||
Self::Integer
|
|
||||||
} else if value.eq(&TypeId::of::<i8>())
|
|
||||||
|| value.eq(&TypeId::of::<i16>())
|
|| value.eq(&TypeId::of::<i16>())
|
||||||
|| value.eq(&TypeId::of::<i32>())
|
|| value.eq(&TypeId::of::<i32>())
|
||||||
|| value.eq(&TypeId::of::<i64>())
|
|| value.eq(&TypeId::of::<i64>())
|
||||||
@ -679,12 +683,9 @@ mod tests {
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"a": {
|
"a": {
|
||||||
"kind": "Value",
|
|
||||||
"maximum": 65535,
|
"maximum": 65535,
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"shortPath": "u16",
|
|
||||||
"typePath": "u16",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -99,6 +99,12 @@ impl From<&Type> for TypeReferenceId {
|
|||||||
TypeReferenceId(t.path().replace("::", "-").into())
|
TypeReferenceId(t.path().replace("::", "-").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&TypePathTable> for TypeReferenceId {
|
||||||
|
fn from(t: &TypePathTable) -> Self {
|
||||||
|
TypeReferenceId(t.path().replace("::", "-").into())
|
||||||
|
}
|
||||||
|
}
|
||||||
impl From<&str> for TypeReferenceId {
|
impl From<&str> for TypeReferenceId {
|
||||||
fn from(t: &str) -> Self {
|
fn from(t: &str) -> Self {
|
||||||
TypeReferenceId(t.replace("::", "-").into())
|
TypeReferenceId(t.replace("::", "-").into())
|
||||||
@ -126,14 +132,18 @@ pub enum FieldType {
|
|||||||
|
|
||||||
/// Information about the attributes of a field.
|
/// Information about the attributes of a field.
|
||||||
#[derive(Clone, Debug, Deref, DerefMut, Default)]
|
#[derive(Clone, Debug, Deref, DerefMut, Default)]
|
||||||
pub struct FieldsInformation(#[deref] pub Vec<FieldInformation>, FieldType);
|
pub struct FieldsInformation {
|
||||||
|
/// Fields information.
|
||||||
|
#[deref]
|
||||||
|
fields: Vec<FieldInformation>,
|
||||||
|
/// Field type information.
|
||||||
|
fields_type: FieldType,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&TypeInformation> for Option<FieldsInformation> {
|
impl From<&TypeInformation> for Option<FieldsInformation> {
|
||||||
fn from(value: &TypeInformation) -> Self {
|
fn from(value: &TypeInformation) -> Self {
|
||||||
let Some(info) = value.try_get_type_info() else {
|
let info = value.try_get_type_info()?;
|
||||||
return None;
|
let (fields, fields_type) = match info {
|
||||||
};
|
|
||||||
let (array, field_type) = match info {
|
|
||||||
TypeInfo::Struct(struct_info) => (
|
TypeInfo::Struct(struct_info) => (
|
||||||
get_fields_information(struct_info.iter()),
|
get_fields_information(struct_info.iter()),
|
||||||
if value.is_forced_as_array() {
|
if value.is_forced_as_array() {
|
||||||
@ -150,14 +160,17 @@ impl From<&TypeInformation> for Option<FieldsInformation> {
|
|||||||
get_fields_information(tuple_info.iter()),
|
get_fields_information(tuple_info.iter()),
|
||||||
FieldType::Unnamed,
|
FieldType::Unnamed,
|
||||||
),
|
),
|
||||||
TypeInfo::List(_) => return None,
|
TypeInfo::List(_)
|
||||||
TypeInfo::Array(_) => return None,
|
| TypeInfo::Array(_)
|
||||||
TypeInfo::Map(_) => return None,
|
| TypeInfo::Map(_)
|
||||||
TypeInfo::Set(_) => return None,
|
| TypeInfo::Set(_)
|
||||||
TypeInfo::Enum(_) => return None,
|
| TypeInfo::Enum(_)
|
||||||
TypeInfo::Opaque(_) => return None,
|
| TypeInfo::Opaque(_) => return None,
|
||||||
};
|
};
|
||||||
Some(FieldsInformation(array, field_type))
|
Some(FieldsInformation {
|
||||||
|
fields,
|
||||||
|
fields_type,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +238,32 @@ pub enum TypeInformation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeInformation {
|
impl TypeInformation {
|
||||||
|
/// Returns the reference type if the stored type is a reference one.
|
||||||
|
pub fn get_reference_type(&self) -> Option<TypeReferencePath> {
|
||||||
|
if self.is_primitive_type() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.try_get_type_path_table()
|
||||||
|
.map(TypeReferencePath::definition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Returns true if the stored type is a primitive one.
|
||||||
|
pub fn is_primitive_type(&self) -> bool {
|
||||||
|
self.try_get_primitive_type().is_some()
|
||||||
|
}
|
||||||
|
/// Returns the primitive type if the stored type is a primitive one.
|
||||||
|
pub fn try_get_primitive_type(&self) -> Option<SchemaType> {
|
||||||
|
SchemaType::try_get_primitive_type_from_type_id(self.type_id())
|
||||||
|
}
|
||||||
|
/// Converts the type information into a schema type information.
|
||||||
|
pub fn to_schema_type_info(self) -> SchemaTypeInfo {
|
||||||
|
let stored_fields = (&self).into();
|
||||||
|
SchemaTypeInfo {
|
||||||
|
ty_info: self,
|
||||||
|
field_data: None,
|
||||||
|
stored_fields,
|
||||||
|
}
|
||||||
|
}
|
||||||
/// Returns the documentation of the type.
|
/// Returns the documentation of the type.
|
||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
pub fn get_docs(&self) -> Option<Cow<'static, str>> {
|
pub fn get_docs(&self) -> Option<Cow<'static, str>> {
|
||||||
@ -234,8 +273,7 @@ impl TypeInformation {
|
|||||||
}
|
}
|
||||||
TypeInformation::TypeInfo(type_info) => type_info.docs(),
|
TypeInformation::TypeInfo(type_info) => type_info.docs(),
|
||||||
TypeInformation::VariantInfo(variant_info) => variant_info.docs(),
|
TypeInformation::VariantInfo(variant_info) => variant_info.docs(),
|
||||||
TypeInformation::Type(_) => None,
|
_ => None,
|
||||||
TypeInformation::TypeId(_) => None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
docs.map(|docs| docs.trim().replace("\n", "").into())
|
docs.map(|docs| docs.trim().replace("\n", "").into())
|
||||||
@ -256,15 +294,23 @@ impl TypeInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the type of the type.
|
||||||
|
pub fn try_get_type(&self) -> Option<&Type> {
|
||||||
|
match self {
|
||||||
|
TypeInformation::TypeInfo(type_info) => Some(type_info.ty()),
|
||||||
|
TypeInformation::TypeRegistration(reg) => Some(reg.type_info().ty()),
|
||||||
|
TypeInformation::Type(t) => Some(&**t),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns whether the type is forced as an array.
|
/// Returns whether the type is forced as an array.
|
||||||
pub fn is_forced_as_array(&self) -> bool {
|
pub fn is_forced_as_array(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
TypeInformation::Type(_) => false,
|
|
||||||
TypeInformation::TypeId(_) | TypeInformation::VariantInfo(_) => false,
|
|
||||||
TypeInformation::TypeInfo(_) => false,
|
|
||||||
TypeInformation::TypeRegistration(type_registration) => type_registration
|
TypeInformation::TypeRegistration(type_registration) => type_registration
|
||||||
.data::<ReflectJsonSchemaForceAsArray>()
|
.data::<ReflectJsonSchemaForceAsArray>()
|
||||||
.is_some(),
|
.is_some(),
|
||||||
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,9 +367,7 @@ impl TypeInformation {
|
|||||||
}
|
}
|
||||||
/// Try to get the optional type information from the enum information.
|
/// Try to get the optional type information from the enum information.
|
||||||
pub fn try_get_optional_from_info(enum_info: &EnumInfo) -> Option<&GenericInfo> {
|
pub fn try_get_optional_from_info(enum_info: &EnumInfo) -> Option<&GenericInfo> {
|
||||||
let Some(generic) = enum_info.generics().first() else {
|
let generic = enum_info.generics().first()?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
if enum_info.variant_len() != 2
|
if enum_info.variant_len() != 2
|
||||||
|| !enum_info.contains_variant("Some")
|
|| !enum_info.contains_variant("Some")
|
||||||
|| !enum_info.contains_variant("None")
|
|| !enum_info.contains_variant("None")
|
||||||
@ -340,6 +384,7 @@ impl Default for TypeInformation {
|
|||||||
Self::TypeId(TypeId::of::<()>())
|
Self::TypeId(TypeId::of::<()>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&TypeInformation> for SchemaKind {
|
impl From<&TypeInformation> for SchemaKind {
|
||||||
fn from(value: &TypeInformation) -> Self {
|
fn from(value: &TypeInformation) -> Self {
|
||||||
let type_info = value.try_get_type_info();
|
let type_info = value.try_get_type_info();
|
||||||
@ -374,11 +419,6 @@ impl From<&TypeInformation> for SchemaKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<&TypePathTable> for TypeReferenceId {
|
|
||||||
fn from(value: &TypePathTable) -> Self {
|
|
||||||
value.path().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&TypeInformation> for TypeReferenceId {
|
impl TryFrom<&TypeInformation> for TypeReferenceId {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
@ -803,10 +843,8 @@ pub enum InternalSchemaType {
|
|||||||
EnumHolder(Vec<VariantInfo>),
|
EnumHolder(Vec<VariantInfo>),
|
||||||
/// Represents a single enum variant.
|
/// Represents a single enum variant.
|
||||||
EnumVariant(VariantInfo),
|
EnumVariant(VariantInfo),
|
||||||
/// Holds named fields for struct types.
|
/// Holds named fields for struct, tuple, and tuple struct types.
|
||||||
NamedFieldsHolder(FieldsInformation),
|
FieldsHolder(FieldsInformation),
|
||||||
/// Holds unnamed fields for tuple and tuple struct types.
|
|
||||||
UnnamedFieldsHolder(FieldsInformation),
|
|
||||||
/// Represents an Optional type (e.g., Option<T>).
|
/// Represents an Optional type (e.g., Option<T>).
|
||||||
Optional {
|
Optional {
|
||||||
/// Generic information about the wrapped type T in Option<T>.
|
/// Generic information about the wrapped type T in Option<T>.
|
||||||
@ -834,24 +872,26 @@ impl From<&TypeInformation> for InternalSchemaType {
|
|||||||
if let Some(type_info) = value.try_get_type_info() {
|
if let Some(type_info) = value.try_get_type_info() {
|
||||||
match type_info {
|
match type_info {
|
||||||
TypeInfo::Struct(struct_info) => {
|
TypeInfo::Struct(struct_info) => {
|
||||||
if value.is_forced_as_array() {
|
let fields_type = if value.is_forced_as_array() {
|
||||||
InternalSchemaType::UnnamedFieldsHolder(FieldsInformation(
|
FieldType::Unnamed
|
||||||
get_fields_information(struct_info.iter()),
|
|
||||||
FieldType::Unnamed,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
InternalSchemaType::NamedFieldsHolder(FieldsInformation(
|
FieldType::Named
|
||||||
get_fields_information(struct_info.iter()),
|
};
|
||||||
FieldType::Named,
|
InternalSchemaType::FieldsHolder(FieldsInformation {
|
||||||
))
|
fields: get_fields_information(struct_info.iter()),
|
||||||
}
|
fields_type,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
TypeInfo::TupleStruct(info) => InternalSchemaType::UnnamedFieldsHolder(
|
TypeInfo::TupleStruct(info) => {
|
||||||
FieldsInformation(get_fields_information(info.iter()), FieldType::Unnamed),
|
InternalSchemaType::FieldsHolder(FieldsInformation {
|
||||||
),
|
fields: get_fields_information(info.iter()),
|
||||||
TypeInfo::Tuple(info) => InternalSchemaType::UnnamedFieldsHolder(
|
fields_type: FieldType::Unnamed,
|
||||||
FieldsInformation(get_fields_information(info.iter()), FieldType::Unnamed),
|
})
|
||||||
),
|
}
|
||||||
|
TypeInfo::Tuple(info) => InternalSchemaType::FieldsHolder(FieldsInformation {
|
||||||
|
fields: get_fields_information(info.iter()),
|
||||||
|
fields_type: FieldType::Unnamed,
|
||||||
|
}),
|
||||||
TypeInfo::Enum(enum_info) => {
|
TypeInfo::Enum(enum_info) => {
|
||||||
match TypeInformation::try_get_optional_from_info(enum_info) {
|
match TypeInformation::try_get_optional_from_info(enum_info) {
|
||||||
Some(e) => InternalSchemaType::Optional {
|
Some(e) => InternalSchemaType::Optional {
|
||||||
@ -898,12 +938,10 @@ impl From<&TypeInformation> for InternalSchemaType {
|
|||||||
impl From<&SchemaTypeInfo> for InternalSchemaType {
|
impl From<&SchemaTypeInfo> for InternalSchemaType {
|
||||||
fn from(value: &SchemaTypeInfo) -> Self {
|
fn from(value: &SchemaTypeInfo) -> Self {
|
||||||
if let Some(s) = &value.stored_fields {
|
if let Some(s) = &value.stored_fields {
|
||||||
if s.1 == FieldType::Named {
|
InternalSchemaType::FieldsHolder(s.clone())
|
||||||
return InternalSchemaType::NamedFieldsHolder(s.clone());
|
} else {
|
||||||
}
|
(&value.ty_info).into()
|
||||||
return InternalSchemaType::UnnamedFieldsHolder(s.clone());
|
|
||||||
}
|
}
|
||||||
(&value.ty_info).into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +949,6 @@ impl From<&InternalSchemaType> for Option<SchemaTypeVariant> {
|
|||||||
fn from(value: &InternalSchemaType) -> Self {
|
fn from(value: &InternalSchemaType) -> Self {
|
||||||
match value {
|
match value {
|
||||||
InternalSchemaType::Array { .. } => Some(SchemaTypeVariant::Single(SchemaType::Array)),
|
InternalSchemaType::Array { .. } => Some(SchemaTypeVariant::Single(SchemaType::Array)),
|
||||||
InternalSchemaType::EnumHolder(_) => None,
|
|
||||||
InternalSchemaType::EnumVariant(variant) => match variant {
|
InternalSchemaType::EnumVariant(variant) => match variant {
|
||||||
VariantInfo::Tuple(t) => {
|
VariantInfo::Tuple(t) => {
|
||||||
if t.field_len() == 1 {
|
if t.field_len() == 1 {
|
||||||
@ -926,15 +963,16 @@ impl From<&InternalSchemaType> for Option<SchemaTypeVariant> {
|
|||||||
VariantInfo::Struct(_) => Some(SchemaTypeVariant::Single(SchemaType::Object)),
|
VariantInfo::Struct(_) => Some(SchemaTypeVariant::Single(SchemaType::Object)),
|
||||||
VariantInfo::Unit(_) => Some(SchemaTypeVariant::Single(SchemaType::String)),
|
VariantInfo::Unit(_) => Some(SchemaTypeVariant::Single(SchemaType::String)),
|
||||||
},
|
},
|
||||||
InternalSchemaType::NamedFieldsHolder { .. } => {
|
InternalSchemaType::FieldsHolder(fields) => {
|
||||||
Some(SchemaTypeVariant::Single(SchemaType::Object))
|
if fields.fields_type == FieldType::Unnamed {
|
||||||
}
|
if fields.fields.len() == 1 {
|
||||||
InternalSchemaType::UnnamedFieldsHolder(unnamed_fields) => {
|
let schema: InternalSchemaType = (&fields.fields[0].type_info).into();
|
||||||
if unnamed_fields.len() == 1 {
|
(&schema).into()
|
||||||
let schema: InternalSchemaType = (&unnamed_fields[0].type_info).into();
|
} else {
|
||||||
(&schema).into()
|
Some(SchemaTypeVariant::Single(SchemaType::Array))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(SchemaTypeVariant::Single(SchemaType::Array))
|
Some(SchemaTypeVariant::Single(SchemaType::Object))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InternalSchemaType::Optional {
|
InternalSchemaType::Optional {
|
||||||
@ -954,7 +992,7 @@ impl From<&InternalSchemaType> for Option<SchemaTypeVariant> {
|
|||||||
Some(SchemaTypeVariant::Single((*type_id).into()))
|
Some(SchemaTypeVariant::Single((*type_id).into()))
|
||||||
}
|
}
|
||||||
InternalSchemaType::RegularType(ty) => Some(SchemaTypeVariant::Single(ty.id().into())),
|
InternalSchemaType::RegularType(ty) => Some(SchemaTypeVariant::Single(ty.id().into())),
|
||||||
InternalSchemaType::NoInfo => None,
|
InternalSchemaType::NoInfo | InternalSchemaType::EnumHolder(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1024,26 +1062,28 @@ impl SchemaTypeInfo {
|
|||||||
/// Converts the schema type information into a JSON schema reference.
|
/// Converts the schema type information into a JSON schema reference.
|
||||||
pub fn to_ref_schema(&self) -> JsonSchemaBevyType {
|
pub fn to_ref_schema(&self) -> JsonSchemaBevyType {
|
||||||
let range = self.get_range();
|
let range = self.get_range();
|
||||||
|
let description = self.get_docs();
|
||||||
|
let (ref_type, schema_type) = (self.ty_info.get_reference_type(), self.into());
|
||||||
JsonSchemaBevyType {
|
JsonSchemaBevyType {
|
||||||
description: self.get_docs(),
|
description,
|
||||||
minimum: range.min.get_inclusive(),
|
minimum: range.min.get_inclusive(),
|
||||||
maximum: range.max.get_inclusive(),
|
maximum: range.max.get_inclusive(),
|
||||||
exclusive_minimum: range.min.get_exclusive(),
|
exclusive_minimum: range.min.get_exclusive(),
|
||||||
exclusive_maximum: range.max.get_exclusive(),
|
exclusive_maximum: range.max.get_exclusive(),
|
||||||
ref_type: self
|
ref_type,
|
||||||
.ty_info
|
kind: None,
|
||||||
.try_get_type_path_table()
|
schema_type,
|
||||||
.map(TypeReferencePath::definition),
|
|
||||||
..default()
|
..default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
/// Converts the schema type information into a JSON schema definition.
|
||||||
fn from(val: SchemaTypeInfo) -> Self {
|
pub fn to_definition(&self) -> (Option<TypeReferenceId>, JsonSchemaBevyType) {
|
||||||
let schema_type: Option<SchemaTypeVariant> = (&val).into();
|
let id: Option<TypeReferenceId> = self.ty_info.try_get_type_path_table().map(Into::into);
|
||||||
|
let range = self.ty_info.get_range();
|
||||||
|
|
||||||
let (type_path, short_path, crate_name, module_path) =
|
let (type_path, short_path, crate_name, module_path) =
|
||||||
if let Some(type_path_table) = val.ty_info.try_get_type_path_table() {
|
if let Some(type_path_table) = self.ty_info.try_get_type_path_table() {
|
||||||
(
|
(
|
||||||
type_path_table.path().into(),
|
type_path_table.path().into(),
|
||||||
type_path_table.short_path().into(),
|
type_path_table.short_path().into(),
|
||||||
@ -1053,24 +1093,21 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
} else {
|
} else {
|
||||||
(Cow::default(), Cow::default(), None, None)
|
(Cow::default(), Cow::default(), None, None)
|
||||||
};
|
};
|
||||||
let kind: SchemaKind = (&val.ty_info).into();
|
|
||||||
let range = val.get_range();
|
|
||||||
let mut schema = JsonSchemaBevyType {
|
let mut schema = JsonSchemaBevyType {
|
||||||
schema_type: schema_type.clone(),
|
description: self.ty_info.get_docs(),
|
||||||
kind,
|
|
||||||
description: val.get_docs(),
|
|
||||||
type_path,
|
type_path,
|
||||||
short_path,
|
short_path,
|
||||||
crate_name,
|
crate_name,
|
||||||
module_path,
|
module_path,
|
||||||
|
kind: Some((&self.ty_info).into()),
|
||||||
minimum: range.min.get_inclusive(),
|
minimum: range.min.get_inclusive(),
|
||||||
maximum: range.max.get_inclusive(),
|
maximum: range.max.get_inclusive(),
|
||||||
exclusive_minimum: range.min.get_exclusive(),
|
exclusive_minimum: range.min.get_exclusive(),
|
||||||
exclusive_maximum: range.max.get_exclusive(),
|
exclusive_maximum: range.max.get_exclusive(),
|
||||||
..Default::default()
|
schema_type: self.into(),
|
||||||
|
..default()
|
||||||
};
|
};
|
||||||
let internal_type: InternalSchemaType = (&val).into();
|
let internal_type: InternalSchemaType = (self).into();
|
||||||
|
|
||||||
match internal_type {
|
match internal_type {
|
||||||
InternalSchemaType::Map { key, value } => {
|
InternalSchemaType::Map { key, value } => {
|
||||||
let key: SchemaTypeInfo = SchemaTypeInfo {
|
let key: SchemaTypeInfo = SchemaTypeInfo {
|
||||||
@ -1083,9 +1120,9 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
field_data: None,
|
field_data: None,
|
||||||
stored_fields: None,
|
stored_fields: None,
|
||||||
};
|
};
|
||||||
schema.additional_properties = Some(key.clone().into());
|
schema.additional_properties = Some(key.clone().to_definition().1.into());
|
||||||
schema.value_type = Some(value.into());
|
schema.value_type = Some(value.to_definition().1.into());
|
||||||
schema.key_type = Some(key.into());
|
schema.key_type = Some(key.to_definition().1.into());
|
||||||
}
|
}
|
||||||
InternalSchemaType::Regular(_)
|
InternalSchemaType::Regular(_)
|
||||||
| InternalSchemaType::RegularType(_)
|
| InternalSchemaType::RegularType(_)
|
||||||
@ -1094,23 +1131,29 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
schema.one_of = variants.iter().map(build_schema).collect();
|
schema.one_of = variants.iter().map(build_schema).collect();
|
||||||
}
|
}
|
||||||
InternalSchemaType::EnumVariant(variant_info) => {
|
InternalSchemaType::EnumVariant(variant_info) => {
|
||||||
schema.kind = SchemaKind::Value;
|
schema.kind = Some(SchemaKind::Value);
|
||||||
schema.schema_type = Some(SchemaTypeVariant::Single(SchemaType::Object));
|
schema.schema_type = Some(SchemaTypeVariant::Single(SchemaType::Object));
|
||||||
let ty_info: TypeInformation = (&variant_info).into();
|
let ty_info: TypeInformation = (&variant_info).into();
|
||||||
let field_data: Option<SchemaFieldData> = Some((&variant_info).into());
|
let field_data: Option<SchemaFieldData> = Some((&variant_info).into());
|
||||||
|
|
||||||
match &variant_info {
|
match &variant_info {
|
||||||
VariantInfo::Struct(struct_variant_info) => {
|
VariantInfo::Struct(struct_variant_info) => {
|
||||||
let stored_fields = get_fields_information(struct_variant_info.iter());
|
let fields = get_fields_information(struct_variant_info.iter());
|
||||||
|
|
||||||
let schema_field = SchemaTypeInfo {
|
let schema_field = SchemaTypeInfo {
|
||||||
ty_info,
|
ty_info,
|
||||||
field_data,
|
field_data,
|
||||||
stored_fields: Some(FieldsInformation(stored_fields, FieldType::Named)),
|
stored_fields: Some(FieldsInformation {
|
||||||
|
fields,
|
||||||
|
fields_type: FieldType::Named,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
schema.properties =
|
schema.properties = [(
|
||||||
[(variant_info.name().into(), schema_field.into())].into();
|
variant_info.name().into(),
|
||||||
|
schema_field.to_definition().1.into(),
|
||||||
|
)]
|
||||||
|
.into();
|
||||||
schema.required = vec![variant_info.name().into()];
|
schema.required = vec![variant_info.name().into()];
|
||||||
}
|
}
|
||||||
VariantInfo::Tuple(tuple_variant_info) => {
|
VariantInfo::Tuple(tuple_variant_info) => {
|
||||||
@ -1118,13 +1161,18 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
let schema_field = SchemaTypeInfo {
|
let schema_field = SchemaTypeInfo {
|
||||||
ty_info,
|
ty_info,
|
||||||
field_data: None,
|
field_data: None,
|
||||||
stored_fields: Some(FieldsInformation(
|
stored_fields: Some(FieldsInformation {
|
||||||
stored_fields,
|
fields: stored_fields,
|
||||||
FieldType::Unnamed,
|
|
||||||
)),
|
fields_type: FieldType::Unnamed,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
schema.properties =
|
|
||||||
[(variant_info.name().into(), schema_field.into())].into();
|
schema.properties = [(
|
||||||
|
variant_info.name().into(),
|
||||||
|
schema_field.to_definition().1.into(),
|
||||||
|
)]
|
||||||
|
.into();
|
||||||
schema.required = vec![variant_info.name().into()];
|
schema.required = vec![variant_info.name().into()];
|
||||||
}
|
}
|
||||||
VariantInfo::Unit(unit_variant_info) => {
|
VariantInfo::Unit(unit_variant_info) => {
|
||||||
@ -1133,48 +1181,66 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
field_data,
|
field_data,
|
||||||
stored_fields: None,
|
stored_fields: None,
|
||||||
};
|
};
|
||||||
return JsonSchemaVariant::Schema(Box::new(JsonSchemaBevyType {
|
return (
|
||||||
const_value: Some(unit_variant_info.name().to_string().into()),
|
None,
|
||||||
schema_type: Some(SchemaTypeVariant::Single(SchemaType::String)),
|
JsonSchemaBevyType {
|
||||||
description: schema_field.get_docs(),
|
const_value: Some(unit_variant_info.name().to_string().into()),
|
||||||
kind: SchemaKind::Value,
|
schema_type: Some(SchemaTypeVariant::Single(SchemaType::String)),
|
||||||
..Default::default()
|
description: schema_field.get_docs(),
|
||||||
}));
|
kind: Some(SchemaKind::Value),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InternalSchemaType::NamedFieldsHolder(named_fields) => {
|
InternalSchemaType::FieldsHolder(fields) => match fields.fields_type {
|
||||||
schema.additional_properties = Some(JsonSchemaVariant::BoolValue(false));
|
FieldType::Named => {
|
||||||
schema.schema_type = Some(SchemaTypeVariant::Single(SchemaType::Object));
|
schema.additional_properties = Some(JsonSchemaVariant::BoolValue(false));
|
||||||
|
schema.schema_type = Some(SchemaTypeVariant::Single(SchemaType::Object));
|
||||||
schema.properties = named_fields
|
let schema_fields: Vec<(Cow<'static, str>, SchemaTypeInfo)> = fields
|
||||||
.iter()
|
.fields
|
||||||
.map(|field| (field.field.to_name(), SchemaTypeInfo::from(field).into()))
|
|
||||||
.collect();
|
|
||||||
schema.required = named_fields
|
|
||||||
.iter()
|
|
||||||
.map(|field| field.field.to_name())
|
|
||||||
.collect();
|
|
||||||
}
|
|
||||||
InternalSchemaType::UnnamedFieldsHolder(unnamed_fields) => {
|
|
||||||
if unnamed_fields.len() == 1 {
|
|
||||||
let new_schema = SchemaTypeInfo::from(&unnamed_fields[0]).into();
|
|
||||||
if let JsonSchemaVariant::Schema(new_schema_type) = new_schema {
|
|
||||||
schema = *new_schema_type;
|
|
||||||
schema.schema_type = schema_type.clone();
|
|
||||||
schema.description = val.get_docs();
|
|
||||||
} else {
|
|
||||||
return new_schema;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
schema.prefix_items = unnamed_fields
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| SchemaTypeInfo::from(field).into())
|
.map(|field| (field.field.to_name(), SchemaTypeInfo::from(field)))
|
||||||
|
.collect();
|
||||||
|
schema.properties = schema_fields
|
||||||
|
.iter()
|
||||||
|
.map(|(name, schema)| (name.clone(), schema.to_ref_schema().into()))
|
||||||
|
.collect();
|
||||||
|
for (_, field_schema) in schema_fields {
|
||||||
|
if field_schema.ty_info.is_primitive_type() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let (id, definition) = field_schema.to_definition();
|
||||||
|
let Some(id) = id else { continue };
|
||||||
|
if !schema.definitions.contains_key(&id) {
|
||||||
|
schema.definitions.insert(id, definition.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
schema.required = fields
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| field.field.to_name())
|
||||||
.collect();
|
.collect();
|
||||||
schema.min_items = Some(unnamed_fields.len() as u64);
|
|
||||||
schema.max_items = Some(unnamed_fields.len() as u64);
|
|
||||||
}
|
}
|
||||||
}
|
FieldType::Unnamed => {
|
||||||
|
if fields.fields.len() == 1 {
|
||||||
|
let (_, new_schema_type) =
|
||||||
|
SchemaTypeInfo::from(&fields.fields[0]).to_definition();
|
||||||
|
schema = new_schema_type;
|
||||||
|
schema.schema_type = self.into();
|
||||||
|
schema.description = self.get_docs();
|
||||||
|
} else {
|
||||||
|
schema.prefix_items = fields
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| SchemaTypeInfo::from(field).to_definition().1.into())
|
||||||
|
.collect();
|
||||||
|
schema.min_items = Some(fields.fields.len() as u64);
|
||||||
|
schema.max_items = Some(fields.fields.len() as u64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
InternalSchemaType::Array {
|
InternalSchemaType::Array {
|
||||||
element_ty,
|
element_ty,
|
||||||
min_size,
|
min_size,
|
||||||
@ -1185,7 +1251,7 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
field_data: None,
|
field_data: None,
|
||||||
stored_fields: None,
|
stored_fields: None,
|
||||||
};
|
};
|
||||||
schema.items = Some(items_schema.into());
|
schema.items = Some(items_schema.to_definition().1.into());
|
||||||
schema.min_items = min_size;
|
schema.min_items = min_size;
|
||||||
schema.max_items = max_size;
|
schema.max_items = max_size;
|
||||||
}
|
}
|
||||||
@ -1193,23 +1259,22 @@ impl From<SchemaTypeInfo> for JsonSchemaVariant {
|
|||||||
generic: _,
|
generic: _,
|
||||||
ref schema_type_info,
|
ref schema_type_info,
|
||||||
} => {
|
} => {
|
||||||
let schema_variant: JsonSchemaVariant = schema_type_info.as_ref().clone().into();
|
let schema_variant: JsonSchemaVariant =
|
||||||
|
schema_type_info.as_ref().clone().to_definition().1.into();
|
||||||
if let JsonSchemaVariant::Schema(value) = schema_variant {
|
if let JsonSchemaVariant::Schema(value) = schema_variant {
|
||||||
let range = val.get_range();
|
let range = self.get_range();
|
||||||
schema = *value;
|
schema = *value;
|
||||||
schema.schema_type = schema_type.clone();
|
schema.schema_type = self.into();
|
||||||
schema.minimum = range.min.get_inclusive();
|
schema.minimum = range.min.get_inclusive();
|
||||||
schema.maximum = range.max.get_inclusive();
|
schema.maximum = range.max.get_inclusive();
|
||||||
schema.exclusive_minimum = range.min.get_exclusive();
|
schema.exclusive_minimum = range.min.get_exclusive();
|
||||||
schema.exclusive_maximum = range.max.get_exclusive();
|
schema.exclusive_maximum = range.max.get_exclusive();
|
||||||
schema.description = val.get_docs();
|
schema.description = self.get_docs();
|
||||||
schema.kind = SchemaKind::Optional;
|
schema.kind = Some(SchemaKind::Optional);
|
||||||
} else {
|
|
||||||
return schema_variant;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JsonSchemaVariant::Schema(Box::new(schema))
|
(id, schema)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,38 +1367,28 @@ impl<'a, T> From<&'a T> for SchemaTypeInfo
|
|||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
TypeInformation: From<&'a T>,
|
TypeInformation: From<&'a T>,
|
||||||
SchemaFieldData: TryFrom<&'a T>,
|
SchemaFieldData: From<&'a T>,
|
||||||
{
|
{
|
||||||
fn from(value: &'a T) -> Self {
|
fn from(value: &'a T) -> Self {
|
||||||
let ty_info: TypeInformation = value.into();
|
let ty_info: TypeInformation = value.into();
|
||||||
let field_data: Option<SchemaFieldData> = value.try_into().ok();
|
let field_data: SchemaFieldData = value.into();
|
||||||
let stored_fields = (&ty_info).into();
|
let stored_fields = (&ty_info).into();
|
||||||
SchemaTypeInfo {
|
SchemaTypeInfo {
|
||||||
ty_info,
|
ty_info,
|
||||||
field_data,
|
field_data: Some(field_data),
|
||||||
stored_fields,
|
stored_fields,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a [`SchemaTypeInfo`] from a value.
|
|
||||||
pub fn build_schema_type_info<'a, T>(value: &'a T) -> SchemaTypeInfo
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
TypeInformation: From<&'a T>,
|
|
||||||
SchemaFieldData: TryFrom<&'a T>,
|
|
||||||
{
|
|
||||||
value.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds a JSON schema variant from a value.
|
/// Builds a JSON schema variant from a value.
|
||||||
pub fn build_schema<'a, T>(value: &'a T) -> JsonSchemaVariant
|
pub fn build_schema<'a, T>(value: &'a T) -> JsonSchemaVariant
|
||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
TypeInformation: From<&'a T>,
|
SchemaTypeInfo: From<&'a T>,
|
||||||
SchemaFieldData: TryFrom<&'a T>,
|
|
||||||
{
|
{
|
||||||
build_schema_type_info(value).into()
|
let schema: SchemaTypeInfo = value.into();
|
||||||
|
schema.to_definition().1.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&UnnamedField> for SchemaFieldData {
|
impl From<&UnnamedField> for SchemaFieldData {
|
||||||
@ -1411,20 +1466,6 @@ impl From<&TypeInfo> for TypeInformation {
|
|||||||
TypeInformation::TypeInfo(Box::new(value.clone()))
|
TypeInformation::TypeInfo(Box::new(value.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl TryFrom<&TypeInfo> for SchemaFieldData {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(_: &TypeInfo) -> Result<Self, Self::Error> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl TryFrom<&TypeRegistration> for SchemaFieldData {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(_: &TypeRegistration) -> Result<Self, Self::Error> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&TypeRegistration> for TypeInformation {
|
impl From<&TypeRegistration> for TypeInformation {
|
||||||
fn from(value: &TypeRegistration) -> Self {
|
fn from(value: &TypeRegistration) -> Self {
|
||||||
@ -1437,15 +1478,6 @@ impl From<Type> for TypeInformation {
|
|||||||
TypeInformation::Type(Box::new(value))
|
TypeInformation::Type(Box::new(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&Type> for SchemaFieldData {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(_: &Type) -> Result<Self, Self::Error> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&TypeId> for TypeInformation {
|
impl From<&TypeId> for TypeInformation {
|
||||||
fn from(value: &TypeId) -> Self {
|
fn from(value: &TypeId) -> Self {
|
||||||
TypeInformation::TypeId(*value)
|
TypeInformation::TypeId(*value)
|
||||||
@ -1457,14 +1489,6 @@ impl From<TypeId> for TypeInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&TypeId> for SchemaFieldData {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(_: &TypeId) -> Result<Self, Self::Error> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_fields_information<'a, 'b, T>(iterator: Iter<'a, T>) -> Vec<FieldInformation>
|
fn get_fields_information<'a, 'b, T>(iterator: Iter<'a, T>) -> Vec<FieldInformation>
|
||||||
where
|
where
|
||||||
SchemaFieldData: From<&'a T>,
|
SchemaFieldData: From<&'a T>,
|
||||||
@ -1491,7 +1515,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_test() {
|
fn integer_test() {
|
||||||
let type_info = build_schema_type_info(&TypeId::of::<u16>());
|
let type_info = TypeInformation::from(&TypeId::of::<u16>()).to_schema_type_info();
|
||||||
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
type_info.get_range().min,
|
type_info.get_range().min,
|
||||||
@ -1520,7 +1544,7 @@ mod tests {
|
|||||||
.as_struct()
|
.as_struct()
|
||||||
.expect("Should not fail");
|
.expect("Should not fail");
|
||||||
let field_info = struct_info.field("no_value").expect("Should not fail");
|
let field_info = struct_info.field("no_value").expect("Should not fail");
|
||||||
let type_info = build_schema_type_info(field_info);
|
let type_info = SchemaTypeInfo::from(field_info);
|
||||||
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
||||||
let range = type_info.get_range();
|
let range = type_info.get_range();
|
||||||
assert_eq!(range.min, Some(BoundValue::Inclusive(10.into())));
|
assert_eq!(range.min, Some(BoundValue::Inclusive(10.into())));
|
||||||
@ -1545,7 +1569,7 @@ mod tests {
|
|||||||
.as_struct()
|
.as_struct()
|
||||||
.expect("Should not fail");
|
.expect("Should not fail");
|
||||||
let field_info = struct_info.field("no_value").expect("Should not fail");
|
let field_info = struct_info.field("no_value").expect("Should not fail");
|
||||||
let type_info = build_schema_type_info(field_info);
|
let type_info = SchemaTypeInfo::from(field_info);
|
||||||
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
||||||
let range = type_info.get_range();
|
let range = type_info.get_range();
|
||||||
assert!(!range.in_range((-1).into()));
|
assert!(!range.in_range((-1).into()));
|
||||||
@ -1574,12 +1598,13 @@ mod tests {
|
|||||||
register.register_type_data::<bevy_math::Vec3, ReflectJsonSchemaForceAsArray>();
|
register.register_type_data::<bevy_math::Vec3, ReflectJsonSchemaForceAsArray>();
|
||||||
}
|
}
|
||||||
let type_registry = atr.read();
|
let type_registry = atr.read();
|
||||||
let declaration = build_schema_type_info(
|
let declaration = TypeInformation::from(
|
||||||
type_registry
|
type_registry
|
||||||
.get(TypeId::of::<bevy_math::Vec3>())
|
.get(TypeId::of::<bevy_math::Vec3>())
|
||||||
.expect(""),
|
.expect(""),
|
||||||
);
|
)
|
||||||
let _: JsonSchemaVariant = declaration.clone().into();
|
.to_schema_type_info();
|
||||||
|
let _: JsonSchemaVariant = declaration.to_definition().1.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1596,7 +1621,7 @@ mod tests {
|
|||||||
.as_tuple_struct()
|
.as_tuple_struct()
|
||||||
.expect("Should not fail");
|
.expect("Should not fail");
|
||||||
let field_info = struct_info.iter().next().expect("Should not fail");
|
let field_info = struct_info.iter().next().expect("Should not fail");
|
||||||
let type_info = build_schema_type_info(field_info);
|
let type_info = SchemaTypeInfo::from(field_info);
|
||||||
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
let schema_type: Option<SchemaTypeVariant> = (&type_info).into();
|
||||||
let range = type_info.get_range();
|
let range = type_info.get_range();
|
||||||
assert_eq!(range.min, Some(BoundValue::Inclusive(0.into())));
|
assert_eq!(range.min, Some(BoundValue::Inclusive(0.into())));
|
||||||
@ -1630,7 +1655,9 @@ mod tests {
|
|||||||
pub struct ArrayComponent {
|
pub struct ArrayComponent {
|
||||||
pub array: [i32; 3],
|
pub array: [i32; 3],
|
||||||
}
|
}
|
||||||
let _ = build_schema(&ArrayComponent::get_type_registration());
|
let type_info =
|
||||||
|
TypeInformation::from(&ArrayComponent::get_type_registration()).to_schema_type_info();
|
||||||
|
let _: JsonSchemaVariant = type_info.to_definition().1.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1643,7 +1670,9 @@ mod tests {
|
|||||||
"{\"map\": {\"0\": 1, \"1\": 41, \"2\": null}}"
|
"{\"map\": {\"0\": 1, \"1\": 41, \"2\": null}}"
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
let _ = build_schema(&HashMapStruct::get_type_registration());
|
let type_info =
|
||||||
|
TypeInformation::from(&HashMapStruct::get_type_registration()).to_schema_type_info();
|
||||||
|
let _: JsonSchemaVariant = type_info.to_definition().1.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1669,6 +1698,9 @@ mod tests {
|
|||||||
pub second: SecondStruct,
|
pub second: SecondStruct,
|
||||||
pub third: ThirdStruct,
|
pub third: ThirdStruct,
|
||||||
}
|
}
|
||||||
let _ = build_schema(&NestedStruct::get_type_registration());
|
let type_info =
|
||||||
|
TypeInformation::from(&NestedStruct::get_type_registration()).to_schema_type_info();
|
||||||
|
let _s: JsonSchemaVariant = type_info.to_definition().1.into();
|
||||||
|
// eprintln!("{}", serde_json::to_string_pretty(&s).expect("msg"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user