1use std::fmt;
6use crate::network::NodeID;
7
8
9#[derive(Clone)]
18pub struct Packet {
19 id: usize,
20 path: PacketPath,
21 path_idx: usize,
22 injection_rd: usize,
23}
24
25impl Packet {
26 pub fn increment_path_idx(&mut self) {
29 if self.is_absorbed() {
30 panic!("Packet has already been absorbed.");
31 }
32 self.path_idx += 1;
33 }
34
35 pub fn decrement_path_idx(&mut self) {
38 if self.path_idx == 0 {
39 panic!("Packet is already at the beginning of its path.");
40 }
41 self.path_idx -= 1;
42 }
43
44 pub fn is_absorbed(&self) -> bool {
46 self.path_idx == self.path.len()
47 }
48
49 pub fn should_be_absorbed(&self) -> bool {
51 self.path_idx == self.path.len()-1
52 }
53
54 pub fn get_injection_rd(&self) -> usize {
55 self.injection_rd
56 }
57
58 pub fn cur_node(&self) -> Option<NodeID> {
61 match self.path.get(self.path_idx) {
62 Some(next_id) => Some(*next_id),
63 None => None,
64 }
65 }
66
67 pub fn next_node(&self) -> Option<NodeID> {
70 match self.path.get(self.path_idx + 1) {
71 Some(next_id) => Some(*next_id),
72 None => None,
73 }
74 }
75
76 pub fn dist_to_go(&self) -> usize {
79 self.path.len() - self.path_idx + 1
80 }
81
82 pub fn get_path_idx(&self) -> usize {
84 self.path_idx
85 }
86
87 pub fn get_path(&self) -> &PacketPath {
89 &self.path
90 }
91
92 pub fn get_path_mut(&mut self) -> &mut PacketPath {
94 &mut self.path
95 }
96}
97
98impl fmt::Debug for Packet {
99 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100 f.debug_struct("Packet")
101 .field("id", &self.id)
102 .field("cur_node", &self.cur_node())
103 .field("injection_rd", &self.injection_rd)
104 .finish()
105 }
106}
107
108impl PartialEq for Packet {
109 fn eq(&self, other: &Self) -> bool {
110 self.id == other.id
111 }
112}
113
114
115pub struct PacketFactory {
118 cur_id: usize,
119}
120
121impl PacketFactory {
122 pub fn new() -> Self {
124 PacketFactory { cur_id: 0 }
125 }
126
127 pub fn create_packet(
129 &mut self,
130 path: PacketPath,
131 injection_rd: usize,
132 path_idx: usize,
133 ) -> Packet {
134 let p = Packet {id: self.cur_id, path, path_idx, injection_rd };
135 self.cur_id += 1;
136 p
137 }
138}
139
140
141pub type PacketPath = Vec<NodeID>;
143
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148
149 #[test]
150 #[should_panic]
151 fn test_iter_through_path() {
152 let mut packet_factory = PacketFactory::new();
153 let mut p = packet_factory.create_packet(vec![1, 4, 9, 16], 0, 0);
154 assert_eq!(p.get_path_idx(), 0);
155 assert_eq!(p.cur_node().unwrap(), 1);
156 assert_eq!(p.next_node().unwrap(), 4);
157 assert_eq!(p.dist_to_go(), 4);
158
159 p.increment_path_idx();
160
161 assert_eq!(p.get_path_idx(), 1);
162 assert_eq!(p.cur_node().unwrap(), 4);
163 assert_eq!(p.next_node().unwrap(), 9);
164 assert_eq!(p.dist_to_go(), 3);
165
166 p.increment_path_idx();
167 p.increment_path_idx();
168
169 assert_eq!(p.dist_to_go(), 1);
170 assert_eq!(p.next_node(), None);
171 p.increment_path_idx();
172 assert_eq!(p.dist_to_go(), 0);
173 assert_eq!(p.cur_node(), None);
174 assert_eq!(p.next_node(), None);
175 assert!(p.is_absorbed());
176
177 p.increment_path_idx();
179 }
180
181}