graph_core/edge.rs
1use crate::NodeId;
2
3/// A directed edge from `source` to `target` carrying a weight of type `W`.
4///
5/// For unweighted graphs use `W = ()` (the default). For weighted graphs use
6/// any numeric type, most commonly `f64`.
7///
8/// # Examples
9///
10/// ```
11/// use graph_core::{Edge, NodeId};
12///
13/// let u = NodeId::new(0);
14/// let v = NodeId::new(1);
15///
16/// // Weighted edge
17/// let weighted = Edge::new(u, v, 3.5_f64);
18/// assert_eq!(weighted.weight, 3.5);
19///
20/// // Unweighted edge (weight = ())
21/// let unweighted: Edge<()> = Edge::new(u, v, ());
22/// assert_eq!(unweighted.source, u);
23/// assert_eq!(unweighted.target, v);
24/// ```
25#[derive(Debug, Clone, PartialEq)]
26pub struct Edge<W = ()> {
27 /// The node this edge originates from.
28 pub source: NodeId,
29 /// The node this edge points to.
30 pub target: NodeId,
31 /// The edge weight. Use `()` for unweighted graphs.
32 pub weight: W,
33}
34
35// ── Construction ──────────────────────────────────────────────────────────────
36
37impl<W> Edge<W> {
38 /// Creates a new directed edge.
39 ///
40 /// # Examples
41 ///
42 /// ```
43 /// use graph_core::{Edge, NodeId};
44 ///
45 /// let e = Edge::new(NodeId::new(0), NodeId::new(1), 2.0_f64);
46 /// assert_eq!(e.weight, 2.0);
47 /// ```
48 #[inline]
49 pub fn new(source: NodeId, target: NodeId, weight: W) -> Self {
50 Edge {
51 source,
52 target,
53 weight,
54 }
55 }
56
57 /// Returns `true` if this is a self-loop (source == target).
58 ///
59 /// # Examples
60 ///
61 /// ```
62 /// use graph_core::{Edge, NodeId};
63 ///
64 /// let looped = Edge::new(NodeId::new(3), NodeId::new(3), ());
65 /// assert!(looped.is_self_loop());
66 ///
67 /// let normal = Edge::new(NodeId::new(0), NodeId::new(1), ());
68 /// assert!(!normal.is_self_loop());
69 /// ```
70 #[must_use]
71 #[inline]
72 pub fn is_self_loop(&self) -> bool {
73 self.source == self.target
74 }
75
76 /// Returns the reversed edge (source and target swapped, weight unchanged).
77 ///
78 /// # Examples
79 ///
80 /// ```
81 /// use graph_core::{Edge, NodeId};
82 ///
83 /// let e = Edge::new(NodeId::new(0), NodeId::new(1), 5u32);
84 /// let r = e.reversed();
85 /// assert_eq!(r.source, NodeId::new(1));
86 /// assert_eq!(r.target, NodeId::new(0));
87 /// assert_eq!(r.weight, 5);
88 /// ```
89 #[must_use]
90 pub fn reversed(self) -> Self
91 where
92 W: Clone,
93 {
94 Edge {
95 source: self.target,
96 target: self.source,
97 weight: self.weight,
98 }
99 }
100}
101
102// ── Type aliases ──────────────────────────────────────────────────────────────
103
104/// A weighted directed edge with `f64` weights.
105///
106/// # Examples
107///
108/// ```
109/// use graph_core::{WeightedEdge, NodeId};
110///
111/// let e = WeightedEdge::new(NodeId::new(0), NodeId::new(2), 1.5);
112/// assert_eq!(e.weight, 1.5);
113/// ```
114pub type WeightedEdge = Edge<f64>;
115
116/// An unweighted directed edge (weight type `()`).
117///
118/// # Examples
119///
120/// ```
121/// use graph_core::{UnweightedEdge, NodeId};
122///
123/// let e = UnweightedEdge::new(NodeId::new(0), NodeId::new(1), ());
124/// assert_eq!(e.source, NodeId::new(0));
125/// ```
126pub type UnweightedEdge = Edge<()>;