1use std::path::PathBuf;
7
8use serde::{Deserialize, Serialize};
9
10use crate::workspace::SyncSource;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct SyncRequest {
15 pub source: SyncSource,
17
18 #[serde(default)]
20 pub ignore: Vec<String>,
21
22 #[serde(default)]
24 pub no_save: bool,
25
26 #[serde(default)]
28 pub snapshot: bool,
29
30 #[serde(default)]
32 pub use_cache: bool,
33
34 #[serde(default)]
36 pub force: bool,
37}
38
39impl SyncRequest {
40 pub fn local(path: impl Into<PathBuf>) -> Self {
42 Self {
43 source: SyncSource::local(path),
44 ignore: vec![],
45 no_save: false,
46 snapshot: false,
47 use_cache: false,
48 force: false,
49 }
50 }
51
52 pub fn github_org(org: impl Into<String>) -> Self {
54 Self {
55 source: SyncSource::github_org(org),
56 ignore: vec![],
57 no_save: false,
58 snapshot: false,
59 use_cache: false,
60 force: false,
61 }
62 }
63
64 pub fn github_repo(owner: impl Into<String>, repo: impl Into<String>) -> Self {
66 Self {
67 source: SyncSource::github_repo(owner, repo),
68 ignore: vec![],
69 no_save: false,
70 snapshot: false,
71 use_cache: false,
72 force: false,
73 }
74 }
75
76 pub fn detect(input: &str) -> Self {
78 Self {
79 source: SyncSource::detect(input),
80 ignore: vec![],
81 no_save: false,
82 snapshot: false,
83 use_cache: false,
84 force: false,
85 }
86 }
87
88 pub fn with_ignore(mut self, ignore: impl IntoIterator<Item = impl Into<String>>) -> Self {
90 self.ignore.extend(ignore.into_iter().map(|s| s.into()));
91 self
92 }
93
94 pub fn without_save(mut self) -> Self {
96 self.no_save = true;
97 self
98 }
99
100 pub fn with_snapshot(mut self) -> Self {
102 self.snapshot = true;
103 self
104 }
105
106 pub fn use_cache(mut self) -> Self {
108 self.use_cache = true;
109 self
110 }
111
112 pub fn force(mut self) -> Self {
114 self.force = true;
115 self
116 }
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct GraphRequest {
122 pub path: PathBuf,
124
125 #[serde(skip_serializing_if = "Option::is_none")]
127 pub output: Option<PathBuf>,
128
129 #[serde(default)]
131 pub force: bool,
132}
133
134impl GraphRequest {
135 pub fn new(path: impl Into<PathBuf>) -> Self {
137 Self {
138 path: path.into(),
139 output: None,
140 force: false,
141 }
142 }
143
144 pub fn with_output(mut self, output: impl Into<PathBuf>) -> Self {
146 self.output = Some(output.into());
147 self
148 }
149
150 pub fn force(mut self) -> Self {
152 self.force = true;
153 self
154 }
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct StatusRequest {
160 pub path: PathBuf,
162
163 #[serde(default)]
165 pub detailed: bool,
166}
167
168impl StatusRequest {
169 pub fn new(path: impl Into<PathBuf>) -> Self {
171 Self {
172 path: path.into(),
173 detailed: false,
174 }
175 }
176
177 pub fn detailed(mut self) -> Self {
179 self.detailed = true;
180 self
181 }
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct LoadRequest {
187 pub path: PathBuf,
189}
190
191impl LoadRequest {
192 pub fn new(path: impl Into<PathBuf>) -> Self {
194 Self { path: path.into() }
195 }
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct ComposeRequest {
201 pub path: PathBuf,
203
204 #[serde(default)]
206 pub format: ComposeFormat,
207
208 #[serde(skip_serializing_if = "Option::is_none")]
210 pub output: Option<PathBuf>,
211
212 #[serde(default)]
214 pub force: bool,
215}
216
217#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
219#[serde(rename_all = "lowercase")]
220pub enum ComposeFormat {
221 #[default]
223 Markdown,
224 Json,
226}
227
228impl std::str::FromStr for ComposeFormat {
229 type Err = String;
230
231 fn from_str(s: &str) -> Result<Self, Self::Err> {
232 match s.to_lowercase().as_str() {
233 "md" | "markdown" => Ok(Self::Markdown),
234 "json" => Ok(Self::Json),
235 _ => Err(format!("Unknown format: {}", s)),
236 }
237 }
238}
239
240impl ComposeRequest {
241 pub fn new(path: impl Into<PathBuf>) -> Self {
243 Self {
244 path: path.into(),
245 format: ComposeFormat::Markdown,
246 output: None,
247 force: false,
248 }
249 }
250
251 pub fn format(mut self, format: ComposeFormat) -> Self {
253 self.format = format;
254 self
255 }
256
257 pub fn with_output(mut self, output: impl Into<PathBuf>) -> Self {
259 self.output = Some(output.into());
260 self
261 }
262
263 pub fn force(mut self) -> Self {
265 self.force = true;
266 self
267 }
268}
269
270#[derive(Debug, Clone, Serialize, Deserialize)]
272pub struct ServeRequest {
273 pub path: PathBuf,
275
276 #[serde(default = "default_port")]
278 pub port: u16,
279
280 #[serde(skip_serializing_if = "Option::is_none")]
282 pub wasm_dir: Option<PathBuf>,
283}
284
285fn default_port() -> u16 {
286 3000
287}
288
289impl ServeRequest {
290 pub fn new(path: impl Into<PathBuf>) -> Self {
292 Self {
293 path: path.into(),
294 port: default_port(),
295 wasm_dir: None,
296 }
297 }
298
299 pub fn port(mut self, port: u16) -> Self {
301 self.port = port;
302 self
303 }
304
305 pub fn wasm_dir(mut self, dir: impl Into<PathBuf>) -> Self {
307 self.wasm_dir = Some(dir.into());
308 self
309 }
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
314pub struct CleanRequest {
315 pub path: PathBuf,
317}
318
319impl CleanRequest {
320 pub fn new(path: impl Into<PathBuf>) -> Self {
322 Self { path: path.into() }
323 }
324}
325
326#[derive(Debug, Clone, Serialize, Deserialize)]
328pub struct GitChangesRequest {
329 pub path: PathBuf,
331}
332
333impl GitChangesRequest {
334 pub fn new(path: impl Into<PathBuf>) -> Self {
336 Self { path: path.into() }
337 }
338}