1use crate::{Identifier, Result};
2use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
3use std::{
4 fmt::Debug,
5 io::{Read, Write},
6};
7
8#[repr(C, align(16))]
10#[derive(Copy, Clone, PartialEq, Hash)]
11pub struct Chunk {
12 identifier: Identifier,
14 length: u64,
16 offset: u64,
18}
19
20impl Debug for Chunk {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 write!(
23 f,
24 "({:X}) - {}, {}",
25 *self.identifier, self.length, self.offset
26 )
27 }
28}
29
30impl Chunk {
31 pub const SIZE: usize = std::mem::size_of::<Self>();
33
34 pub fn new(identifier: impl Into<Identifier>, length: u64, offset: u64) -> Self {
36 Self {
37 identifier: identifier.into(),
38 length,
39 offset,
40 }
41 }
42
43 pub fn identifier(&self) -> Identifier {
45 self.identifier
46 }
47
48 pub fn length(&self) -> u64 {
50 self.length
51 }
52
53 pub fn length_mut(&mut self) -> &mut u64 {
55 &mut self.length
56 }
57
58 pub fn offset(&self) -> u64 {
60 self.offset
61 }
62
63 pub fn offset_mut(&mut self) -> &mut u64 {
65 &mut self.offset
66 }
67
68 pub fn read<E: ByteOrder>(reader: &mut dyn Read) -> Result<Self> {
70 Ok(Self {
71 identifier: reader.read_u128::<E>()?.try_into()?,
72 length: reader.read_u64::<E>()?,
73 offset: reader.read_u64::<E>()?,
74 })
75 }
76
77 pub fn write<E: ByteOrder>(self, writer: &mut dyn Write) -> Result<()> {
79 writer.write_u128::<E>(*self.identifier)?;
80 writer.write_u64::<E>(self.length)?;
81 writer.write_u64::<E>(self.offset)?;
82
83 Ok(())
84 }
85}