flow_graph_interpreter/interpreter/
components.rs1use std::collections::HashMap;
2use std::fmt::Debug;
3use std::sync::atomic::AtomicBool;
4use std::sync::Arc;
5
6pub(crate) mod component;
7pub(crate) mod core;
8pub(crate) mod internal;
9pub(crate) mod null;
10pub(crate) mod self_component;
11
12use flow_component::Component;
13use wick_interface_types::{ComponentSignature, OperationSignature};
14
15use self::core::CoreComponent;
16use self::internal::InternalComponent;
17use crate::error::InterpreterError;
18use crate::graph::types::Network;
19use crate::SharedHandler;
20
21pub(crate) type ComponentMap = HashMap<String, ComponentSignature>;
22
23#[derive(Debug)]
24#[must_use]
25pub struct HandlerMap {
26 components: HashMap<String, NamespaceHandler>,
27}
28
29impl Default for HandlerMap {
30 fn default() -> Self {
31 Self::new(Vec::new()).unwrap()
32 }
33}
34
35impl HandlerMap {
36 pub fn new(components: Vec<NamespaceHandler>) -> Result<Self, InterpreterError> {
37 let mut map = Self {
38 components: Default::default(),
39 };
40 for component in components {
41 map.add(component)?;
42 }
43
44 map.add(NamespaceHandler::new(
45 InternalComponent::ID,
46 Box::new(InternalComponent::default()),
47 ))?;
48
49 Ok(map)
50 }
51
52 pub(crate) fn add_core(&mut self, network: &Network) -> Result<(), InterpreterError> {
53 self.add(NamespaceHandler::new(
54 CoreComponent::ID,
55 Box::new(CoreComponent::new(network, self)?),
56 ))
57 }
58
59 #[must_use]
60 pub const fn inner(&self) -> &HashMap<String, NamespaceHandler> {
61 &self.components
62 }
63
64 #[must_use]
65 pub fn component_signatures(&self) -> ComponentMap {
66 self
67 .components
68 .iter()
69 .map(|(name, p)| (name.clone(), p.component.signature().clone()))
70 .collect::<HashMap<String, ComponentSignature>>()
71 }
72
73 #[must_use]
74 pub fn get(&self, namespace: &str) -> Option<&NamespaceHandler> {
75 self.components.get(namespace)
76 }
77
78 #[must_use]
79 pub fn has(&self, namespace: &str) -> bool {
80 self.components.contains_key(namespace)
81 }
82
83 pub fn add(&mut self, component: NamespaceHandler) -> Result<(), InterpreterError> {
84 if self.components.contains_key(&component.namespace) {
85 return Err(InterpreterError::DuplicateNamespace(component.namespace));
86 }
87 self.components.insert(component.namespace.clone(), component);
88 Ok(())
89 }
90
91 pub(crate) fn keys(&self) -> Vec<String> {
92 self.components.keys().cloned().collect()
93 }
94
95 #[allow(unused)]
96 pub(crate) fn get_signature(&self, namespace: &str) -> Option<&ComponentSignature> {
97 self.components.get(namespace).map(|c| c.component.signature())
98 }
99
100 pub(crate) fn get_op_signature(&self, namespace: &str, name: &str) -> Option<&OperationSignature> {
101 self
102 .components
103 .get(namespace)
104 .and_then(|c| c.component.signature().get_operation(name))
105 }
106
107 pub(crate) fn get_op_list(&self, namespace: &str) -> Vec<&str> {
108 self
109 .components
110 .get(namespace)
111 .map(|c| {
112 c.component
113 .signature()
114 .operations
115 .iter()
116 .map(|op| op.name.as_str())
117 .collect::<Vec<_>>()
118 })
119 .unwrap_or_default()
120 }
121}
122
123pub(crate) fn dyn_component_id(name: &str, schematic: &str, instance: &str) -> String {
124 format!("{}<{}::{}>", name, schematic, instance)
125}
126
127pub(crate) fn reconcile_op_id(ns: &str, name: &str, schematic: &str, instance: &str) -> String {
128 if ns == CoreComponent::ID && core::DYNAMIC_OPERATIONS.contains(&name) {
129 dyn_component_id(name, schematic, instance)
130 } else {
131 name.to_owned()
132 }
133}
134
135#[derive(Clone)]
136#[must_use]
137pub struct NamespaceHandler {
138 pub(crate) namespace: String,
139 pub(crate) component: SharedHandler,
140 pub(crate) exposed: Arc<AtomicBool>,
141}
142
143impl NamespaceHandler {
144 pub fn new<T: Into<String>>(namespace: T, component: Box<dyn Component + Send + Sync>) -> Self {
145 Self {
146 namespace: namespace.into(),
147 component: Arc::new(component),
148 exposed: Arc::new(AtomicBool::new(false)),
149 }
150 }
151
152 pub fn new_from_shared<T: Into<String>>(namespace: T, component: Arc<Box<dyn Component + Send + Sync>>) -> Self {
153 Self {
154 namespace: namespace.into(),
155 component,
156 exposed: Arc::new(AtomicBool::new(false)),
157 }
158 }
159
160 #[must_use]
161 pub fn namespace(&self) -> &str {
162 &self.namespace
163 }
164
165 #[must_use]
166 pub fn component(&self) -> &SharedHandler {
167 &self.component
168 }
169
170 pub fn expose(&self) {
171 self.exposed.store(true, std::sync::atomic::Ordering::Relaxed);
172 }
173
174 #[must_use]
175 pub fn is_exposed(&self) -> bool {
176 self.exposed.load(std::sync::atomic::Ordering::Relaxed)
177 }
178}
179
180impl Debug for NamespaceHandler {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 f.debug_struct("NamespaceHandler")
183 .field("namespace", &self.namespace)
184 .field("component", &self.component.signature())
185 .finish()
186 }
187}