use std::fmt;
use crate::network::NodeID;
#[derive(Clone)]
pub struct Packet {
id: usize,
path: PacketPath,
path_idx: usize,
injection_rd: usize,
}
impl Packet {
pub fn increment_path_idx(&mut self) {
if self.is_absorbed() {
panic!("Packet has already been absorbed.");
}
self.path_idx += 1;
}
pub fn decrement_path_idx(&mut self) {
if self.path_idx == 0 {
panic!("Packet is already at the beginning of its path.");
}
self.path_idx -= 1;
}
pub fn is_absorbed(&self) -> bool {
self.path_idx == self.path.len()
}
pub fn should_be_absorbed(&self) -> bool {
self.path_idx == self.path.len()-1
}
pub fn get_injection_rd(&self) -> usize {
self.injection_rd
}
pub fn cur_node(&self) -> Option<NodeID> {
match self.path.get(self.path_idx) {
Some(next_id) => Some(*next_id),
None => None,
}
}
pub fn next_node(&self) -> Option<NodeID> {
match self.path.get(self.path_idx + 1) {
Some(next_id) => Some(*next_id),
None => None,
}
}
pub fn dist_to_go(&self) -> usize {
self.path.len() - self.path_idx + 1
}
pub fn get_path_idx(&self) -> usize {
self.path_idx
}
pub fn get_path(&self) -> &PacketPath {
&self.path
}
pub fn get_path_mut(&mut self) -> &mut PacketPath {
&mut self.path
}
}
impl fmt::Debug for Packet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Packet")
.field("id", &self.id)
.field("cur_node", &self.cur_node())
.field("injection_rd", &self.injection_rd)
.finish()
}
}
impl PartialEq for Packet {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
pub struct PacketFactory {
cur_id: usize,
}
impl PacketFactory {
pub fn new() -> Self {
PacketFactory { cur_id: 0 }
}
pub fn create_packet(
&mut self,
path: PacketPath,
injection_rd: usize,
path_idx: usize,
) -> Packet {
let p = Packet {id: self.cur_id, path, path_idx, injection_rd };
self.cur_id += 1;
p
}
}
pub type PacketPath = Vec<NodeID>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_iter_through_path() {
let mut packet_factory = PacketFactory::new();
let mut p = packet_factory.create_packet(vec![1, 4, 9, 16], 0, 0);
assert_eq!(p.get_path_idx(), 0);
assert_eq!(p.cur_node().unwrap(), 1);
assert_eq!(p.next_node().unwrap(), 4);
assert_eq!(p.dist_to_go(), 4);
p.increment_path_idx();
assert_eq!(p.get_path_idx(), 1);
assert_eq!(p.cur_node().unwrap(), 4);
assert_eq!(p.next_node().unwrap(), 9);
assert_eq!(p.dist_to_go(), 3);
p.increment_path_idx();
p.increment_path_idx();
assert_eq!(p.dist_to_go(), 1);
assert_eq!(p.next_node(), None);
p.increment_path_idx();
assert_eq!(p.dist_to_go(), 0);
assert_eq!(p.cur_node(), None);
assert_eq!(p.next_node(), None);
assert!(p.is_absorbed());
p.increment_path_idx();
}
}