dijkstra_suite/node.rs
1//! This modules defines types and traits for a graph node
2//!
3//! ## The`Node` type
4//!
5//! `Node` type plays a central role in this suite.
6//!
7//! Each `Node` has an id and a weight, both generic over types implementing `NodeId`
8//! and `NodeWeight` traits respectively. Both have blanket implementations over generic types
9//! so you can use any types you want as long as it implements the required traits
10//!
11//! ```rust
12//! use dijkstra_suite::node::Node;
13//!
14//! let node_a: Node<(i32, i32), f64> = Node {
15//! weight: 1.0,
16//! ..Default::default()
17//! };
18//!
19//! let node_b = Node {
20//! id: (0, 0),
21//! weight: 1.0,
22//! neighbours: vec![],
23//! };
24//!
25//! let node_c: Node<(i32, i32), f32> = Node::default();
26//!
27//! assert_eq!(node_a, node_b);
28//! assert_eq!(node_c.weight, 0.0)
29//! ```
30//!
31//! ## The`NodeId` trait
32//!
33//! `Nodeid` is a super trait that ensures the id of the node is comparable and hashable
34//! (current implementation uses an `HashMap` under the hood), requiring the implementing
35//! type also to implement `Hash`, `Eq` and `Default`
36//!
37//!
38//! ## The`NodeWeight` trait
39//!
40//! `NodeWeight` is a super trait that ensures the weight of the node is a number or number-like
41//! types, requiring the implementing type also to implement `Add`, `Div`, `Mul`, `Rem`, `Sub`
42//! and `PartialEq`
43
44use std::{
45 fmt::Debug,
46 hash::Hash,
47 ops::{Add, Deref, Div, Mul, Rem, Sub},
48};
49
50#[derive(Debug, Clone)]
51pub struct Node<I: NodeId, W: NodeWeight> {
52 pub id: I,
53 pub weight: W,
54 pub neighbours: Vec<NodeConnection<I, W>>,
55}
56
57impl<I: NodeId, W: NodeWeight> Default for Node<I, W> {
58 fn default() -> Self {
59 Node {
60 id: I::default(),
61 weight: W::default(),
62 neighbours: vec![],
63 }
64 }
65}
66
67impl<I: NodeId, W: NodeWeight> PartialEq for Node<I, W> {
68 fn eq(&self, other: &Self) -> bool {
69 self.id == other.id && self.weight == other.weight && self.neighbours == other.neighbours
70 }
71}
72
73pub trait NodeId: Debug + Default + Clone + Eq + PartialOrd + Hash {}
74
75impl<T> NodeId for T where T: Debug + Default + Clone + Eq + PartialOrd + Hash {}
76
77pub trait NodeWeight:
78 Debug
79 + Default
80 + Clone
81 + PartialEq
82 + PartialOrd
83 + Add<Output = Self>
84 + Sub<Output = Self>
85 + Mul<Output = Self>
86 + Div<Output = Self>
87 + Rem<Output = Self>
88{
89}
90
91impl<T> NodeWeight for T where
92 T: Debug
93 + Default
94 + Clone
95 + PartialEq
96 + PartialOrd
97 + Add<Output = T>
98 + Sub<Output = T>
99 + Mul<Output = T>
100 + Div<Output = T>
101 + Rem<Output = T>
102{
103}
104
105// #[derive(Debug, Default, Clone, PartialEq)]
106// pub struct Weight<T: NodeWeight>(pub T);
107//
108// impl<T: NodeWeight> Eq for Weight<T> {}
109//
110// impl<T: NodeWeight> Ord for Weight<T> {
111// fn cmp(&self, other: &Self) -> std::cmp::Ordering {
112// self.0
113// .partial_cmp(&other.0)
114// .expect("Weight contains a value with no defined order (e.g. NaN)")
115// }
116// }
117//
118// impl<T: NodeWeight> PartialOrd for Weight<T> {
119// fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
120// Some(self.cmp(other))
121// }
122// }
123//
124// impl<T> Deref for Weight<T>
125// where
126// T: Debug
127// + Default
128// + Clone
129// + PartialEq
130// + PartialOrd
131// + Ord
132// + Add<Output = T>
133// + Sub<Output = T>
134// + Mul<Output = T>
135// + Div<Output = T>
136// + Rem<Output = T>,
137// {
138// type Target = T;
139//
140// fn deref(&self) -> &Self::Target {
141// &self.0
142// }
143// }
144//
145// impl<T: NodeWeight> Add for Weight<T> {
146// type Output = Weight<T>;
147//
148// fn add(self, rhs: Self) -> Self::Output {
149// Weight(self.0 + rhs.0)
150// }
151// }
152//
153// impl<T: NodeWeight> Sub for Weight<T> {
154// type Output = Weight<T>;
155//
156// fn sub(self, rhs: Self) -> Self::Output {
157// Weight(self.0 - rhs.0)
158// }
159// }
160//
161// impl<T: NodeWeight> Mul for Weight<T> {
162// type Output = Weight<T>;
163//
164// fn mul(self, rhs: Self) -> Self::Output {
165// Weight(self.0 * rhs.0)
166// }
167// }
168//
169// impl<T: NodeWeight> Div for Weight<T> {
170// type Output = Weight<T>;
171//
172// fn div(self, rhs: Self) -> Self::Output {
173// Weight(self.0 / rhs.0)
174// }
175// }
176//
177// impl<T: NodeWeight> Rem for Weight<T> {
178// type Output = Weight<T>;
179//
180// fn rem(self, rhs: Self) -> Self::Output {
181// Weight(self.0 % rhs.0)
182// }
183// }
184
185#[derive(Debug, Clone)]
186pub struct NodeConnection<I: NodeId, W: NodeWeight> {
187 pub from: I,
188 pub to: I,
189 pub weight: W,
190}
191
192impl<I: NodeId, W: NodeWeight> Default for NodeConnection<I, W> {
193 fn default() -> Self {
194 NodeConnection {
195 from: I::default(),
196 to: I::default(),
197 weight: W::default(),
198 }
199 }
200}
201
202impl<I: NodeId, W: NodeWeight> AsRef<NodeConnection<I, W>> for NodeConnection<I, W> {
203 fn as_ref(&self) -> &NodeConnection<I, W> {
204 self
205 }
206}
207
208impl<I: NodeId, W: NodeWeight> PartialEq for NodeConnection<I, W> {
209 fn eq(&self, other: &Self) -> bool {
210 self.from == other.from && self.to == other.to && self.weight == other.weight
211 }
212}
213
214impl<I: NodeId, W: NodeWeight> Eq for NodeConnection<I, W> {}
215
216impl<I: NodeId, W: NodeWeight> Ord for NodeConnection<I, W> {
217 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
218 self.weight.partial_cmp(&other.weight).expect("bla")
219 }
220}
221
222impl<I: NodeId, W: NodeWeight> PartialOrd for NodeConnection<I, W> {
223 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
224 Some(self.cmp(other))
225 }
226}
227
228#[cfg(test)]
229mod test {
230 use super::*;
231
232 #[test]
233 fn test_node() {
234 let node_a = Node {
235 weight: 1,
236 ..Default::default()
237 };
238
239 let node_b = Node {
240 id: (0, 0),
241 weight: 1,
242 neighbours: vec![],
243 };
244
245 let node_c: Node<(i32, i32), i32> = Node::default();
246
247 assert_eq!(node_a, node_b);
248 assert_eq!(node_c.weight, 0)
249 }
250
251 #[test]
252 fn test_node_float() {
253 let node_a: Node<(i32, i32), f64> = Node {
254 weight: 1.0,
255 ..Default::default()
256 };
257
258 let node_b = Node {
259 id: (0, 0),
260 weight: 1.0,
261 neighbours: vec![],
262 };
263
264 let node_c: Node<(i32, i32), f32> = Node::default();
265
266 assert_eq!(node_a, node_b);
267 assert_eq!(node_c.weight, 0.0)
268 }
269}