flow_graph/schematic/iterators/
connection.rs

1use super::*;
2use crate::{Connection, ConnectionIndex};
3
4#[derive(Debug, Clone)]
5#[must_use]
6pub struct Connections<'graph, DATA> {
7  schematic: &'graph Schematic<DATA>,
8  pub(super) connections: Vec<ConnectionIndex>,
9  pub(super) cur_index: usize,
10}
11
12impl<'graph, DATA> Connections<'graph, DATA> {
13  pub(crate) fn new(schematic: &'graph Schematic<DATA>, connections: Vec<ConnectionIndex>) -> Self {
14    Self {
15      schematic,
16      connections,
17      cur_index: 0,
18    }
19  }
20
21  #[must_use]
22  pub fn len(&self) -> usize {
23    self.connections.len()
24  }
25
26  #[must_use]
27  pub fn is_empty(&self) -> bool {
28    self.connections.is_empty()
29  }
30}
31
32impl<'graph, DATA> Iterator for Connections<'graph, DATA>
33where
34  DATA: Clone,
35{
36  type Item = ConnectionRef<'graph, DATA>;
37
38  fn next(&mut self) -> Option<ConnectionRef<'graph, DATA>> {
39    let result = self
40      .connections
41      .get(self.cur_index)
42      .map(|index| ConnectionRef::new(self.schematic, *index));
43    self.cur_index += 1;
44    result
45  }
46}
47
48impl<'graph, DATA> std::fmt::Display for Connections<'graph, DATA>
49where
50  DATA: Clone,
51{
52  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53    for (index, _) in self.connections.iter().enumerate() {
54      let comma = if index < (self.connections.len() - 1) { ", " } else { "" };
55      if index == self.cur_index {
56        write!(
57          f,
58          ">>>{}<<<{}",
59          display_connection(self.schematic, get_connection(self.schematic, index)),
60          comma
61        )?;
62      } else {
63        write!(
64          f,
65          "{}{}",
66          display_connection(self.schematic, get_connection(self.schematic, index)),
67          comma
68        )?;
69      }
70    }
71    if self.cur_index >= self.connections.len() {
72      write!(f, ", >>>DONE<<<")?;
73    }
74    Ok(())
75  }
76}
77
78#[derive(Debug, Clone)]
79#[must_use]
80pub struct ConnectionRef<'graph, DATA> {
81  schematic: &'graph Schematic<DATA>,
82  pub(crate) index: ConnectionIndex,
83}
84
85impl<'graph, DATA> ConnectionRef<'graph, DATA>
86where
87  DATA: Clone,
88{
89  pub(crate) const fn new(schematic: &'graph Schematic<DATA>, index: ConnectionIndex) -> Self {
90    Self { schematic, index }
91  }
92
93  pub fn from(&self) -> Port<DATA> {
94    let connection = &self.schematic.connections[self.index];
95    Port::new(self.schematic, connection.from)
96  }
97
98  pub fn to(&self) -> Port<DATA> {
99    let connection = &self.schematic.connections[self.index];
100    Port::new(self.schematic, connection.to)
101  }
102
103  pub fn inner(&self) -> &Connection<DATA> {
104    get_connection(self.schematic, self.index)
105  }
106
107  #[must_use]
108  pub const fn index(&self) -> ConnectionIndex {
109    self.index
110  }
111}
112
113impl<'graph, DATA> std::fmt::Display for ConnectionRef<'graph, DATA>
114where
115  DATA: Clone,
116{
117  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118    write!(f, "{}", display_connection(self.schematic, self.inner()))
119  }
120}
121
122fn display_connection<DATA>(schematic: &Schematic<DATA>, connection: &Connection<DATA>) -> String
123where
124  DATA: Clone,
125{
126  let from_node = &schematic.nodes[connection.from.node_index];
127  let from_port = &from_node.outputs()[connection.from.port_index];
128  let to_node = &schematic.nodes[connection.to.node_index];
129  let to_port = &to_node.inputs()[connection.to.port_index];
130  format!("{}[{}]=>{}[{}]", from_node, from_port, to_node, to_port)
131}