use crate::command::{CommandExecutor, GitCommand};
use crate::error::{Error, Result};
use async_trait::async_trait;
#[derive(Debug, Clone, Copy)]
pub enum CatFileMode {
Type,
Size,
Exists,
PrettyPrint,
}
#[derive(Debug, Clone)]
pub struct CatFileCommand {
pub executor: CommandExecutor,
pub mode: CatFileMode,
pub object: String,
}
impl CatFileCommand {
pub fn pretty_print(object: impl Into<String>) -> Self {
Self {
executor: CommandExecutor::default(),
mode: CatFileMode::PrettyPrint,
object: object.into(),
}
}
pub fn object_type(object: impl Into<String>) -> Self {
Self {
executor: CommandExecutor::default(),
mode: CatFileMode::Type,
object: object.into(),
}
}
pub fn size(object: impl Into<String>) -> Self {
Self {
executor: CommandExecutor::default(),
mode: CatFileMode::Size,
object: object.into(),
}
}
pub fn exists(object: impl Into<String>) -> Self {
Self {
executor: CommandExecutor::default(),
mode: CatFileMode::Exists,
object: object.into(),
}
}
}
#[async_trait]
impl GitCommand for CatFileCommand {
type Output = String;
fn get_executor(&self) -> &CommandExecutor {
&self.executor
}
fn get_executor_mut(&mut self) -> &mut CommandExecutor {
&mut self.executor
}
fn build_command_args(&self) -> Vec<String> {
let flag = match self.mode {
CatFileMode::Type => "-t",
CatFileMode::Size => "-s",
CatFileMode::Exists => "-e",
CatFileMode::PrettyPrint => "-p",
};
vec!["cat-file".into(), flag.into(), self.object.clone()]
}
async fn execute(&self) -> Result<String> {
if self.object.is_empty() {
return Err(Error::invalid_config(
"cat-file requires a non-empty object",
));
}
let out = self.execute_raw().await?;
Ok(out.stdout_trimmed().to_string())
}
}