reactive_graph_sys_system_environment/
factory.rs

1use std::env;
2use std::ops::Deref;
3use std::sync::Arc;
4use std::sync::LazyLock;
5
6use log::info;
7use reactive_graph_graph::prelude::*;
8use reactive_graph_plugin_api::prelude::plugin::*;
9use reactive_graph_reactive_model_impl::ReactiveEntity;
10use reactive_graph_reactive_model_impl::ReactiveProperties;
11use reactive_graph_reactive_service_api::ReactiveEntityRegistrationError;
12use reactive_graph_runtime_model::COMPONENT_LABELED;
13use reactive_graph_runtime_model::LabeledProperties::LABEL;
14use serde_json::json;
15use thiserror::Error;
16use uuid::Uuid;
17
18use reactive_graph_std_base_model::COMPONENT_NAMED;
19use reactive_graph_std_base_model::NamedProperties::NAME;
20use reactive_graph_std_value_model::COMPONENT_VALUE;
21use reactive_graph_std_value_model::ValueProperties::VALUE;
22
23use reactive_graph_sys_system_environment_model::ENTITY_TYPE_SYSTEM_ENV_VAR;
24use reactive_graph_sys_system_environment_model::NAMESPACE_SYSTEM_ENVIRONMENT_ID;
25
26static SYSTEM_ENV_COMPONENTS: LazyLock<ComponentTypeIds> = LazyLock::new(|| {
27    ComponentTypeIds::new()
28        .component(COMPONENT_LABELED.clone())
29        .component(COMPONENT_VALUE.clone())
30        .component(COMPONENT_NAMED.clone())
31});
32#[derive(Component)]
33pub struct SystemEnvironmentReactiveEntityFactory {
34    #[component(default = "crate::plugin::inject_plugin_context")]
35    context: Arc<dyn PluginContext + Send + Sync>,
36}
37
38#[derive(Debug, Error)]
39pub enum SystemEnvironmentFactoryError {
40    #[error("Entity type not found")]
41    EntityTypeNotFound,
42    #[error("Failed to create reactive entity: {0}")]
43    ReactiveEntityRegistrationError(#[from] ReactiveEntityRegistrationError),
44}
45
46impl SystemEnvironmentReactiveEntityFactory {
47    pub async fn create_entity_instances(&self) -> Result<(), SystemEnvironmentFactoryError> {
48        let entity_type_manager = self.context.get_entity_type_manager();
49        let ty = ENTITY_TYPE_SYSTEM_ENV_VAR.deref();
50        // let ty = EntityTypeId::new_from_type("asdf", "asdf");
51        info!("{ty}");
52        let Some(entity_type) = entity_type_manager.get(ty) else {
53            return Err(SystemEnvironmentFactoryError::EntityTypeNotFound);
54        };
55        let entity_instance_manager = self.context.get_entity_instance_manager();
56        // let components = ComponentTypeIds::new()
57        //     .component(&COMPONENT_LABELED)
58        //     .component(&COMPONENT_VALUE)
59        //     .component(&COMPONENT_NAMED);
60        let properties = PropertyInstances::new_from_property_types_with_defaults(&entity_type.properties);
61        for (name, value) in env::vars() {
62            let id = Uuid::new_v5(&NAMESPACE_SYSTEM_ENVIRONMENT_ID, name.as_bytes());
63            if entity_instance_manager.has(id) {
64                continue;
65            }
66            let mut properties = properties.clone();
67            properties.set(LABEL, json!(format!("/io/reactive-graph/system/env/{}", name.clone().to_lowercase())));
68            properties.set(VALUE, json!(value));
69            properties.set(NAME, json!(name.clone()));
70            let properties = ReactiveProperties::new_with_id_from_properties(id, properties);
71            let reactive_entity = ReactiveEntity::builder()
72                // let entity_instance = EntityInstance::builder()
73                .ty(&entity_type.ty)
74                .id(id)
75                .components(SYSTEM_ENV_COMPONENTS.clone())
76                .properties(properties)
77                .build();
78            if let Err(e) = entity_instance_manager.register(reactive_entity) {
79                return Err(e.into());
80            }
81        }
82        Ok(())
83    }
84}