unobtanium_graph_algorithms/graph/
branded.rs1use core::hash::Hash;
6use std::marker::PhantomData;
7use std::ops::Deref;
8
9use crate::graph::Graph;
10use crate::node::NodeId;
11
12#[derive(Default, Clone, Copy)]
13struct InvariantLifetime<'id>(PhantomData<*mut &'id ()>);
14
15pub struct MutableGraph<'id, T: Eq + Hash + Clone> {
20 graph: &'id mut Graph<T>,
21 _marker: InvariantLifetime<'id>,
22}
23
24#[derive(Clone, Copy)]
33pub struct BrandedNodeId<'id> {
34 inner: NodeId,
35 _marker: InvariantLifetime<'id>,
36}
37
38impl PartialEq for BrandedNodeId<'_> {
39 fn eq(&self, other: &Self) -> bool {
40 self.inner == other.inner
41 }
42}
43
44impl Eq for BrandedNodeId<'_> { }
45
46impl Hash for BrandedNodeId<'_> {
47 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
48 self.inner.hash(state);
49 }
50}
51
52impl PartialOrd for BrandedNodeId<'_> {
53 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
54 Some(self.cmp(other))
55 }
56}
57
58impl Ord for BrandedNodeId<'_> {
59 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
60 self.inner.cmp(&other.inner)
61 }
62}
63
64impl<'id, T: Eq + Hash + Clone> MutableGraph<'id, T> {
65
66 #[allow(clippy::new_ret_no_self)]
70 pub fn new<F, R>(graph: &'id mut Graph<T>, callback: F) -> R
71 where
72 for<'new_id> F: FnOnce(MutableGraph<'new_id, T>) -> R,
73 {
74 callback(Self {
75 graph,
76 _marker: Default::default(),
77 })
78 }
79
80 pub fn fetch_id_for_data(&mut self, data: &T) -> BrandedNodeId<'id> {
86 BrandedNodeId {
87 inner: self.graph.fetch_id_for_data(data),
88 _marker: Default::default(),
89 }
90 }
91
92 pub fn get_node_data_for_id(&self, id: BrandedNodeId<'id>) -> Option<&T> {
94 self.graph.get_node_data_for_id(id.inner)
95 }
96
97 #[inline(always)]
99 pub fn add_edge(&mut self, from: BrandedNodeId<'id>, to: BrandedNodeId<'id>) {
100 self.add_edge_weighted(from, to, 1.0);
101 }
102
103 #[inline(always)]
105 pub fn add_edge_weighted(
106 &mut self,
107 from: BrandedNodeId<'id>,
108 to: BrandedNodeId<'id>,
109 weight: f32,
110 ) {
111 self.graph.add_edge_weighted(from.inner, to.inner, weight);
112 }
113}
114
115impl<'id, T: Eq + Hash + Clone> Deref for MutableGraph<'id, T> {
116 type Target = Graph<T>;
117
118 fn deref(&self) -> &Self::Target {
119 self.graph
120 }
121}