bevy_remote/schemas/
mod.rs

1//! Module with schemas used for various BRP endpoints
2use bevy_ecs::{
3    reflect::{ReflectComponent, ReflectResource},
4    resource::Resource,
5};
6use bevy_platform::collections::HashMap;
7use bevy_reflect::{
8    prelude::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize, TypeData,
9    TypeRegistration,
10};
11use core::any::TypeId;
12
13pub mod json_schema;
14pub mod open_rpc;
15
16/// Holds mapping of reflect [type data](TypeData) to strings,
17/// later on used in Bevy Json Schema.
18#[derive(Debug, Resource, Reflect)]
19#[reflect(Resource)]
20pub struct SchemaTypesMetadata {
21    /// Type Data id mapping to strings.
22    pub type_data_map: HashMap<TypeId, String>,
23}
24
25impl Default for SchemaTypesMetadata {
26    fn default() -> Self {
27        let mut data_types = Self {
28            type_data_map: Default::default(),
29        };
30        data_types.map_type_data::<ReflectComponent>("Component");
31        data_types.map_type_data::<ReflectResource>("Resource");
32        data_types.map_type_data::<ReflectDefault>("Default");
33        #[cfg(feature = "bevy_asset")]
34        data_types.map_type_data::<bevy_asset::ReflectAsset>("Asset");
35        #[cfg(feature = "bevy_asset")]
36        data_types.map_type_data::<bevy_asset::ReflectHandle>("AssetHandle");
37        data_types.map_type_data::<ReflectSerialize>("Serialize");
38        data_types.map_type_data::<ReflectDeserialize>("Deserialize");
39        data_types
40    }
41}
42
43impl SchemaTypesMetadata {
44    /// Map `TypeId` of `TypeData` to string
45    pub fn map_type_data<T: TypeData>(&mut self, name: impl Into<String>) {
46        self.type_data_map.insert(TypeId::of::<T>(), name.into());
47    }
48
49    /// Build reflect types list for a given type registration
50    pub fn get_registered_reflect_types(&self, reg: &TypeRegistration) -> Vec<String> {
51        self.type_data_map
52            .iter()
53            .filter_map(|(id, name)| reg.data_by_id(*id).and(Some(name.clone())))
54            .collect()
55    }
56
57    /// Checks if slice contains string value that matches checked `TypeData`
58    pub fn has_type_data<T: TypeData>(&self, types_string_slice: &[String]) -> bool {
59        self.has_type_data_by_id(TypeId::of::<T>(), types_string_slice)
60    }
61
62    /// Checks if slice contains string value that matches checked `TypeData` by id.
63    pub fn has_type_data_by_id(&self, id: TypeId, types_string_slice: &[String]) -> bool {
64        self.type_data_map
65            .get(&id)
66            .is_some_and(|data_s| types_string_slice.iter().any(|e| e.eq(data_s)))
67    }
68}