gix_pack/data/file/
init.rs1use std::path::Path;
2
3use crate::data;
4
5impl data::File {
7 pub fn at(path: impl AsRef<Path>, object_hash: gix_hash::Kind) -> Result<data::File, data::header::decode::Error> {
12 Self::at_inner(path.as_ref(), object_hash)
13 }
14
15 fn at_inner(path: &Path, object_hash: gix_hash::Kind) -> Result<data::File, data::header::decode::Error> {
16 use crate::data::header::N32_SIZE;
17 let hash_len = object_hash.len_in_bytes();
18
19 let data = crate::mmap::read_only(path).map_err(|e| data::header::decode::Error::Io {
20 source: e,
21 path: path.to_owned(),
22 })?;
23 let pack_len = data.len();
24 if pack_len < N32_SIZE * 3 + hash_len {
25 return Err(data::header::decode::Error::Corrupt(format!(
26 "Pack data of size {pack_len} is too small for even an empty pack with shortest hash"
27 )));
28 }
29 let (kind, num_objects) =
30 data::header::decode(&data[..12].try_into().expect("enough data after previous check"))?;
31 Ok(data::File {
32 data,
33 path: path.to_owned(),
34 id: gix_features::hash::crc32(path.as_os_str().to_string_lossy().as_bytes()),
35 version: kind,
36 num_objects,
37 hash_len,
38 object_hash,
39 })
40 }
41}