use bstr::BString; use git_hash::ObjectId; use crate::{ extension::Signature, util::{split_at_byte_exclusive, split_at_pos}, }; pub type Paths = Vec; #[allow(dead_code)] #[derive(Clone)] pub struct ResolvePath { /// relative to the root of the repository, or what would be stored in the index name: BString, /// 0 = ancestor/common, 1 = ours, 2 = theirs stages: [Option; 3], } #[allow(dead_code)] #[derive(Clone, Copy)] pub struct Stage { mode: u32, id: ObjectId, } pub const SIGNATURE: Signature = *b"REUC"; pub fn decode(mut data: &[u8], object_hash: git_hash::Kind) -> Option { let hash_len = object_hash.len_in_bytes(); let mut out = Vec::new(); while !data.is_empty() { let (path, rest) = split_at_byte_exclusive(data, 0)?; data = rest; let mut modes = [0u32; 3]; for mode in modes.iter_mut() { let (mode_ascii, rest) = split_at_byte_exclusive(data, 0)?; data = rest; *mode = u32::from_str_radix(std::str::from_utf8(mode_ascii).ok()?, 8).ok()?; } let mut stages = [None, None, None]; for (mode, stage) in modes.iter().zip(stages.iter_mut()) { if *mode == 0 { continue; } let (hash, rest) = split_at_pos(data, hash_len)?; data = rest; *stage = Some(Stage { mode: *mode, id: ObjectId::from(hash), }); } out.push(ResolvePath { name: path.into(), stages, }); } out.into() }