1use crate::data;
2
3pub(crate) const N32_SIZE: usize = std::mem::size_of::<u32>();
4
5pub fn decode(data: &[u8; 12]) -> Result<(data::Version, u32), decode::Error> {
7 let mut ofs = 0;
8 if &data[ofs..ofs + b"PACK".len()] != b"PACK" {
9 return Err(decode::Error::Corrupt("Pack data type not recognized".into()));
10 }
11 ofs += N32_SIZE;
12 let kind = match crate::read_u32(&data[ofs..ofs + N32_SIZE]) {
13 2 => data::Version::V2,
14 3 => data::Version::V3,
15 v => return Err(decode::Error::UnsupportedVersion(v)),
16 };
17 ofs += N32_SIZE;
18 let num_objects = crate::read_u32(&data[ofs..ofs + N32_SIZE]);
19
20 Ok((kind, num_objects))
21}
22
23pub fn encode(version: data::Version, num_objects: u32) -> [u8; 12] {
25 use crate::data::Version::*;
26 let mut buf = [0u8; 12];
27 buf[..4].copy_from_slice(b"PACK");
28 buf[4..8].copy_from_slice(
29 &match version {
30 V2 => 2u32,
31 V3 => 3,
32 }
33 .to_be_bytes()[..],
34 );
35 buf[8..].copy_from_slice(&num_objects.to_be_bytes()[..]);
36 buf
37}
38
39pub mod decode {
41 #[derive(thiserror::Error, Debug)]
43 #[allow(missing_docs)]
44 pub enum Error {
45 #[error("Could not open pack file at '{path}'")]
46 Io {
47 source: std::io::Error,
48 path: std::path::PathBuf,
49 },
50 #[error("{0}")]
51 Corrupt(String),
52 #[error("Unsupported pack version: {0}")]
53 UnsupportedVersion(u32),
54 }
55}