use crate::inventory::Entry;
pub fn chk_inventory_entry_to_bytes(entry: &Entry) -> Vec<u8> {
let parent_str = entry.parent_id().map(|p| p.as_bytes()).unwrap_or(b"");
let ts;
let (header, mut lines) = match entry {
Entry::File {
name,
executable,
revision,
text_sha1,
text_size,
..
} => {
ts = format!("{}", text_size.unwrap());
(
&b"file"[..],
vec![
parent_str,
name.as_bytes(),
revision.as_ref().unwrap().as_bytes(),
text_sha1.as_ref().unwrap().as_slice(),
ts.as_bytes(),
if *executable { b"Y" } else { b"N" },
],
)
}
Entry::Directory { revision, name, .. } => (
&b"dir"[..],
vec![
parent_str,
name.as_bytes(),
revision.as_ref().unwrap().as_bytes(),
],
),
Entry::Link {
name,
revision,
symlink_target,
..
} => (
&b"symlink"[..],
vec![
parent_str,
name.as_bytes(),
revision.as_ref().unwrap().as_bytes(),
symlink_target.as_ref().unwrap().as_bytes(),
],
),
Entry::TreeReference {
revision,
name,
reference_revision,
..
} => (
&b"tree"[..],
vec![
parent_str,
name.as_bytes(),
revision.as_ref().unwrap().as_bytes(),
reference_revision.as_ref().unwrap().as_bytes(),
],
),
};
let header = vec![header, b": ", entry.file_id().as_bytes()].concat();
lines.insert(0, header.as_slice());
lines.join(&b"\n"[..])
}
pub fn chk_inventory_bytes_to_entry(data: &[u8]) -> Entry {
let sections = data.split(|&c| c == b'\n').collect::<Vec<_>>();
let sp: Vec<&[u8]> = sections[0].splitn(2, |&c| c == b':').collect();
assert!(&sp[1][..1] == b" ");
let kind = sp[0];
let file_id = &sp[1][1..];
let file_id = crate::FileId::from(file_id);
let name = String::from_utf8(sections[2].to_vec()).unwrap();
let parent_id = if sections[1].is_empty() {
None
} else {
Some(crate::FileId::from(sections[1]))
};
let revision = Some(crate::RevisionId::from(sections[3]));
match String::from_utf8(kind.to_vec()).unwrap().as_str() {
"file" => Entry::File {
name,
file_id,
parent_id,
text_sha1: Some(sections[4].to_vec()),
text_size: Some(
String::from_utf8(sections[5].to_vec())
.unwrap()
.parse()
.unwrap(),
),
executable: sections[6] == b"Y",
revision,
text_id: None,
},
"dir" => Entry::Directory {
name,
file_id,
parent_id,
revision,
},
"symlink" => Entry::Link {
name,
file_id,
parent_id,
symlink_target: Some(String::from_utf8(sections[4].to_vec()).unwrap()),
revision,
},
"tree" => Entry::TreeReference {
name,
file_id,
parent_id,
reference_revision: Some(crate::RevisionId::from(sections[4])),
revision,
},
_ => {
panic!("Invalid inventory entry");
}
}
}
pub fn chk_inventory_bytes_to_utf8_name_key(
data: &[u8],
) -> (&[u8], crate::FileId, crate::RevisionId) {
let sections = data.split(|&c| c == b'\n').collect::<Vec<_>>();
let sp: Vec<&[u8]> = sections[0].splitn(2, |&c| c == b':').collect();
assert!(&sp[1][..1] == b" ");
let file_id = &sp[1][1..];
let file_id = crate::FileId::from(file_id);
let revision = crate::RevisionId::from(sections[3]);
(sections[2], file_id, revision)
}