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<()>;