1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use std::fmt; #[derive(Clone, Copy, Debug)] pub struct ChunkHeader { offset: u64, header_size: u16, chunk_size: u32, chunk_type: u16, } impl ChunkHeader { pub fn new(offset: u64, header_size: u16, chunk_size: u32, chunk_type: u16) -> Self { Self { offset, header_size, chunk_size, chunk_type, } } pub fn get_offset(&self) -> u64 { self.offset } pub fn get_header_size(&self) -> u16 { self.header_size } pub fn get_data_offset(&self) -> u64 { self.offset + u64::from(self.header_size) } pub fn get_chunk_end(&self) -> u64 { self.offset + u64::from(self.chunk_size) } pub fn absolute(&self, relative: u64) -> u64 { let absolute = self.offset + relative; if absolute > self.get_chunk_end() { panic!("Requested a relative value out of bounds"); } absolute } pub fn get_token(&self) -> u16 { self.chunk_type } } impl fmt::Display for ChunkHeader { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "(Token:{:X}; Start: {}; Data: {}; End {})", self.chunk_type, self.offset, self.get_data_offset(), self.get_chunk_end() ) } } #[cfg(test)] mod tests { use super::ChunkHeader; #[test] pub fn it_returns_data_offset() { let chunk = ChunkHeader::new(4000, 8, 16, 0); assert_eq!(4008, chunk.get_data_offset()); } #[test] pub fn it_returns_chunk_end() { let chunk = ChunkHeader::new(4000, 8, 16, 0); assert_eq!(4016, chunk.get_chunk_end()); } #[test] #[should_panic] pub fn it_panics_from_relative_out_of_bound() { let chunk = ChunkHeader::new(4000, 8, 500, 0); chunk.absolute(510); } #[test] pub fn it_returns_absolute_offsets_from_relative_ones() { let chunk = ChunkHeader::new(4000, 8, 500, 0); let res = chunk.absolute(490); assert_eq!(4490, res); } }