1use std::path::Path;
2
3use crate::CommandError;
4
5#[must_use]
7pub fn list() -> List<'static> {
8 List::new()
9}
10
11#[must_use]
13pub fn add(path: &Path) -> Add<'_> {
14 Add::new(path)
15}
16
17#[must_use]
19pub fn remove(worktree: &Path) -> Remove<'_> {
20 Remove::new(worktree)
21}
22
23#[derive(Debug)]
27pub struct List<'a> {
28 repo_path: Option<&'a Path>,
29 porcelain: bool,
30}
31
32crate::impl_repo_path!(List);
33crate::impl_porcelain!(List);
34
35impl<'a> List<'a> {
36 #[must_use]
37 fn new() -> Self {
38 Self {
39 repo_path: None,
40 porcelain: false,
41 }
42 }
43}
44
45impl Default for List<'_> {
46 fn default() -> Self {
47 Self::new()
48 }
49}
50
51impl crate::Build for List<'_> {
52 fn build(self) -> cmd_proc::Command {
53 crate::base_command(self.repo_path)
54 .argument("worktree")
55 .argument("list")
56 .optional_flag(self.porcelain, "--porcelain")
57 }
58}
59
60#[cfg(feature = "test-utils")]
61impl List<'_> {
62 pub fn test_eq(&self, other: &cmd_proc::Command) {
64 let command = crate::Build::build(Self {
65 repo_path: self.repo_path,
66 porcelain: self.porcelain,
67 });
68 command.test_eq(other);
69 }
70}
71
72#[derive(Debug)]
76pub struct Add<'a> {
77 repo_path: Option<&'a Path>,
78 path: &'a Path,
79 branch: Option<&'a str>,
80 new_branch: Option<&'a str>,
81 commit_ish: Option<&'a str>,
82}
83
84crate::impl_repo_path!(Add);
85
86impl<'a> Add<'a> {
87 #[must_use]
88 fn new(path: &'a Path) -> Self {
89 Self {
90 repo_path: None,
91 path,
92 branch: None,
93 new_branch: None,
94 commit_ish: None,
95 }
96 }
97
98 #[must_use]
100 pub fn branch(mut self, branch: &'a str) -> Self {
101 self.branch = Some(branch);
102 self
103 }
104
105 #[must_use]
109 pub fn new_branch(mut self, branch: &'a str) -> Self {
110 self.new_branch = Some(branch);
111 self
112 }
113
114 #[must_use]
116 pub fn commit_ish(mut self, commit_ish: &'a str) -> Self {
117 self.commit_ish = Some(commit_ish);
118 self
119 }
120
121 pub async fn status(self) -> Result<(), CommandError> {
123 crate::Build::build(self).status().await
124 }
125}
126
127impl crate::Build for Add<'_> {
128 fn build(self) -> cmd_proc::Command {
129 crate::base_command(self.repo_path)
130 .argument("worktree")
131 .argument("add")
132 .optional_option("-b", self.new_branch)
133 .argument(self.path)
134 .optional_argument(self.branch)
135 .optional_argument(self.commit_ish)
136 }
137}
138
139#[cfg(feature = "test-utils")]
140impl Add<'_> {
141 pub fn test_eq(&self, other: &cmd_proc::Command) {
143 let command = crate::Build::build(Self {
144 repo_path: self.repo_path,
145 path: self.path,
146 branch: self.branch,
147 new_branch: self.new_branch,
148 commit_ish: self.commit_ish,
149 });
150 command.test_eq(other);
151 }
152}
153
154#[derive(Debug)]
158pub struct Remove<'a> {
159 repo_path: Option<&'a Path>,
160 worktree: &'a Path,
161 force: bool,
162}
163
164crate::impl_repo_path!(Remove);
165
166impl<'a> Remove<'a> {
167 #[must_use]
168 fn new(worktree: &'a Path) -> Self {
169 Self {
170 repo_path: None,
171 worktree,
172 force: false,
173 }
174 }
175
176 crate::flag_methods! {
177 pub fn force / force_if, force, "Conditionally force removal."
181 }
182
183 pub async fn status(self) -> Result<(), CommandError> {
185 crate::Build::build(self).status().await
186 }
187}
188
189impl crate::Build for Remove<'_> {
190 fn build(self) -> cmd_proc::Command {
191 crate::base_command(self.repo_path)
192 .argument("worktree")
193 .argument("remove")
194 .optional_flag(self.force, "--force")
195 .argument(self.worktree)
196 }
197}
198
199#[cfg(feature = "test-utils")]
200impl Remove<'_> {
201 pub fn test_eq(&self, other: &cmd_proc::Command) {
203 let command = crate::Build::build(Self {
204 repo_path: self.repo_path,
205 worktree: self.worktree,
206 force: self.force,
207 });
208 command.test_eq(other);
209 }
210}