Skip to main content

egui_snarl/
lib.rs

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