git_spawn/command/
status.rs1use crate::command::{CommandExecutor, CommandOutput, GitCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone, Copy)]
9pub enum StatusFormat {
10 Short,
12 Long,
14 PorcelainV1,
16 PorcelainV2,
18}
19
20#[derive(Debug, Clone, Default)]
22pub struct StatusCommand {
23 pub executor: CommandExecutor,
25 pub format: Option<StatusFormat>,
27 pub branch: bool,
29 pub show_stash: bool,
31 pub null_terminate: bool,
33 pub untracked_files: Option<String>,
35 pub ignored: bool,
37 pub paths: Vec<String>,
39}
40
41impl StatusCommand {
42 #[must_use]
44 pub fn new() -> Self {
45 Self::default()
46 }
47
48 pub fn format(&mut self, f: StatusFormat) -> &mut Self {
50 self.format = Some(f);
51 self
52 }
53
54 pub fn branch(&mut self) -> &mut Self {
56 self.branch = true;
57 self
58 }
59
60 pub fn show_stash(&mut self) -> &mut Self {
62 self.show_stash = true;
63 self
64 }
65
66 pub fn null_terminate(&mut self) -> &mut Self {
68 self.null_terminate = true;
69 self
70 }
71
72 pub fn untracked_files(&mut self, mode: impl Into<String>) -> &mut Self {
74 self.untracked_files = Some(mode.into());
75 self
76 }
77
78 pub fn ignored(&mut self) -> &mut Self {
80 self.ignored = true;
81 self
82 }
83
84 pub fn path(&mut self, p: impl Into<String>) -> &mut Self {
86 self.paths.push(p.into());
87 self
88 }
89}
90
91#[async_trait]
92impl GitCommand for StatusCommand {
93 type Output = CommandOutput;
94
95 fn get_executor(&self) -> &CommandExecutor {
96 &self.executor
97 }
98
99 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
100 &mut self.executor
101 }
102
103 fn build_command_args(&self) -> Vec<String> {
104 let mut args = vec!["status".to_string()];
105 match self.format {
106 Some(StatusFormat::Short) => args.push("--short".into()),
107 Some(StatusFormat::Long) => args.push("--long".into()),
108 Some(StatusFormat::PorcelainV1) => args.push("--porcelain=v1".into()),
109 Some(StatusFormat::PorcelainV2) => args.push("--porcelain=v2".into()),
110 None => {}
111 }
112 if self.branch {
113 args.push("--branch".into());
114 }
115 if self.show_stash {
116 args.push("--show-stash".into());
117 }
118 if self.null_terminate {
119 args.push("-z".into());
120 }
121 if let Some(m) = &self.untracked_files {
122 args.push(format!("--untracked-files={m}"));
123 }
124 if self.ignored {
125 args.push("--ignored".into());
126 }
127 if !self.paths.is_empty() {
128 args.push("--".into());
129 args.extend(self.paths.iter().cloned());
130 }
131 args
132 }
133
134 async fn execute(&self) -> Result<CommandOutput> {
135 self.execute_raw().await
136 }
137}