egui_treeize/
lib.rs

1//!
2//! # egui-treeize
3//!
4//! Provides a tree-like graph visualization for egui.
5//!
6
7#![deny(missing_docs, non_ascii_idents, unsafe_code)]
8#![deny(clippy::correctness, clippy::complexity, clippy::perf, clippy::style, clippy::suspicious)]
9#![warn(clippy::pedantic, clippy::dbg_macro, clippy::must_use_candidate)]
10#![allow(clippy::range_plus_one, clippy::inline_always, clippy::use_self)]
11
12pub mod ui;
13
14use std::ops::{Index, IndexMut};
15
16use egui::{Pos2, ahash::HashSet};
17use slab::Slab;
18
19impl<T> Default for Snarl<T> {
20  fn default() -> Self {
21    Snarl::new()
22  }
23}
24
25/// Node identifier.
26///
27/// This is newtype wrapper around [`usize`] that implements
28/// necessary traits, but omits arithmetic operations.
29#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
30#[repr(transparent)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
32pub struct NodeId(pub usize);
33
34/// Node of the graph.
35#[derive(Clone, Debug)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37#[non_exhaustive]
38pub struct Node<T> {
39  /// Node generic value.
40  pub value: T,
41
42  /// Position of the top-left corner of the node.
43  /// This does not include frame margin.
44  pub pos: egui::Pos2,
45
46  /// Flag indicating that the node is open - not collapsed.
47  pub open: bool,
48}
49
50/// Output pin identifier.
51/// Cosists of node id and pin index.
52#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54pub struct OutPinId {
55  /// Node id.
56  pub node: NodeId,
57
58  /// Output pin index.
59  pub output: usize,
60}
61
62/// Input pin identifier. Cosists of node id and pin index.
63#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65pub struct InPinId {
66  /// Node id.
67  pub node: NodeId,
68
69  /// Input pin index.
70  pub input: usize,
71}
72
73/// Connection between two nodes.
74///
75/// Nodes may support multiple connections to the same input or output.
76/// But duplicate connections between same input and the same output are not allowed.
77/// Attempt to insert existing connection will be ignored.
78#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
79#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
80struct Wire {
81  out_pin: OutPinId,
82  in_pin: InPinId,
83}
84
85#[derive(Clone, Debug)]
86struct Wires {
87  wires: HashSet<Wire>,
88}
89
90#[cfg(feature = "serde")]
91impl serde::Serialize for Wires {
92  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93  where
94    S: serde::Serializer,
95  {
96    use serde::ser::SerializeSeq;
97
98    let mut seq = serializer.serialize_seq(Some(self.wires.len()))?;
99    for wire in &self.wires {
100      seq.serialize_element(&wire)?;
101    }
102    seq.end()
103  }
104}
105
106#[cfg(feature = "serde")]
107impl<'de> serde::Deserialize<'de> for Wires {
108  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
109  where
110    D: serde::Deserializer<'de>,
111  {
112    struct Visitor;
113
114    impl<'de> serde::de::Visitor<'de> for Visitor {
115      type Value = HashSet<Wire>;
116
117      fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
118        formatter.write_str("a sequence of wires")
119      }
120
121      fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
122      where
123        A: serde::de::SeqAccess<'de>,
124      {
125        let mut wires = HashSet::with_hasher(egui::ahash::RandomState::new());
126        while let Some(wire) = seq.next_element()? {
127          wires.insert(wire);
128        }
129        Ok(wires)
130      }
131    }
132
133    let wires = deserializer.deserialize_seq(Visitor)?;
134    Ok(Wires { wires })
135  }
136}
137
138impl Wires {
139  fn new() -> Self {
140    Wires { wires: HashSet::with_hasher(egui::ahash::RandomState::new()) }
141  }
142
143  fn insert(&mut self, wire: Wire) -> bool {
144    self.wires.insert(wire)
145  }
146
147  fn remove(&mut self, wire: &Wire) -> bool {
148    self.wires.remove(wire)
149  }
150
151  fn drop_node(&mut self, node: NodeId) -> usize {
152    let count = self.wires.len();
153    self.wires.retain(|wire| wire.out_pin.node != node && wire.in_pin.node != node);
154    count - self.wires.len()
155  }
156
157  fn drop_inputs(&mut self, pin: InPinId) -> usize {
158    let count = self.wires.len();
159    self.wires.retain(|wire| wire.in_pin != pin);
160    count - self.wires.len()
161  }
162
163  fn drop_outputs(&mut self, pin: OutPinId) -> usize {
164    let count = self.wires.len();
165    self.wires.retain(|wire| wire.out_pin != pin);
166    count - self.wires.len()
167  }
168
169  fn wired_inputs(&self, out_pin: OutPinId) -> impl Iterator<Item = InPinId> + '_ {
170    self.wires.iter().filter(move |wire| wire.out_pin == out_pin).map(|wire| wire.in_pin)
171  }
172
173  fn wired_outputs(&self, in_pin: InPinId) -> impl Iterator<Item = OutPinId> + '_ {
174    self.wires.iter().filter(move |wire| wire.in_pin == in_pin).map(|wire| wire.out_pin)
175  }
176
177  fn iter(&self) -> impl Iterator<Item = Wire> + '_ {
178    self.wires.iter().copied()
179  }
180}
181
182/// Snarl is generic node-graph container.
183///
184/// It holds graph state - positioned nodes and wires between their pins.
185/// It can be rendered using [`Snarl::show`].
186#[derive(Clone, Debug)]
187#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
188pub struct Snarl<T> {
189  // #[cfg_attr(feature = "serde", serde(with = "serde_nodes"))]
190  nodes: Slab<Node<T>>,
191  wires: Wires,
192}
193
194impl<T> Snarl<T> {
195  /// Create a new empty Snarl.
196  ///
197  /// # Examples
198  ///
199  /// ```
200  /// # use egui_snarl::Snarl;
201  /// let snarl = Snarl::<()>::new();
202  /// ```
203  #[must_use]
204  pub fn new() -> Self {
205    Snarl { nodes: Slab::new(), wires: Wires::new() }
206  }
207
208  /// Adds a node to the Snarl.
209  /// Returns the index of the node.
210  ///
211  /// # Examples
212  ///
213  /// ```
214  /// # use egui_snarl::Snarl;
215  /// let mut snarl = Snarl::<()>::new();
216  /// snarl.insert_node(egui::pos2(0.0, 0.0), ());
217  /// ```
218  pub fn insert_node(&mut self, pos: egui::Pos2, node: T) -> NodeId {
219    let idx = self.nodes.insert(Node { value: node, pos, open: true });
220
221    NodeId(idx)
222  }
223
224  /// Adds a node to the Snarl in collapsed state.
225  /// Returns the index of the node.
226  ///
227  /// # Examples
228  ///
229  /// ```
230  /// # use egui_snarl::Snarl;
231  /// let mut snarl = Snarl::<()>::new();
232  /// snarl.insert_node_collapsed(egui::pos2(0.0, 0.0), ());
233  /// ```
234  pub fn insert_node_collapsed(&mut self, pos: egui::Pos2, node: T) -> NodeId {
235    let idx = self.nodes.insert(Node { value: node, pos, open: false });
236
237    NodeId(idx)
238  }
239
240  /// Opens or collapses a node.
241  ///
242  /// # Panics
243  ///
244  /// Panics if the node does not exist.
245  #[track_caller]
246  pub fn open_node(&mut self, node: NodeId, open: bool) {
247    self.nodes[node.0].open = open;
248  }
249
250  /// Removes a node from the Snarl.
251  /// Returns the node if it was removed.
252  ///
253  /// # Panics
254  ///
255  /// Panics if the node does not exist.
256  ///
257  /// # Examples
258  ///
259  /// ```
260  /// # use egui_snarl::Snarl;
261  /// let mut snarl = Snarl::<()>::new();
262  /// let node = snarl.insert_node(egui::pos2(0.0, 0.0), ());
263  /// snarl.remove_node(node);
264  /// ```
265  #[track_caller]
266  pub fn remove_node(&mut self, idx: NodeId) -> T {
267    let value = self.nodes.remove(idx.0).value;
268    self.wires.drop_node(idx);
269    value
270  }
271
272  /// Connects two nodes.
273  /// Returns true if the connection was successful.
274  /// Returns false if the connection already exists.
275  ///
276  /// # Panics
277  ///
278  /// Panics if either node does not exist.
279  #[track_caller]
280  pub fn connect(&mut self, from: OutPinId, to: InPinId) -> bool {
281    assert!(self.nodes.contains(from.node.0));
282    assert!(self.nodes.contains(to.node.0));
283
284    let wire = Wire { out_pin: from, in_pin: to };
285    self.wires.insert(wire)
286  }
287
288  /// Disconnects two nodes.
289  /// Returns true if the connection was removed.
290  ///
291  /// # Panics
292  ///
293  /// Panics if either node does not exist.
294  #[track_caller]
295  pub fn disconnect(&mut self, from: OutPinId, to: InPinId) -> bool {
296    assert!(self.nodes.contains(from.node.0));
297    assert!(self.nodes.contains(to.node.0));
298
299    let wire = Wire { out_pin: from, in_pin: to };
300
301    self.wires.remove(&wire)
302  }
303
304  /// Removes all connections to the node's pin.
305  ///
306  /// Returns number of removed connections.
307  ///
308  /// # Panics
309  ///
310  /// Panics if the node does not exist.
311  #[track_caller]
312  pub fn drop_inputs(&mut self, pin: InPinId) -> usize {
313    assert!(self.nodes.contains(pin.node.0));
314    self.wires.drop_inputs(pin)
315  }
316
317  /// Removes all connections from the node's pin.
318  /// Returns number of removed connections.
319  ///
320  /// # Panics
321  ///
322  /// Panics if the node does not exist.
323  #[track_caller]
324  pub fn drop_outputs(&mut self, pin: OutPinId) -> usize {
325    assert!(self.nodes.contains(pin.node.0));
326    self.wires.drop_outputs(pin)
327  }
328
329  /// Returns reference to the node.
330  #[must_use]
331  pub fn get_node(&self, idx: NodeId) -> Option<&T> {
332    self.nodes.get(idx.0).map(|node| &node.value)
333  }
334
335  /// Returns mutable reference to the node.
336  pub fn get_node_mut(&mut self, idx: NodeId) -> Option<&mut T> {
337    match self.nodes.get_mut(idx.0) {
338      Some(node) => Some(&mut node.value),
339      None => None,
340    }
341  }
342
343  /// Returns reference to the node data.
344  #[must_use]
345  pub fn get_node_info(&self, idx: NodeId) -> Option<&Node<T>> {
346    self.nodes.get(idx.0)
347  }
348
349  /// Returns mutable reference to the node data.
350  pub fn get_node_info_mut(&mut self, idx: NodeId) -> Option<&mut Node<T>> {
351    self.nodes.get_mut(idx.0)
352  }
353
354  /// Iterates over shared references to each node.
355  pub fn nodes(&self) -> NodesIter<'_, T> {
356    NodesIter { nodes: self.nodes.iter() }
357  }
358
359  /// Iterates over mutable references to each node.
360  pub fn nodes_mut(&mut self) -> NodesIterMut<'_, T> {
361    NodesIterMut { nodes: self.nodes.iter_mut() }
362  }
363
364  /// Iterates over shared references to each node and its position.
365  pub fn nodes_pos(&self) -> NodesPosIter<'_, T> {
366    NodesPosIter { nodes: self.nodes.iter() }
367  }
368
369  /// Iterates over mutable references to each node and its position.
370  pub fn nodes_pos_mut(&mut self) -> NodesPosIterMut<'_, T> {
371    NodesPosIterMut { nodes: self.nodes.iter_mut() }
372  }
373
374  /// Iterates over shared references to each node and its identifier.
375  pub fn node_ids(&self) -> NodesIdsIter<'_, T> {
376    NodesIdsIter { nodes: self.nodes.iter() }
377  }
378
379  /// Iterates over mutable references to each node and its identifier.
380  pub fn nodes_ids_mut(&mut self) -> NodesIdsIterMut<'_, T> {
381    NodesIdsIterMut { nodes: self.nodes.iter_mut() }
382  }
383
384  /// Iterates over shared references to each node, its position and its identifier.
385  pub fn nodes_pos_ids(&self) -> NodesPosIdsIter<'_, T> {
386    NodesPosIdsIter { nodes: self.nodes.iter() }
387  }
388
389  /// Iterates over mutable references to each node, its position and its identifier.
390  pub fn nodes_pos_ids_mut(&mut self) -> NodesPosIdsIterMut<'_, T> {
391    NodesPosIdsIterMut { nodes: self.nodes.iter_mut() }
392  }
393
394  /// Iterates over shared references to each node data.
395  pub fn nodes_info(&self) -> NodeInfoIter<'_, T> {
396    NodeInfoIter { nodes: self.nodes.iter() }
397  }
398
399  /// Iterates over mutable references to each node data.
400  pub fn nodes_info_mut(&mut self) -> NodeInfoIterMut<'_, T> {
401    NodeInfoIterMut { nodes: self.nodes.iter_mut() }
402  }
403
404  /// Iterates over shared references to each node id and data.
405  pub fn nodes_ids_data(&self) -> NodeIdsDataIter<'_, T> {
406    NodeIdsDataIter { nodes: self.nodes.iter() }
407  }
408
409  /// Iterates over mutable references to each node id and data.
410  pub fn nodes_ids_data_mut(&mut self) -> NodeIdsDataIterMut<'_, T> {
411    NodeIdsDataIterMut { nodes: self.nodes.iter_mut() }
412  }
413
414  /// Iterates over wires.
415  pub fn wires(&self) -> impl Iterator<Item = (OutPinId, InPinId)> + '_ {
416    self.wires.iter().map(|wire| (wire.out_pin, wire.in_pin))
417  }
418
419  /// Returns input pin of the node.
420  #[must_use]
421  pub fn in_pin(&self, pin: InPinId) -> InPin {
422    InPin::new(self, pin)
423  }
424
425  /// Returns output pin of the node.
426  #[must_use]
427  pub fn out_pin(&self, pin: OutPinId) -> OutPin {
428    OutPin::new(self, pin)
429  }
430}
431
432impl<T> Index<NodeId> for Snarl<T> {
433  type Output = T;
434
435  #[inline]
436  #[track_caller]
437  fn index(&self, idx: NodeId) -> &Self::Output {
438    &self.nodes[idx.0].value
439  }
440}
441
442impl<T> IndexMut<NodeId> for Snarl<T> {
443  #[inline]
444  #[track_caller]
445  fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
446    &mut self.nodes[idx.0].value
447  }
448}
449
450/// Iterator over shared references to nodes.
451#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
452pub struct NodesIter<'a, T> {
453  nodes: slab::Iter<'a, Node<T>>,
454}
455
456impl<'a, T> Iterator for NodesIter<'a, T> {
457  type Item = &'a T;
458
459  fn size_hint(&self) -> (usize, Option<usize>) {
460    self.nodes.size_hint()
461  }
462
463  fn next(&mut self) -> Option<&'a T> {
464    let (_, node) = self.nodes.next()?;
465    Some(&node.value)
466  }
467
468  fn nth(&mut self, n: usize) -> Option<&'a T> {
469    let (_, node) = self.nodes.nth(n)?;
470    Some(&node.value)
471  }
472}
473
474/// Iterator over mutable references to nodes.
475#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
476pub struct NodesIterMut<'a, T> {
477  nodes: slab::IterMut<'a, Node<T>>,
478}
479
480impl<'a, T> Iterator for NodesIterMut<'a, T> {
481  type Item = &'a mut T;
482
483  fn size_hint(&self) -> (usize, Option<usize>) {
484    self.nodes.size_hint()
485  }
486
487  fn next(&mut self) -> Option<&'a mut T> {
488    let (_, node) = self.nodes.next()?;
489    Some(&mut node.value)
490  }
491
492  fn nth(&mut self, n: usize) -> Option<&'a mut T> {
493    let (_, node) = self.nodes.nth(n)?;
494    Some(&mut node.value)
495  }
496}
497
498/// Iterator over shared references to nodes and their positions.
499#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
500pub struct NodesPosIter<'a, T> {
501  nodes: slab::Iter<'a, Node<T>>,
502}
503
504impl<'a, T> Iterator for NodesPosIter<'a, T> {
505  type Item = (Pos2, &'a T);
506
507  fn size_hint(&self) -> (usize, Option<usize>) {
508    self.nodes.size_hint()
509  }
510
511  fn next(&mut self) -> Option<(Pos2, &'a T)> {
512    let (_, node) = self.nodes.next()?;
513    Some((node.pos, &node.value))
514  }
515
516  fn nth(&mut self, n: usize) -> Option<(Pos2, &'a T)> {
517    let (_, node) = self.nodes.nth(n)?;
518    Some((node.pos, &node.value))
519  }
520}
521
522/// Iterator over mutable references to nodes and their positions.
523#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
524pub struct NodesPosIterMut<'a, T> {
525  nodes: slab::IterMut<'a, Node<T>>,
526}
527
528impl<'a, T> Iterator for NodesPosIterMut<'a, T> {
529  type Item = (Pos2, &'a mut T);
530
531  fn size_hint(&self) -> (usize, Option<usize>) {
532    self.nodes.size_hint()
533  }
534
535  fn next(&mut self) -> Option<(Pos2, &'a mut T)> {
536    let (_, node) = self.nodes.next()?;
537    Some((node.pos, &mut node.value))
538  }
539
540  fn nth(&mut self, n: usize) -> Option<(Pos2, &'a mut T)> {
541    let (_, node) = self.nodes.nth(n)?;
542    Some((node.pos, &mut node.value))
543  }
544}
545
546/// Iterator over shared references to nodes and their identifiers.
547#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
548pub struct NodesIdsIter<'a, T> {
549  nodes: slab::Iter<'a, Node<T>>,
550}
551
552impl<'a, T> Iterator for NodesIdsIter<'a, T> {
553  type Item = (NodeId, &'a T);
554
555  fn size_hint(&self) -> (usize, Option<usize>) {
556    self.nodes.size_hint()
557  }
558
559  fn next(&mut self) -> Option<(NodeId, &'a T)> {
560    let (idx, node) = self.nodes.next()?;
561    Some((NodeId(idx), &node.value))
562  }
563
564  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a T)> {
565    let (idx, node) = self.nodes.nth(n)?;
566    Some((NodeId(idx), &node.value))
567  }
568}
569
570/// Iterator over mutable references to nodes and their identifiers.
571#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
572pub struct NodesIdsIterMut<'a, T> {
573  nodes: slab::IterMut<'a, Node<T>>,
574}
575
576impl<'a, T> Iterator for NodesIdsIterMut<'a, T> {
577  type Item = (NodeId, &'a mut T);
578
579  fn size_hint(&self) -> (usize, Option<usize>) {
580    self.nodes.size_hint()
581  }
582
583  fn next(&mut self) -> Option<(NodeId, &'a mut T)> {
584    let (idx, node) = self.nodes.next()?;
585    Some((NodeId(idx), &mut node.value))
586  }
587
588  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut T)> {
589    let (idx, node) = self.nodes.nth(n)?;
590    Some((NodeId(idx), &mut node.value))
591  }
592}
593
594/// Iterator over shared references to nodes, their positions and their identifiers.
595#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
596pub struct NodesPosIdsIter<'a, T> {
597  nodes: slab::Iter<'a, Node<T>>,
598}
599
600impl<'a, T> Iterator for NodesPosIdsIter<'a, T> {
601  type Item = (NodeId, Pos2, &'a T);
602
603  fn size_hint(&self) -> (usize, Option<usize>) {
604    self.nodes.size_hint()
605  }
606
607  fn next(&mut self) -> Option<(NodeId, Pos2, &'a T)> {
608    let (idx, node) = self.nodes.next()?;
609    Some((NodeId(idx), node.pos, &node.value))
610  }
611
612  fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a T)> {
613    let (idx, node) = self.nodes.nth(n)?;
614    Some((NodeId(idx), node.pos, &node.value))
615  }
616}
617
618/// Iterator over mutable references to nodes, their positions and their identifiers.
619#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
620pub struct NodesPosIdsIterMut<'a, T> {
621  nodes: slab::IterMut<'a, Node<T>>,
622}
623
624impl<'a, T> Iterator for NodesPosIdsIterMut<'a, T> {
625  type Item = (NodeId, Pos2, &'a mut T);
626
627  fn size_hint(&self) -> (usize, Option<usize>) {
628    self.nodes.size_hint()
629  }
630
631  fn next(&mut self) -> Option<(NodeId, Pos2, &'a mut T)> {
632    let (idx, node) = self.nodes.next()?;
633    Some((NodeId(idx), node.pos, &mut node.value))
634  }
635
636  fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a mut T)> {
637    let (idx, node) = self.nodes.nth(n)?;
638    Some((NodeId(idx), node.pos, &mut node.value))
639  }
640}
641
642/// Iterator over shared references to nodes.
643#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
644pub struct NodeInfoIter<'a, T> {
645  nodes: slab::Iter<'a, Node<T>>,
646}
647
648impl<'a, T> Iterator for NodeInfoIter<'a, T> {
649  type Item = &'a Node<T>;
650
651  fn size_hint(&self) -> (usize, Option<usize>) {
652    self.nodes.size_hint()
653  }
654
655  fn next(&mut self) -> Option<&'a Node<T>> {
656    let (_, node) = self.nodes.next()?;
657    Some(node)
658  }
659
660  fn nth(&mut self, n: usize) -> Option<&'a Node<T>> {
661    let (_, node) = self.nodes.nth(n)?;
662    Some(node)
663  }
664}
665
666/// Iterator over mutable references to nodes.
667#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
668pub struct NodeInfoIterMut<'a, T> {
669  nodes: slab::IterMut<'a, Node<T>>,
670}
671
672impl<'a, T> Iterator for NodeInfoIterMut<'a, T> {
673  type Item = &'a mut Node<T>;
674
675  fn size_hint(&self) -> (usize, Option<usize>) {
676    self.nodes.size_hint()
677  }
678
679  fn next(&mut self) -> Option<&'a mut Node<T>> {
680    let (_, node) = self.nodes.next()?;
681    Some(node)
682  }
683
684  fn nth(&mut self, n: usize) -> Option<&'a mut Node<T>> {
685    let (_, node) = self.nodes.nth(n)?;
686    Some(node)
687  }
688}
689
690/// Iterator over shared references to nodes.
691#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
692pub struct NodeIdsDataIter<'a, T> {
693  nodes: slab::Iter<'a, Node<T>>,
694}
695
696impl<'a, T> Iterator for NodeIdsDataIter<'a, T> {
697  type Item = (NodeId, &'a Node<T>);
698
699  fn size_hint(&self) -> (usize, Option<usize>) {
700    self.nodes.size_hint()
701  }
702
703  fn next(&mut self) -> Option<(NodeId, &'a Node<T>)> {
704    let (id, node) = self.nodes.next()?;
705    Some((NodeId(id), node))
706  }
707
708  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a Node<T>)> {
709    let (id, node) = self.nodes.nth(n)?;
710    Some((NodeId(id), node))
711  }
712}
713
714/// Iterator over mutable references to nodes.
715#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
716pub struct NodeIdsDataIterMut<'a, T> {
717  nodes: slab::IterMut<'a, Node<T>>,
718}
719
720impl<'a, T> Iterator for NodeIdsDataIterMut<'a, T> {
721  type Item = (NodeId, &'a mut Node<T>);
722
723  fn size_hint(&self) -> (usize, Option<usize>) {
724    self.nodes.size_hint()
725  }
726
727  fn next(&mut self) -> Option<(NodeId, &'a mut Node<T>)> {
728    let (id, node) = self.nodes.next()?;
729    Some((NodeId(id), node))
730  }
731
732  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut Node<T>)> {
733    let (id, node) = self.nodes.nth(n)?;
734    Some((NodeId(id), node))
735  }
736}
737
738/// Node and its output pin.
739#[derive(Clone, Debug)]
740pub struct OutPin {
741  /// Output pin identifier.
742  pub id: OutPinId,
743
744  /// List of input pins connected to this output pin.
745  pub remotes: Vec<InPinId>,
746}
747
748/// Node and its output pin.
749#[derive(Clone, Debug)]
750pub struct InPin {
751  /// Input pin identifier.
752  pub id: InPinId,
753
754  /// List of output pins connected to this input pin.
755  pub remotes: Vec<OutPinId>,
756}
757
758impl OutPin {
759  fn new<T>(snarl: &Snarl<T>, pin: OutPinId) -> Self {
760    OutPin { id: pin, remotes: snarl.wires.wired_inputs(pin).collect() }
761  }
762}
763
764impl InPin {
765  fn new<T>(snarl: &Snarl<T>, pin: InPinId) -> Self {
766    InPin { id: pin, remotes: snarl.wires.wired_outputs(pin).collect() }
767  }
768}