egui_snarl/
lib.rs

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