1use crate::partial::PartialPaths;
9
10use super::Error;
11use super::NodeID;
12
13#[derive(Clone, Debug, Eq, PartialEq)]
14#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
15#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
16pub struct PartialPath {
17 pub(crate) start_node: NodeID,
18 pub(crate) end_node: NodeID,
19 pub(crate) symbol_stack_precondition: PartialSymbolStack,
20 pub(crate) symbol_stack_postcondition: PartialSymbolStack,
21 pub(crate) scope_stack_precondition: PartialScopeStack,
22 pub(crate) scope_stack_postcondition: PartialScopeStack,
23 pub(crate) edges: PartialPathEdgeList,
24}
25
26impl PartialPath {
27 pub fn from_partial_path(
28 graph: &crate::graph::StackGraph,
29 partials: &mut PartialPaths,
30 value: &crate::partial::PartialPath,
31 ) -> Self {
32 Self {
33 start_node: NodeID::from_node(graph, value.start_node),
34 end_node: NodeID::from_node(graph, value.end_node),
35 symbol_stack_precondition: PartialSymbolStack::from_partial_symbol_stack(
36 graph,
37 partials,
38 &value.symbol_stack_precondition,
39 ),
40 symbol_stack_postcondition: PartialSymbolStack::from_partial_symbol_stack(
41 graph,
42 partials,
43 &value.symbol_stack_postcondition,
44 ),
45 scope_stack_precondition: PartialScopeStack::from_partial_scope_stack(
46 graph,
47 partials,
48 &value.scope_stack_precondition,
49 ),
50 scope_stack_postcondition: PartialScopeStack::from_partial_scope_stack(
51 graph,
52 partials,
53 &value.scope_stack_postcondition,
54 ),
55 edges: PartialPathEdgeList::from_partial_path_edge_list(graph, partials, &value.edges),
56 }
57 }
58
59 pub fn to_partial_path(
60 &self,
61 graph: &mut crate::graph::StackGraph,
62 partials: &mut PartialPaths,
63 ) -> Result<crate::partial::PartialPath, Error> {
64 Ok(crate::partial::PartialPath {
65 start_node: self.start_node.to_node(graph)?,
66 end_node: self.end_node.to_node(graph)?,
67 symbol_stack_precondition: self
68 .symbol_stack_precondition
69 .to_partial_symbol_stack(graph, partials)?,
70 symbol_stack_postcondition: self
71 .symbol_stack_postcondition
72 .to_partial_symbol_stack(graph, partials)?,
73 scope_stack_precondition: self
74 .scope_stack_precondition
75 .to_partial_scope_stack(graph, partials)?,
76 scope_stack_postcondition: self
77 .scope_stack_postcondition
78 .to_partial_scope_stack(graph, partials)?,
79 edges: self.edges.to_partial_path_edge_list(graph, partials)?,
80 })
81 }
82}
83
84#[derive(Clone, Debug, Eq, PartialEq)]
85#[cfg_attr(
86 feature = "serde",
87 serde_with::skip_serializing_none, derive(serde::Deserialize, serde::Serialize),
89)]
90#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
91pub struct PartialScopeStack {
92 pub(crate) scopes: Vec<NodeID>,
93 variable: Option<ScopeStackVariable>,
94}
95
96impl PartialScopeStack {
97 pub fn from_partial_scope_stack(
98 graph: &crate::graph::StackGraph,
99 partials: &mut PartialPaths,
100 value: &crate::partial::PartialScopeStack,
101 ) -> Self {
102 let mut value = *value;
103 let mut scopes = Vec::new();
104 while let Some(scope) = value.pop_front(partials) {
105 scopes.push(NodeID::from_node(graph, scope));
106 }
107 Self {
108 scopes,
109 variable: value
110 .variable()
111 .map(|v| ScopeStackVariable::from_scope_stack_variable(v)),
112 }
113 }
114
115 pub fn to_partial_scope_stack(
116 &self,
117 graph: &mut crate::graph::StackGraph,
118 partials: &mut PartialPaths,
119 ) -> Result<crate::partial::PartialScopeStack, Error> {
120 let mut value = match &self.variable {
121 Some(variable) => crate::partial::PartialScopeStack::from_variable(
122 variable.to_scope_stack_variable()?,
123 ),
124 None => crate::partial::PartialScopeStack::empty(),
125 };
126 for scope in &self.scopes {
127 let scope = scope.to_node(graph)?;
128 value.push_back(partials, scope);
129 }
130 Ok(value)
131 }
132}
133
134#[derive(Clone, Debug, Eq, PartialEq)]
135#[cfg_attr(
136 feature = "serde",
137 derive(serde::Deserialize, serde::Serialize),
138 serde(transparent)
139)]
140#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
141pub struct ScopeStackVariable(u32);
142
143impl ScopeStackVariable {
144 pub fn from_scope_stack_variable(value: crate::partial::ScopeStackVariable) -> Self {
145 Self(value.as_u32())
146 }
147
148 pub fn to_scope_stack_variable(&self) -> Result<crate::partial::ScopeStackVariable, Error> {
149 crate::partial::ScopeStackVariable::new(self.0)
150 .ok_or_else(|| Error::InvalidStackVariable(self.0))
151 }
152}
153
154#[derive(Clone, Debug, Eq, PartialEq)]
155#[cfg_attr(
156 feature = "serde",
157 serde_with::skip_serializing_none, derive(serde::Deserialize, serde::Serialize),
159)]
160#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
161pub struct PartialSymbolStack {
162 pub(crate) symbols: Vec<PartialScopedSymbol>,
163 variable: Option<SymbolStackVariable>,
164}
165
166impl PartialSymbolStack {
167 pub fn from_partial_symbol_stack(
168 graph: &crate::graph::StackGraph,
169 partials: &mut PartialPaths,
170 value: &crate::partial::PartialSymbolStack,
171 ) -> Self {
172 let mut value = *value;
173 let mut symbols = Vec::new();
174 while let Some(symbol) = value.pop_front(partials) {
175 symbols.push(PartialScopedSymbol::from_partial_scoped_symbol(
176 graph, partials, &symbol,
177 ));
178 }
179 Self {
180 symbols,
181 variable: value
182 .variable()
183 .map(|v| SymbolStackVariable::from_symbol_stack_variable(v)),
184 }
185 }
186
187 pub fn to_partial_symbol_stack(
188 &self,
189 graph: &mut crate::graph::StackGraph,
190 partials: &mut PartialPaths,
191 ) -> Result<crate::partial::PartialSymbolStack, Error> {
192 let mut value = match &self.variable {
193 Some(variable) => crate::partial::PartialSymbolStack::from_variable(
194 variable.to_symbol_stack_variable()?,
195 ),
196 None => crate::partial::PartialSymbolStack::empty(),
197 };
198 for symbol in &self.symbols {
199 let symbol = symbol.to_partial_scoped_symbol(graph, partials)?;
200 value.push_back(partials, symbol);
201 }
202 Ok(value)
203 }
204}
205
206#[derive(Clone, Debug, Eq, PartialEq)]
207#[cfg_attr(
208 feature = "serde",
209 derive(serde::Deserialize, serde::Serialize),
210 serde(transparent)
211)]
212#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
213pub struct SymbolStackVariable(u32);
214
215impl SymbolStackVariable {
216 pub fn from_symbol_stack_variable(value: crate::partial::SymbolStackVariable) -> Self {
217 Self(value.as_u32())
218 }
219
220 pub fn to_symbol_stack_variable(&self) -> Result<crate::partial::SymbolStackVariable, Error> {
221 crate::partial::SymbolStackVariable::new(self.0)
222 .ok_or_else(|| Error::InvalidStackVariable(self.0))
223 }
224}
225
226#[derive(Clone, Debug, Eq, PartialEq)]
227#[cfg_attr(
228 feature = "serde",
229 serde_with::skip_serializing_none, derive(serde::Deserialize, serde::Serialize),
231)]
232#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
233pub struct PartialScopedSymbol {
234 symbol: String,
235 pub(crate) scopes: Option<PartialScopeStack>,
236}
237
238impl PartialScopedSymbol {
239 pub fn from_partial_scoped_symbol(
240 graph: &crate::graph::StackGraph,
241 partials: &mut crate::partial::PartialPaths,
242 value: &crate::partial::PartialScopedSymbol,
243 ) -> Self {
244 Self {
245 symbol: graph[value.symbol].to_string(),
246 scopes: value.scopes.into_option().map(|scopes| {
247 PartialScopeStack::from_partial_scope_stack(graph, partials, &scopes)
248 }),
249 }
250 }
251
252 pub fn to_partial_scoped_symbol(
253 &self,
254 graph: &mut crate::graph::StackGraph,
255 partials: &mut crate::partial::PartialPaths,
256 ) -> Result<crate::partial::PartialScopedSymbol, Error> {
257 Ok(crate::partial::PartialScopedSymbol {
258 symbol: graph.add_symbol(&self.symbol),
259 scopes: self
260 .scopes
261 .as_ref()
262 .map(|scopes| scopes.to_partial_scope_stack(graph, partials))
263 .transpose()?
264 .into(),
265 })
266 }
267}
268
269#[derive(Clone, Debug, Eq, PartialEq)]
270#[cfg_attr(
271 feature = "serde",
272 derive(serde::Deserialize, serde::Serialize),
273 serde(transparent)
274)]
275#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
276pub struct PartialPathEdgeList {
277 pub(crate) edges: Vec<PartialPathEdge>,
278}
279
280impl PartialPathEdgeList {
281 pub fn from_partial_path_edge_list(
282 graph: &crate::graph::StackGraph,
283 partials: &mut PartialPaths,
284 value: &crate::partial::PartialPathEdgeList,
285 ) -> Self {
286 let mut value = *value;
287 let mut edges = Vec::new();
288 while let Some(edge) = value.pop_front(partials) {
289 edges.push(PartialPathEdge::from_partial_path_edge(
290 graph, partials, &edge,
291 ));
292 }
293 Self { edges }
294 }
295
296 pub fn to_partial_path_edge_list(
297 &self,
298 graph: &mut crate::graph::StackGraph,
299 partials: &mut PartialPaths,
300 ) -> Result<crate::partial::PartialPathEdgeList, Error> {
301 let mut value = crate::partial::PartialPathEdgeList::empty();
302 for edge in &self.edges {
303 let edge = edge.to_partial_path_edge(graph, partials)?;
304 value.push_back(partials, edge);
305 }
306 Ok(value)
307 }
308}
309
310#[derive(Clone, Debug, Eq, PartialEq)]
311#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
312#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
313pub struct PartialPathEdge {
314 pub(crate) source: NodeID,
315 precedence: i32,
316}
317
318impl PartialPathEdge {
319 pub fn from_partial_path_edge(
320 graph: &crate::graph::StackGraph,
321 _partials: &mut PartialPaths,
322 value: &crate::partial::PartialPathEdge,
323 ) -> Self {
324 Self {
325 source: NodeID::from_node_id(graph, value.source_node_id),
326 precedence: value.precedence,
327 }
328 }
329
330 pub fn to_partial_path_edge(
331 &self,
332 graph: &mut crate::graph::StackGraph,
333 _partials: &mut PartialPaths,
334 ) -> Result<crate::partial::PartialPathEdge, Error> {
335 Ok(crate::partial::PartialPathEdge {
336 source_node_id: self.source.to_node_id(graph)?,
337 precedence: self.precedence,
338 })
339 }
340}