1use std::collections::{HashMap, HashSet};
4
5use crate::prelude::*;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct NodeID {
13    pub label: String,
14    pub uuid: Uuid,
15}
16
17impl NodeID {
18    pub fn new(label: impl Into<String>) -> Self {
20        NodeID {
21            label: label.into(),
22            uuid: Uuid::new_v4(),
23        }
24    }
25
26    pub fn input(&self, input: impl Into<String>) -> InputID {
29        let label = input.into();
30
31        InputID {
32            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
33            label,
34        }
35    }
36
37    pub fn output(&self, output: impl Into<String>) -> OutputID {
40        let label = output.into();
41
42        OutputID {
43            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
44            label,
45        }
46    }
47
48    pub fn query(&self, query: impl Into<String>) -> QueryID {
51        let label = query.into();
52
53        QueryID {
54            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
55            label,
56        }
57    }
58
59    pub fn queryable(&self, queryable: impl Into<String>) -> QueryableID {
62        let label = queryable.into();
63
64        QueryableID {
65            uuid: Uuid::new_v3(&self.uuid, label.as_bytes()),
66            label,
67        }
68    }
69}
70
71pub struct NodeDataLayout {
74    pub inputs: HashSet<Uuid>,
75    pub outputs: HashSet<Uuid>,
76    pub queries: HashSet<Uuid>,
77    pub queryables: HashSet<Uuid>,
78}
79
80pub struct NodeDebugLayout {
83    pub labels: HashMap<Uuid, String>,
84}
85
86pub struct NodeLayout {
89    pub id: NodeID,
90    pub data: NodeDataLayout,
91    pub debug: NodeDebugLayout,
92}
93
94impl NodeLayout {
95    pub fn new(id: &NodeID) -> Self {
97        Self {
98            id: id.clone(),
99            data: NodeDataLayout {
100                inputs: HashSet::new(),
101                outputs: HashSet::new(),
102                queries: HashSet::new(),
103                queryables: HashSet::new(),
104            },
105            debug: NodeDebugLayout {
106                labels: HashMap::new(),
107            },
108        }
109    }
110
111    pub fn input(&mut self, input: impl Into<String>) -> PrimitiveID {
114        let label: String = input.into();
115        let layout = self.id.input(&label);
116
117        self.data.inputs.insert(layout.uuid);
118
119        self.debug.labels.insert(layout.uuid, label.clone());
120
121        tracing::debug!(
122            "Node '{}' (uuid: {}) added input layout with label: '{}' (uuid: {})",
123            self.id.label,
124            self.id.uuid,
125            label,
126            layout.uuid
127        );
128
129        layout.into()
130    }
131
132    pub fn output(&mut self, output: impl Into<String>) -> PrimitiveID {
135        let label: String = output.into();
136        let layout = self.id.output(&label);
137
138        self.data.outputs.insert(layout.uuid);
139
140        self.debug.labels.insert(layout.uuid, label.clone());
141
142        tracing::debug!(
143            "Node '{}' (uuid: {}) added output layout with label: '{}' (uuid: {})",
144            self.id.label,
145            self.id.uuid,
146            label,
147            layout.uuid
148        );
149
150        layout.into()
151    }
152
153    pub fn query(&mut self, query: impl Into<String>) -> PrimitiveID {
156        let label: String = query.into();
157        let layout = self.id.query(&label);
158
159        self.data.queries.insert(layout.uuid);
160
161        self.debug.labels.insert(layout.uuid, label.clone());
162
163        tracing::debug!(
164            "Node '{}' (uuid: {}) added query layout with label: '{}' (uuid: {})",
165            self.id.label,
166            self.id.uuid,
167            label,
168            layout.uuid
169        );
170
171        layout.into()
172    }
173
174    pub fn queryable(&mut self, queryable: impl Into<String>) -> PrimitiveID {
177        let label: String = queryable.into();
178        let layout = self.id.queryable(&label);
179
180        self.data.queryables.insert(layout.uuid);
181
182        self.debug.labels.insert(layout.uuid, label.clone());
183
184        tracing::debug!(
185            "Node '{}' (uuid: {}) added queryable layout with label: '{}' (uuid: {})",
186            self.id.label,
187            self.id.uuid,
188            label,
189            layout.uuid
190        );
191
192        layout.into()
193    }
194}