1use crate::command::{CommandExecutor, CommandOutput, GitCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone, Default)]
9pub struct AddCommand {
10 pub executor: CommandExecutor,
12 pub paths: Vec<String>,
14 pub all: bool,
16 pub update: bool,
18 pub force: bool,
20 pub dry_run: bool,
22 pub verbose: bool,
24 pub intent_to_add: bool,
26 pub patch: bool,
28 pub ignore_errors: bool,
30}
31
32impl AddCommand {
33 #[must_use]
35 pub fn new() -> Self {
36 Self::default()
37 }
38
39 pub fn path(&mut self, p: impl Into<String>) -> &mut Self {
41 self.paths.push(p.into());
42 self
43 }
44
45 pub fn paths<I, S>(&mut self, ps: I) -> &mut Self
47 where
48 I: IntoIterator<Item = S>,
49 S: Into<String>,
50 {
51 self.paths.extend(ps.into_iter().map(Into::into));
52 self
53 }
54
55 pub fn all(&mut self) -> &mut Self {
57 self.all = true;
58 self
59 }
60
61 pub fn update(&mut self) -> &mut Self {
63 self.update = true;
64 self
65 }
66
67 pub fn force(&mut self) -> &mut Self {
69 self.force = true;
70 self
71 }
72
73 pub fn dry_run(&mut self) -> &mut Self {
75 self.dry_run = true;
76 self
77 }
78
79 pub fn verbose(&mut self) -> &mut Self {
81 self.verbose = true;
82 self
83 }
84
85 pub fn intent_to_add(&mut self) -> &mut Self {
87 self.intent_to_add = true;
88 self
89 }
90
91 pub fn patch(&mut self) -> &mut Self {
93 self.patch = true;
94 self
95 }
96
97 pub fn ignore_errors(&mut self) -> &mut Self {
99 self.ignore_errors = true;
100 self
101 }
102}
103
104#[async_trait]
105impl GitCommand for AddCommand {
106 type Output = CommandOutput;
107
108 fn get_executor(&self) -> &CommandExecutor {
109 &self.executor
110 }
111
112 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
113 &mut self.executor
114 }
115
116 fn build_command_args(&self) -> Vec<String> {
117 let mut args = vec!["add".to_string()];
118 if self.all {
119 args.push("--all".into());
120 }
121 if self.update {
122 args.push("--update".into());
123 }
124 if self.force {
125 args.push("--force".into());
126 }
127 if self.dry_run {
128 args.push("--dry-run".into());
129 }
130 if self.verbose {
131 args.push("--verbose".into());
132 }
133 if self.intent_to_add {
134 args.push("--intent-to-add".into());
135 }
136 if self.patch {
137 args.push("--patch".into());
138 }
139 if self.ignore_errors {
140 args.push("--ignore-errors".into());
141 }
142 if !self.paths.is_empty() {
143 args.push("--".into());
144 args.extend(self.paths.iter().cloned());
145 }
146 args
147 }
148
149 async fn execute(&self) -> Result<CommandOutput> {
150 self.execute_raw().await
151 }
152}