pub fn status_paths(output: &[u8]) -> Vec<Vec<u8>> {
let mut paths: Vec<Vec<u8>> = Vec::<Vec<u8>>::new();
let mut entries = non_empty_fields(output).into_iter();
while let Some(entry) = entries.next() {
if entry.len() < 4 {
continue;
}
paths.push(entry[3..].to_vec());
let renamed: bool = matches!(entry[0], b'R' | b'C') || matches!(entry[1], b'R' | b'C');
if renamed && let Some(original) = entries.next() {
paths.push(original.to_vec());
}
}
return paths;
}
pub fn diff_paths(output: &[u8]) -> Vec<Vec<u8>> {
let mut paths: Vec<Vec<u8>> = Vec::new();
for path in non_empty_fields(output) {
paths.push(path.to_vec());
}
return paths;
}
fn is_nul(byte: &u8) -> bool {
return *byte == 0;
}
fn non_empty_fields(output: &[u8]) -> Vec<&[u8]> {
let mut fields: Vec<&[u8]> = Vec::new();
for field in output.split(is_nul) {
if !field.is_empty() {
fields.push(field);
}
}
return fields;
}
pub fn overlapping_paths(dirty: &[Vec<u8>], incoming: &[Vec<u8>]) -> Vec<Vec<u8>> {
let mut overlap: Vec<Vec<u8>> = Vec::<Vec<u8>>::new();
for path in dirty {
if incoming.contains(path) && !overlap.contains(path) {
overlap.push(path.clone());
}
}
return overlap;
}
const LISTED_LIMIT: usize = 5;
pub fn listed(paths: &[Vec<u8>]) -> String {
let mut names: Vec<String> = Vec::new();
for path in paths.iter().take(LISTED_LIMIT) {
names.push(String::from_utf8_lossy(path).into_owned());
}
if paths.len() > LISTED_LIMIT {
names.push(format!("and {} more", paths.len() - LISTED_LIMIT));
}
return names.join(", ");
}
#[cfg(test)]
#[path = "auto_push_dirty_paths_tests.rs"]
mod tests;