From 0a3b70762c49c6edc1430b1962ccd5aeb38071f8 Mon Sep 17 00:00:00 2001 From: Piotr Siuszko Date: Sat, 21 Jun 2025 04:27:02 +0200 Subject: [PATCH] Add JSON Schema version identification field --- crates/bevy_remote/src/schemas/json_schema.rs | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/crates/bevy_remote/src/schemas/json_schema.rs b/crates/bevy_remote/src/schemas/json_schema.rs index 31c6d2b427..22d3eaa880 100644 --- a/crates/bevy_remote/src/schemas/json_schema.rs +++ b/crates/bevy_remote/src/schemas/json_schema.rs @@ -41,7 +41,8 @@ impl TypeRegistrySchemaReader for TypeRegistry { extra_info: &SchemaTypesMetadata, ) -> Option { let type_reg = self.get(type_id)?; - let mut schema: JsonSchemaBevyType = (type_reg, extra_info).into(); + let mut schema: JsonSchemaBevyType = (type_reg, extra_info).try_into().ok()?; + schema.schema = Some(SchemaMarker::default()); schema.default_value = self.try_get_default_value_for_type_id(type_id); Some(schema) @@ -65,20 +66,32 @@ impl TypeRegistrySchemaReader for TypeRegistry { } } -impl From<(&TypeRegistration, &SchemaTypesMetadata)> for JsonSchemaBevyType { - fn from(value: (&TypeRegistration, &SchemaTypesMetadata)) -> Self { +impl TryFrom<(&TypeRegistration, &SchemaTypesMetadata)> for JsonSchemaBevyType { + type Error = (); + + fn try_from(value: (&TypeRegistration, &SchemaTypesMetadata)) -> Result { let (reg, metadata) = value; if let Some(s) = reg.data::() { - return s.0.clone(); + return Ok(s.0.clone()); } let type_info = reg.type_info(); let base_schema = type_info.build_schema(); let JsonSchemaVariant::Schema(mut typed_schema) = base_schema else { - return JsonSchemaBevyType::default(); + return Err(()); }; typed_schema.reflect_types = metadata.get_registered_reflect_types(reg); - *typed_schema + Ok(*typed_schema) + } +} + +/// Identifies the JSON Schema version used in the schema. +#[derive(Deserialize, Serialize, Debug, Reflect, PartialEq, Clone)] +pub struct SchemaMarker(String); + +impl Default for SchemaMarker { + fn default() -> Self { + Self("https://json-schema.org/draft/2020-12/schema".to_string()) } } @@ -89,6 +102,10 @@ impl From<(&TypeRegistration, &SchemaTypesMetadata)> for JsonSchemaBevyType { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default, Reflect)] #[serde(rename_all = "camelCase")] pub struct JsonSchemaBevyType { + /// Identifies the JSON Schema version used in the schema. + #[serde(rename = "$schema")] + #[serde(skip_serializing_if = "Option::is_none", default)] + pub schema: Option, /// JSON Schema specific field. /// This keyword is used to reference a statically identified schema. #[serde(rename = "$ref")] @@ -612,6 +629,7 @@ mod tests { eprintln!("{:#?}", &schema_as_value); let value = json!({ "shortPath": "Foo", + "$schema": "https://json-schema.org/draft/2020-12/schema", "typePath": "bevy_remote::schemas::json_schema::tests::Foo", "modulePath": "bevy_remote::schemas::json_schema::tests", "crateName": "bevy_remote",