flow_graph_interpreter/interpreter/
components.rs

1use 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}