use std::collections::HashMap;
use bstr::{BStr, BString, ByteSlice, ByteVec};
pub mod init;
pub mod apply;
pub mod shutdown;
pub mod delayed;
pub mod process;
pub enum Process<'a> {
SingleFile {
child: std::process::Child,
command: std::process::Command,
},
MultiFile {
client: &'a mut process::Client,
key: Key,
},
}
#[derive(Debug, Copy, Clone)]
pub enum Operation {
Clean,
Smudge,
}
impl Operation {
pub fn as_str(&self) -> &'static str {
match self {
Operation::Clean => "clean",
Operation::Smudge => "smudge",
}
}
}
#[derive(Default)]
pub struct State {
running: HashMap<BString, process::Client>,
pub context: gix_command::Context,
}
impl State {
pub fn new(context: gix_command::Context) -> Self {
Self {
running: Default::default(),
context,
}
}
}
impl Clone for State {
fn clone(&self) -> Self {
State {
running: Default::default(),
context: self.context.clone(),
}
}
}
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct Key(BString);
fn substitute_f_parameter(cmd: &BStr, path: &BStr) -> BString {
let mut buf: BString = Vec::with_capacity(cmd.len()).into();
let mut ofs = 0;
while let Some(pos) = cmd[ofs..].find(b"%f") {
buf.push_str(&cmd[ofs..ofs + pos]);
buf.extend_from_slice(&gix_quote::single(path));
ofs += pos + 2;
}
buf.push_str(&cmd[ofs..]);
buf
}
#[cfg(test)]
mod tests {
use super::substitute_f_parameter;
#[test]
fn each_f_parameter_is_replaced_with_the_quoted_path() {
for (cmd, expected) in [
("cmd", "cmd"),
("cmd %f", "cmd 'path'"),
("cmd a %f b %f c", "cmd a 'path' b 'path' c"),
("%f %f %f", "'path' 'path' 'path'"),
] {
assert_eq!(
substitute_f_parameter(cmd.into(), "path".into()),
expected,
"only `%f` is replaced, the rest of the command is copied exactly once"
);
}
}
}