1 /// Describing the range of reconstructed data. 2 #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Ord, PartialOrd)] 3 pub struct IpFragRange { 4 /// Offset of section 5 pub start: u16, 6 /// Offset + length of section 7 pub end: u16, 8 } 9 10 impl IpFragRange { 11 /// Return if the value is contained within the section. is_value_connected(&self, value: u16) -> bool12 fn is_value_connected(&self, value: u16) -> bool { 13 self.start <= value && self.end >= value 14 } 15 16 /// Combine both sections if possible. merge(&self, other: IpFragRange) -> Option<IpFragRange>17 pub fn merge(&self, other: IpFragRange) -> Option<IpFragRange> { 18 if self.is_value_connected(other.start) 19 || self.is_value_connected(other.end) 20 || other.is_value_connected(self.start) 21 || other.is_value_connected(self.end) 22 { 23 Some(IpFragRange { 24 start: core::cmp::min(self.start, other.start), 25 end: core::cmp::max(self.end, other.end), 26 }) 27 } else { 28 None 29 } 30 } 31 } 32 33 #[cfg(test)] 34 mod test { 35 use super::*; 36 use alloc::format; 37 38 #[test] debug_clone_eq()39 fn debug_clone_eq() { 40 let section = IpFragRange { start: 1, end: 2 }; 41 let _ = format!("{:?}", section); 42 assert_eq!(section, section.clone()); 43 assert_eq!(section.cmp(§ion), core::cmp::Ordering::Equal); 44 assert_eq!( 45 section.partial_cmp(§ion), 46 Some(core::cmp::Ordering::Equal) 47 ); 48 49 use core::hash::{Hash, Hasher}; 50 use std::collections::hash_map::DefaultHasher; 51 let h1 = { 52 let mut h = DefaultHasher::new(); 53 section.hash(&mut h); 54 h.finish() 55 }; 56 let h2 = { 57 let mut h = DefaultHasher::new(); 58 section.clone().hash(&mut h); 59 h.finish() 60 }; 61 assert_eq!(h1, h2); 62 } 63 64 #[test] is_value_connected()65 fn is_value_connected() { 66 let s = IpFragRange { start: 5, end: 9 }; 67 assert_eq!(false, s.is_value_connected(3)); 68 assert_eq!(false, s.is_value_connected(4)); 69 assert!(s.is_value_connected(5)); 70 assert!(s.is_value_connected(6)); 71 assert!(s.is_value_connected(7)); 72 assert!(s.is_value_connected(8)); 73 assert!(s.is_value_connected(9)); 74 assert_eq!(false, s.is_value_connected(10)); 75 assert_eq!(false, s.is_value_connected(11)); 76 } 77 78 #[test] merge()79 fn merge() { 80 let tests = [ 81 ((0, 1), (1, 2), Some((0, 2))), 82 ((0, 1), (2, 3), None), 83 ((3, 7), (1, 2), None), 84 ((3, 7), (1, 3), Some((1, 7))), 85 ((3, 7), (1, 4), Some((1, 7))), 86 ((3, 7), (1, 5), Some((1, 7))), 87 ((3, 7), (1, 6), Some((1, 7))), 88 ((3, 7), (1, 7), Some((1, 7))), 89 ((3, 7), (1, 8), Some((1, 8))), 90 ]; 91 for t in tests { 92 let a = IpFragRange { 93 start: t.0 .0, 94 end: t.0 .1, 95 }; 96 let b = IpFragRange { 97 start: t.1 .0, 98 end: t.1 .1, 99 }; 100 let expected = t.2.map(|v| IpFragRange { 101 start: v.0, 102 end: v.1, 103 }); 104 assert_eq!(a.merge(b), expected); 105 assert_eq!(b.merge(a), expected); 106 } 107 } 108 } 109