git_spawn/command/
hash_object.rs1use crate::command::{CommandExecutor, GitCommand};
4use crate::error::{Error, Result};
5use async_trait::async_trait;
6use std::path::PathBuf;
7
8#[derive(Debug, Clone, Default)]
10pub struct HashObjectCommand {
11 pub executor: CommandExecutor,
13 pub paths: Vec<PathBuf>,
15 pub write: bool,
17 pub stdin: bool,
20 pub object_type: Option<String>,
22}
23
24impl HashObjectCommand {
25 #[must_use]
27 pub fn new() -> Self {
28 Self::default()
29 }
30
31 pub fn path(&mut self, p: impl Into<PathBuf>) -> &mut Self {
33 self.paths.push(p.into());
34 self
35 }
36
37 pub fn write(&mut self) -> &mut Self {
39 self.write = true;
40 self
41 }
42
43 pub fn object_type(&mut self, t: impl Into<String>) -> &mut Self {
45 self.object_type = Some(t.into());
46 self
47 }
48}
49
50#[async_trait]
51impl GitCommand for HashObjectCommand {
52 type Output = String;
54
55 fn get_executor(&self) -> &CommandExecutor {
56 &self.executor
57 }
58
59 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
60 &mut self.executor
61 }
62
63 fn build_command_args(&self) -> Vec<String> {
64 let mut args = vec!["hash-object".to_string()];
65 if self.write {
66 args.push("-w".into());
67 }
68 if let Some(t) = &self.object_type {
69 args.push("-t".into());
70 args.push(t.clone());
71 }
72 if self.stdin {
73 args.push("--stdin".into());
74 }
75 args.extend(self.paths.iter().map(|p| p.display().to_string()));
76 args
77 }
78
79 async fn execute(&self) -> Result<String> {
80 if self.paths.is_empty() && !self.stdin {
81 return Err(Error::invalid_config(
82 "hash-object requires at least one path",
83 ));
84 }
85 let out = self.execute_raw().await?;
86 Ok(out.stdout_trimmed().to_string())
87 }
88}