iridis_layout/
node.rs

1use std::collections::{HashMap, HashSet};
2
3use crate::prelude::*;
4
5/// Represents a node
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct NodeLayout {
8    pub label: String,
9    pub uuid: Uuid,
10}
11
12impl NodeLayout {
13    /// Creates a new node layout with a unique UUID v4
14    pub fn new(label: impl Into<String>) -> Self {
15        NodeLayout {
16            label: label.into(),
17            uuid: Uuid::new_v4(),
18        }
19    }
20
21    /// Creates a new input layout with a unique UUID v3 based on the node's UUID and input label
22    pub fn input(&self, input: impl Into<String>) -> InputLayout {
23        let label = input.into();
24        InputLayout {
25            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
26            label,
27        }
28    }
29
30    /// Creates a new output layout with a unique UUID v3 based on the node's UUID and output label
31    pub fn output(&self, output: impl Into<String>) -> OutputLayout {
32        let label = output.into();
33        OutputLayout {
34            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
35            label,
36        }
37    }
38
39    /// Creates a new query layout with a unique UUID v3 based on the node's UUID and query label
40    pub fn query(&self, query: impl Into<String>) -> QueryLayout {
41        let label = query.into();
42        QueryLayout {
43            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
44            label,
45        }
46    }
47
48    /// Creates a new queryable layout with a unique UUID v3 based on the node's UUID and queryable label
49    pub fn queryable(&self, queryable: impl Into<String>) -> QueryableLayout {
50        let label = queryable.into();
51        QueryableLayout {
52            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
53            label,
54        }
55    }
56}
57
58/// This is the object passed to the user's lambda function to build the node's IO layout
59pub struct NodeIOBuilder {
60    /// The node layout this io builder is applied to
61    pub layout: NodeLayout,
62
63    /// The runtime only cares about input UUIDs
64    pub inputs: HashSet<Uuid>,
65    /// The runtime only cares about output UUIDs
66    pub outputs: HashSet<Uuid>,
67    /// The runtime only cares about query UUIDs
68    pub queries: HashSet<Uuid>,
69    /// The runtime only cares about queryable UUIDs
70    pub queryables: HashSet<Uuid>,
71
72    /// Labels for the node's IO, useful for debugging and visualization
73    pub labels: HashMap<Uuid, String>,
74}
75
76impl NodeIOBuilder {
77    pub fn new(layout: &NodeLayout) -> Self {
78        Self {
79            layout: layout.clone(),
80
81            inputs: HashSet::new(),
82            outputs: HashSet::new(),
83            queryables: HashSet::new(),
84            queries: HashSet::new(),
85
86            labels: HashMap::new(),
87        }
88    }
89
90    /// Creates a new input layout with the given label
91    pub fn input(&mut self, input: impl Into<String>) -> IOLayout {
92        let label: String = input.into();
93        let layout = self.layout.input(&label);
94
95        self.inputs.insert(layout.uuid);
96
97        self.labels.insert(layout.uuid, label.clone());
98
99        tracing::debug!(
100            "Node '{}' (uuid: {}) added input layout with label: '{}' (uuid: {})",
101            self.layout.label,
102            self.layout.uuid,
103            label,
104            layout.uuid
105        );
106
107        layout.into()
108    }
109
110    /// Creates a new output layout with the given label
111    pub fn output(&mut self, output: impl Into<String>) -> IOLayout {
112        let label: String = output.into();
113        let layout = self.layout.output(&label);
114
115        self.outputs.insert(layout.uuid);
116
117        self.labels.insert(layout.uuid, label.clone());
118
119        tracing::debug!(
120            "Node '{}' (uuid: {}) added output layout with label: '{}' (uuid: {})",
121            self.layout.label,
122            self.layout.uuid,
123            label,
124            layout.uuid
125        );
126
127        layout.into()
128    }
129
130    /// Creates a new query layout with the given label
131    pub fn query(&mut self, query: impl Into<String>) -> IOLayout {
132        let label: String = query.into();
133        let layout = self.layout.query(&label);
134
135        self.queries.insert(layout.uuid);
136
137        self.labels.insert(layout.uuid, label.clone());
138
139        tracing::debug!(
140            "Node '{}' (uuid: {}) added query layout with label: '{}' (uuid: {})",
141            self.layout.label,
142            self.layout.uuid,
143            label,
144            layout.uuid
145        );
146
147        layout.into()
148    }
149
150    /// Creates a new queryable layout with the given label
151    pub fn queryable(&mut self, queryable: impl Into<String>) -> IOLayout {
152        let label: String = queryable.into();
153        let layout = self.layout.queryable(&label);
154
155        self.queryables.insert(layout.uuid);
156
157        self.labels.insert(layout.uuid, label.clone());
158
159        tracing::debug!(
160            "Node '{}' (uuid: {}) added queryable layout with label: '{}' (uuid: {})",
161            self.layout.label,
162            self.layout.uuid,
163            label,
164            layout.uuid
165        );
166
167        layout.into()
168    }
169}