1use std::collections::HashMap;
11use std::ops::AddAssign;
12
13#[cfg(feature = "display")]
14use std::fmt::{Display, Formatter};
15
16use crate::subgraph_free::{
17 AttrStmt as AstAttrStmt, EdgeStmt, Graph as SFGraph, NodeID, NodeStmt, Port, Stmt,
18};
19
20pub use crate::ast::AList;
21
22#[derive(Debug, Clone)]
27pub struct Graph<A> {
28 pub strict: bool,
32 pub is_digraph: bool,
34 pub name: Option<String>,
36 pub attr: Vec<AttrStmt<A>>,
38 pub nodes: NodeSet<A>,
40 pub edges: EdgeSet<A>,
42 pub ideqs: Vec<IDEq>,
44}
45
46#[cfg(feature = "display")]
47impl<A> Display for Graph<A>
48where
49 A: Display,
50{
51 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
52 if self.strict {
53 write!(f, "strict ")?;
54 }
55 if self.is_digraph {
56 write!(f, "digraph ")?;
57 } else {
58 write!(f, "graph ")?;
59 }
60 if let Some(name) = &self.name {
61 write!(f, "{}", name)?;
62 }
63
64 writeln!(f, "{{")?;
65 for stmt in &self.attr {
66 writeln!(f, "{}", stmt)?;
67 }
68
69 for ideq in &self.ideqs {
70 writeln!(f, "{}", ideq)?;
71 }
72
73 write!(f, "{}", self.nodes)?;
74 write!(f, "{}", self.edges)?;
75 writeln!(f, "}}")?;
76
77 Result::Ok(())
78 }
79}
80
81impl<A> Graph<A> {
82 pub fn filter_map<F, B>(self, f: F) -> Graph<B>
90 where
91 F: Fn(A) -> Option<B>,
92 {
93 let new_attr = self
94 .attr
95 .into_iter()
96 .filter_map(|attr_stmt| attr_stmt.filter_map(&f))
97 .collect();
98 let new_nodes = self.nodes.map(&f);
99 let new_edges = self.edges.map(&f);
100
101 Graph {
102 strict: self.strict,
103 is_digraph: self.is_digraph,
104 name: self.name,
105 attr: new_attr,
106 nodes: new_nodes,
107 edges: new_edges,
108 ideqs: self.ideqs,
109 }
110 }
111}
112
113impl<A, G> From<G> for Graph<A>
114where
115 G: Into<SFGraph<A>>,
116 A: Clone,
117{
118 fn from(graph: G) -> Self {
119 let graph = graph.into();
120 let mut attrs: Vec<AstAttrStmt<_>> = Vec::new();
121 let mut nodes = Vec::new();
122 let mut edges = Vec::new();
123 let mut ideqs = Vec::new();
124
125 for stmt in graph.stmts {
126 match stmt {
127 Stmt::NodeStmt(node) => nodes.push(node),
128 Stmt::EdgeStmt(edge) => edges.push(edge),
129 Stmt::AttrStmt(attr) => attrs.push(attr),
130 Stmt::IDEq(lhs, rhs) => ideqs.push(IDEq {lhs, rhs}),
131 }
132 }
133
134 let mut nodes: NodeSet<A> = nodes.into();
135 let edges: EdgeSet<A> = (edges, &mut nodes).into();
136 let attr: Vec<AttrStmt<A>> = attrs
137 .into_iter()
138 .flat_map(|stmt: AstAttrStmt<_>| {
139 let attr_l: Vec<AttrStmt<A>> = stmt.into();
140 attr_l
141 })
142 .collect();
143
144 Graph {
145 strict: graph.strict,
146 is_digraph: graph.is_digraph,
147 name: graph.name,
148 attr,
149 nodes,
150 edges,
151 ideqs,
152 }
153 }
154}
155
156#[cfg(feature = "petgraph")]
157use petgraph::graph::Graph as PetGraph;
158#[cfg(feature = "petgraph")]
159impl<A> From<Graph<A>> for PetGraph<Node<A>, AList<A>> {
160 fn from(val: Graph<A>) -> Self {
161 let mut graph = PetGraph::new();
162 let mut node_indices = HashMap::new();
163 for node in val.nodes.set {
164 let ni = graph.add_node(node.1);
165 node_indices.insert(node.0, ni);
166 }
167 for edge in val.edges.set {
168 let from_ni = node_indices.get(&edge.from).unwrap();
169 let to_ni = node_indices.get(&edge.to).unwrap();
170 graph.add_edge(*from_ni, *to_ni, edge.attr);
171 }
172 graph
173 }
174}
175
176#[derive(Debug, Clone)]
178pub struct Node<A> {
179 pub id: String,
181 pub port: Option<Port>,
183 pub attr: AList<A>,
185}
186
187impl<A> From<NodeStmt<A>> for Node<A> {
188 fn from(stmt: NodeStmt<A>) -> Self {
189 Node {
190 id: stmt.node.id.to_string(),
191 port: stmt.node.port,
192 attr: stmt.attr.map(|list| list.into()).unwrap_or(AList::empty()),
193 }
194 }
195}
196
197impl<A> From<&NodeID> for Node<A> {
198 fn from(node: &NodeID) -> Self {
199 Node {
200 id: node.id.to_string(),
201 port: node.port.clone(),
202 attr: AList::empty(),
203 }
204 }
205}
206
207impl<A> Node<A> {
208 fn map<F, B>(self, f: F) -> Node<B>
209 where
210 F: Fn(A) -> Option<B>,
211 {
212 Node {
213 id: self.id,
214 port: self.port,
215 attr: self.attr.filter_map_attr(&f),
216 }
217 }
218}
219
220#[cfg(feature = "display")]
221impl<A> Display for Node<A>
222where
223 A: Display,
224{
225 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
226 write!(f, "\"{}\" ", self.id)?;
227 if let Some(port) = &self.port {
228 write!(f, "{}", port)?;
229 }
230 if !self.attr.is_empty() {
231 write!(f, "[{}]", self.attr)?;
232 }
233
234 Ok(())
235 }
236}
237
238#[derive(Debug, Clone)]
240pub struct NodeSet<A> {
241 pub set: HashMap<String, Node<A>>,
244}
245
246impl<A> NodeSet<A> {
247 fn insert_if_absent(&mut self, id: String, or: Node<A>) {
248 if self.set.get(&id).is_none() {
250 self.set.insert(id, or);
251 }
252 }
253
254 fn map<F, B>(self, f: F) -> NodeSet<B>
255 where
256 F: Fn(A) -> Option<B>,
257 {
258 let new_set = self
259 .set
260 .into_iter()
261 .map(|(name, node)| (name, node.map(&f)))
262 .collect();
263 NodeSet { set: new_set }
264 }
265}
266
267impl<A, I> From<I> for NodeSet<A>
268where
269 I: IntoIterator<Item = NodeStmt<A>>,
270{
271 fn from(nodes: I) -> Self {
272 let set: HashMap<_, _> = nodes
273 .into_iter()
274 .map(|node| (node.node.id.to_string(), node.into()))
275 .collect();
276 NodeSet { set }
277 }
278}
279
280#[cfg(feature = "display")]
281impl<A> Display for NodeSet<A>
282where
283 A: Display,
284{
285 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
286 for node in self.set.values() {
287 writeln!(f, "{}", node)?;
288 }
289
290 Ok(())
291 }
292}
293
294#[derive(Debug, Clone)]
296pub struct EdgeSet<A> {
297 pub set: Vec<Edge<A>>,
299}
300
301impl<A> EdgeSet<A> {
302 fn empty() -> Self {
303 Self { set: Vec::new() }
304 }
305
306 fn map<F, B>(self, f: F) -> EdgeSet<B>
307 where
308 F: Fn(A) -> Option<B>,
309 {
310 let new_set = self.set.into_iter().map(|edge| edge.map(&f)).collect();
311 EdgeSet { set: new_set }
312 }
313}
314
315impl<A> AddAssign for EdgeSet<A> {
316 fn add_assign(&mut self, mut rhs: Self) {
317 self.set.append(&mut rhs.set)
318 }
319}
320
321#[cfg(feature = "display")]
322impl<A> Display for EdgeSet<A>
323where
324 A: Display,
325{
326 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
327 for edge in &self.set {
328 writeln!(f, "{}", edge)?;
329 }
330 Ok(())
331 }
332}
333
334#[derive(Debug, Clone, Eq, PartialEq)]
337pub struct Edge<A> {
338 pub from: String,
340 pub to: String,
342 pub attr: AList<A>,
344}
345
346#[cfg(feature = "display")]
347impl<A> Display for Edge<A>
348where
349 A: Display,
350{
351 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
352 write!(f, "\"{}\" -> \"{}\" [{}]", self.from, self.to, self.attr)
353 }
354}
355
356impl<A> Edge<A> {
357 fn map<F, B>(self, f: F) -> Edge<B>
358 where
359 F: Fn(A) -> Option<B>,
360 {
361 Edge {
362 from: self.from,
363 to: self.to,
364 attr: self.attr.filter_map_attr(&f),
365 }
366 }
367}
368
369impl<A> From<(EdgeStmt<A>, &mut NodeSet<A>)> for EdgeSet<A>
370where
371 A: Clone,
372{
373 fn from(tuple: (EdgeStmt<A>, &mut NodeSet<A>)) -> Self {
374 let (stmt, nodes) = tuple;
375 let mut from = stmt.from;
376 let mut rhs = stmt.next;
377 let mut set = Vec::new();
378 let attr = stmt.attr.map(|list| list.into()).unwrap_or(AList::empty());
379
380 loop {
381 let to = rhs.to;
382 let from_id = from.id.clone();
383 let to_id = to.id.clone();
384
385 nodes.insert_if_absent(from.id.to_string(), (&from).into());
386 nodes.insert_if_absent(to.id.to_string(), (&to).into());
387
388 let edge = Edge {
389 from: from_id.to_string(),
390 to: to_id.to_string(),
391 attr: attr.clone(),
392 };
393
394 set.push(edge);
395
396 if rhs.next.is_none() {
397 return EdgeSet { set };
398 }
399 from = to;
400 rhs = *(rhs.next.unwrap());
401 }
402 }
403}
404
405impl<A, I> From<(I, &mut NodeSet<A>)> for EdgeSet<A>
406where
407 I: IntoIterator<Item = EdgeStmt<A>>,
408 A: Clone,
409{
410 fn from(tuple: (I, &mut NodeSet<A>)) -> Self {
411 let (stmts, nodes) = tuple;
412 let mut set = EdgeSet::empty();
413 for stmt in stmts {
414 set += (stmt, &mut *nodes).into();
415 }
416 set
417 }
418}
419
420#[derive(Debug, Copy, Clone)]
421pub enum AttrStmt<A> {
425 Graph(A),
427 Node(A),
429 Edge(A),
431}
432
433impl<A> AttrStmt<A> {
434 fn filter_map<F, B>(self, f: F) -> Option<AttrStmt<B>>
435 where
436 F: Fn(A) -> Option<B>,
437 {
438 match self {
439 AttrStmt::Graph(a) => {
440 f(a).map(AttrStmt::Graph)
441 }
442 AttrStmt::Node(a) => {
443 f(a).map(AttrStmt::Node)
444 }
445 AttrStmt::Edge(a) => {
446 f(a).map(AttrStmt::Edge)
447 }
448 }
449 }
450}
451
452impl<A> From<AstAttrStmt<A>> for Vec<AttrStmt<A>> {
453 fn from(val: AstAttrStmt<A>) -> Self {
454 match val {
455 AstAttrStmt::Graph(list) => {
456 let alist: AList<A> = list.into();
457 alist
458 .into_iter()
459 .map(|attr| AttrStmt::Graph(attr))
460 .collect()
461 }
462 AstAttrStmt::Node(list) => {
463 let alist: AList<A> = list.into();
464 alist
465 .into_iter()
466 .map(|attr| AttrStmt::Node(attr))
467 .collect()
468 }
469 AstAttrStmt::Edge(list) => {
470 let alist: AList<A> = list.into();
471 alist
472 .into_iter()
473 .map(|attr| AttrStmt::Edge(attr))
474 .collect()
475 }
476 }
477 }
478}
479
480#[cfg(feature = "display")]
481impl<A> Display for AttrStmt<A>
482where
483 A: Display,
484{
485 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
486 match self {
487 AttrStmt::Graph(attr) => write!(f, "graph [{}]", attr),
488 AttrStmt::Edge(attr) => write!(f, "edge [{}]", attr),
489 AttrStmt::Node(attr) => write!(f, "node [{}]", attr),
490 }
491 }
492}
493
494#[derive(Clone, Debug)]
495pub struct IDEq {
497 pub lhs: String,
499 pub rhs: String,
501}
502
503#[cfg(feature = "display")]
504impl Display for IDEq {
505 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
506 write!(f, "{} = {}", self.lhs, self.rhs)
507 }
508}