#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PacketField {
pub start_bit: u32,
pub end_bit: u32,
pub label: String,
}
impl PacketField {
pub fn bit_width(&self) -> u32 {
self.end_bit - self.start_bit + 1
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Packet {
pub title: Option<String>,
pub fields: Vec<PacketField>,
}
impl Packet {
pub fn total_bits(&self) -> u32 {
self.fields.iter().map(|f| f.end_bit + 1).max().unwrap_or(0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn packet_field_bit_width_single() {
let f = PacketField {
start_bit: 5,
end_bit: 5,
label: "FLAG".to_string(),
};
assert_eq!(f.bit_width(), 1);
}
#[test]
fn packet_field_bit_width_range() {
let f = PacketField {
start_bit: 0,
end_bit: 15,
label: "Source Port".to_string(),
};
assert_eq!(f.bit_width(), 16);
}
#[test]
fn packet_total_bits_empty() {
let p = Packet {
title: None,
fields: vec![],
};
assert_eq!(p.total_bits(), 0);
}
#[test]
fn packet_total_bits_multiple_fields() {
let p = Packet {
title: Some("TCP".to_string()),
fields: vec![
PacketField {
start_bit: 0,
end_bit: 15,
label: "Source Port".to_string(),
},
PacketField {
start_bit: 16,
end_bit: 31,
label: "Dest Port".to_string(),
},
],
};
assert_eq!(p.total_bits(), 32);
}
#[test]
fn packet_equality_and_clone() {
let a = Packet {
title: Some("IP".to_string()),
fields: vec![PacketField {
start_bit: 0,
end_bit: 3,
label: "Version".to_string(),
}],
};
let b = a.clone();
assert_eq!(a, b);
let c = Packet {
title: None,
fields: vec![],
};
assert_ne!(a, c);
}
}