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