prepona/graph/edge/
flow_edge.rs1use magnitude::Magnitude;
2
3use crate::graph::edge::Edge;
4
5#[derive(Debug, Copy, Clone)]
7pub struct FlowEdge<W> {
8 id: usize,
9 weight: Magnitude<W>,
10 capacity: usize,
11 flow: isize,
12}
13
14impl<W> FlowEdge<W> {
15 pub fn init_with(weight: Magnitude<W>, capacity: usize, flow: isize) -> Self {
26 if flow > capacity as isize {
27 panic!(
28 "Flow of the edge can not be greater than the capacity: {} > {}",
29 flow, capacity
30 );
31 }
32
33 FlowEdge {
34 id: 0,
35 weight,
36 capacity,
37 flow,
38 }
39 }
40
41 pub fn get_flow(&self) -> isize {
44 self.flow
45 }
46
47 pub fn get_capacity(&self) -> usize {
50 self.capacity
51 }
52
53 pub fn set_flow(&mut self, flow: isize) {
59 if flow > self.get_capacity() as isize {
60 panic!("Flow of the edge can not be greater than the current capacity of the edge: {} > {}", flow, self.get_capacity());
61 }
62
63 self.flow = flow;
64 }
65
66 pub fn set_capacity(&mut self, capacity: usize) {
72 if (capacity as isize) < self.get_flow() {
73 panic!("Capacity of the edge can not be smaller than the current flow of the edge: {} < {}", capacity, self.get_flow());
74 }
75 self.capacity = capacity
76 }
77}
78
79impl<W> Edge<W> for FlowEdge<W> {
81 fn init(weight: Magnitude<W>) -> Self {
82 FlowEdge::init_with(weight, 0, 0)
83 }
84
85 fn get_weight(&self) -> &Magnitude<W> {
86 &self.weight
87 }
88
89 fn set_weight(&mut self, weight: Magnitude<W>) {
90 self.weight = weight
91 }
92
93 fn set_id(&mut self, id: usize) {
94 self.id = id
95 }
96
97 fn get_id(&self) -> usize {
98 self.id
99 }
100}
101
102use std::any::Any;
103use std::convert::{From, TryFrom};
104impl<W: Any> From<W> for FlowEdge<W> {
105 fn from(weight: W) -> Self {
107 FlowEdge::init(weight.into())
108 }
109}
110
111impl<W: Any> TryFrom<(W, usize, isize)> for FlowEdge<W> {
112 type Error = String;
113
114 fn try_from((weight, capacity, flow): (W, usize, isize)) -> Result<Self, Self::Error> {
118 if flow > capacity as isize {
119 Err(format!(
120 "Flow of the edge can not be greater than the capacity: {} > {}",
121 flow, capacity
122 ))
123 } else {
124 Ok(FlowEdge::init_with(weight.into(), capacity, flow))
125 }
126 }
127}
128
129impl<W: PartialEq> PartialEq for FlowEdge<W> {
130 fn eq(&self, other: &Self) -> bool {
131 self.weight == other.weight
132 && self.id == other.id
133 && self.flow == other.flow
134 && self.capacity == other.capacity
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141 use std::convert::TryInto;
142
143 #[test]
144 fn init() {
145 let edge = FlowEdge::init(2.into());
146
147 assert_eq!(edge.get_weight(), &2.into());
148 assert_eq!(edge.get_capacity(), 0);
149 assert_eq!(edge.get_flow(), 0);
150 }
151
152 #[test]
153 fn init_with() {
154 let edge = FlowEdge::init_with(2.into(), 4, 3);
155
156 assert_eq!(edge.get_weight(), &2.into());
157 assert_eq!(edge.get_capacity(), 4);
158 assert_eq!(edge.get_flow(), 3);
159 }
160
161 #[test]
162 fn set_weight() {
163 let mut edge = FlowEdge::init(2.into());
164
165 edge.set_weight(3.into());
166
167 assert_eq!(edge.get_weight(), &3.into());
168 }
169
170 #[test]
171 fn set_capacity() {
172 let mut edge = FlowEdge::init(2.into());
173
174 edge.set_capacity(5);
175
176 assert_eq!(edge.get_capacity(), 5);
177 }
178
179 #[test]
180 fn set_flow() {
181 let mut edge = FlowEdge::init(2.into());
182 edge.set_capacity(5);
183
184 edge.set_flow(4);
185
186 assert_eq!(edge.get_flow(), 4);
187 }
188
189 #[test]
190 fn from_triplet() {
191 let edge: FlowEdge<usize> = 2.into();
192
193 assert_eq!(edge.get_weight(), &2.into());
194 assert_eq!(edge.get_capacity(), 0);
195 assert_eq!(edge.get_flow(), 0);
196 }
197
198 #[test]
199 fn from_quintuplet() {
200 let edge: FlowEdge<usize> = (2, 4, 3).try_into().unwrap();
201
202 assert_eq!(edge.get_weight(), &2.into());
203 assert_eq!(edge.get_capacity(), 4);
204 assert_eq!(edge.get_flow(), 3);
205 }
206
207 #[test]
208 #[should_panic(expected = "Flow of the edge can not be greater than the capacity: 4 > 3")]
209 fn init_with_flow_larger_than_capacity() {
210 let _ = FlowEdge::init_with(2.into(), 3, 4);
211 }
212
213 #[test]
214 #[should_panic(
215 expected = "Flow of the edge can not be greater than the current capacity of the edge: 4 > 0"
216 )]
217 fn set_flow_larger_than_capacity() {
218 let mut edge = FlowEdge::init(2.into());
219
220 edge.set_flow(4);
221 }
222
223 #[test]
224 #[should_panic(
225 expected = "Capacity of the edge can not be smaller than the current flow of the edge: 0 < 4"
226 )]
227 fn set_capacity_smaller_than_flow() {
228 let mut edge = FlowEdge::init_with(2.into(), 5, 4);
229
230 edge.set_capacity(0);
231 }
232
233 #[test]
234 fn from_quintuplet_with_flow_larger_than_capacity() {
235 let edge_res: Result<FlowEdge<usize>, String> = (2, 0, 4).try_into();
236
237 assert!(edge_res.is_err());
238 assert_eq!(
239 edge_res.unwrap_err(),
240 "Flow of the edge can not be greater than the capacity: 4 > 0".to_string()
241 )
242 }
243}