1use crate::{DefaultIx, EdgeIndex, NodeIndex};
7use core::marker::PhantomData;
8
9pub trait GraphEntry {
10 type Idx;
11 type Weight;
12}
13
14pub trait ComputeGraph {
15 type Edge: GraphEntry;
16 type Node: GraphEntry;
17
18 fn add_node(
19 &mut self,
20 node: <Self::Node as GraphEntry>::Weight,
21 ) -> <Self::Node as GraphEntry>::Idx;
22
23 fn add_edge(
24 &mut self,
25 src: <Self::Node as GraphEntry>::Idx,
26 target: <Self::Node as GraphEntry>::Idx,
27 weight: <Self::Edge as GraphEntry>::Weight,
28 ) -> <Self::Edge as GraphEntry>::Idx;
29
30 fn clear(&mut self);
31}
32
33pub struct Edge<Idx = DefaultIx, W = ()> {
34 pub link: Link<Idx>,
35 pub weight: Option<W>,
36 _idx: PhantomData<EdgeIndex<Idx>>,
37}
38
39impl<Idx, W> Edge<Idx, W> {
40 pub fn new(src: NodeIndex<Idx>, target: NodeIndex<Idx>, weight: Option<W>) -> Self {
41 Self {
42 link: Link::new(src, target),
43 weight,
44 _idx: PhantomData,
45 }
46 }
47
48 pub fn from_link(link: Link<Idx>) -> Self {
49 Self {
50 link,
51 weight: None,
52 _idx: PhantomData,
53 }
54 }
55
56 pub fn unweighted(src: NodeIndex<Idx>, target: NodeIndex<Idx>) -> Self {
57 Self::new(src, target, None)
58 }
59
60 pub fn weighted(src: NodeIndex<Idx>, target: NodeIndex<Idx>, weight: W) -> Self {
61 Self::new(src, target, Some(weight))
62 }
63
64 pub fn with_weight(self, weight: W) -> Self {
65 Self {
66 weight: Some(weight),
67 ..self
68 }
69 }
70
71 pub fn is_unweighted(&self) -> bool {
72 self.weight.is_none()
73 }
74
75 pub fn is_weighted(&self) -> bool {
76 self.weight.is_some()
77 }
78
79 pub fn weight(&self) -> Option<&W> {
80 self.weight.as_ref()
81 }
82
83 pub fn weight_mut(&mut self) -> Option<&mut W> {
84 self.weight.as_mut()
85 }
86}
87
88impl<Idx, W> GraphEntry for Edge<Idx, W> {
89 type Idx = EdgeIndex<Idx>;
90 type Weight = W;
91}
92
93pub struct Link<Idx = DefaultIx> {
94 pub src: NodeIndex<Idx>,
95 pub target: NodeIndex<Idx>,
96}
97
98impl<Idx> Link<Idx> {
99 pub fn new(src: NodeIndex<Idx>, target: NodeIndex<Idx>) -> Self {
100 Self { src, target }
101 }
102}
103
104pub trait GraphEdge {
105 type Idx;
106
107 fn src(&self) -> NodeIndex<Self::Idx>;
108
109 fn target(&self) -> NodeIndex<Self::Idx>;
110}
111
112impl<Idx> GraphEdge for Link<Idx>
113where
114 Idx: Copy,
115{
116 type Idx = Idx;
117
118 fn src(&self) -> NodeIndex<Idx> {
119 self.src
120 }
121
122 fn target(&self) -> NodeIndex<Idx> {
123 self.target
124 }
125}
126
127impl<Idx, W> GraphEdge for Edge<Idx, W>
128where
129 Idx: Copy,
130{
131 type Idx = Idx;
132
133 fn src(&self) -> NodeIndex<Idx> {
134 self.link.src
135 }
136
137 fn target(&self) -> NodeIndex<Idx> {
138 self.link.target
139 }
140}