gitignore_template_generator/parser/api.rs
1use std::ffi::OsString;
2
3use clap::ValueEnum;
4
5use crate::core::ProgramExit;
6pub use crate::parser::impls::ClapArgsParser;
7
8#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Default)]
9pub enum TimeoutUnit {
10 MILLISECOND,
11 #[default]
12 SECOND,
13}
14
15/// Struct to gather cli args parsing result.
16///
17/// Used by [`crate::parser::ArgsParser`] implementations to store
18/// parsing result.
19#[derive(Debug, PartialEq, Default)]
20pub struct Args {
21 /// A non-empty list of gitignore template names.
22 ///
23 /// * Represented by the provided positional arguments, and required
24 /// unless any of `author`, `version` or `help` options are given.
25 /// * This field does not allow commas in any of its field.
26 pub template_names: Vec<String>,
27
28 /// The gitignore template generator service url.
29 ///
30 /// * Optional value represented by the cli option
31 /// [`crate::constant::cli_options::SERVER_URL`] that takes a string
32 /// value, and falling back to
33 /// [`crate::constant::template_manager::BASE_URL`] if not provided
34 /// in cli args.
35 pub server_url: String,
36
37 /// The gitignore template generator service endpoint uri.
38 ///
39 /// * Optional value represented by the cli option
40 /// [`crate::constant::cli_options::GENERATOR_URI`] that takes a string
41 /// value, and falling back to
42 /// [`crate::constant::template_manager::GENERATOR_URI`] if not provided in cli
43 /// args.
44 pub generator_uri: String,
45
46 /// The gitignore template lister service endpoint uri.
47 ///
48 /// * Optional value represented by the cli option
49 /// [`crate::constant::cli_options::LISTER_URI`] that takes a string
50 /// value, and falling back to
51 /// [`crate::constant::template_manager::LISTER_URI`] if not provided in cli
52 /// args.
53 pub lister_uri: String,
54
55 /// The boolean indicator of whether to display help infos or not.
56 ///
57 /// * Optional value represented by the cli option
58 /// [`crate::constant::cli_options::HELP`], and falling back to `false`
59 /// if not provided in cli args.
60 /// * Has precedence over version and author options if multiple are given
61 pub show_help: bool,
62
63 /// The boolean indicator of whether to display version infos or not.
64 ///
65 /// * Optional value represented by the cli option
66 /// [`crate::constant::cli_options::VERSION`], and falling back to
67 /// `false` if not provided in cli args.
68 /// * Has precedence over author option if multiple are given
69 pub show_version: bool,
70
71 /// The boolean indicator of whether to display author infos or not.
72 ///
73 /// * Optional value represented by the cli option
74 /// [`crate::constant::cli_options::AUTHOR`], and falling back to
75 /// `false` if not provided in cli args.
76 pub show_author: bool,
77
78 /// The boolean indicator of whether to display list of available templates
79 /// or not.
80 ///
81 /// * Optional value represented by the cli option
82 /// [`crate::constant::cli_options::LIST`], and falling back to
83 /// `false` if not provided in cli args.
84 pub show_list: bool,
85
86 /// The boolean indicator of whether to enable robust template check or not.
87 ///
88 /// Robust template check allow the script to handle template existence
89 /// check without reaching the generator endpoint.
90 ///
91 /// * Optional value represented by the cli option
92 /// [`crate::constant::cli_options::CHECK`], and falling back to
93 /// `false` if not provided in cli args.
94 pub check_template_names: bool,
95
96 /// The service call timeout.
97 ///
98 /// * Optional value represented by the cli option
99 /// [`crate::constant::cli_options::TIMEOUT`], and falling back to
100 /// [`crate::constant::template_manager::TIMEOUT`] if not provided in
101 /// cli args.
102 pub timeout: u64,
103
104 /// The timeout unit.
105 ///
106 /// * Optional value represented by the cli option
107 /// [`crate::constant::cli_options::TIMEOUT_UNIT`], and falling back to
108 /// [`crate::constant::template_manager::TIMEOUT_UNIT`] if not provided in
109 /// cli args.
110 pub timeout_unit: TimeoutUnit,
111}
112
113impl Args {
114 pub fn new() -> Self {
115 Self {
116 template_names: Vec::new(),
117 server_url: crate::constant::template_manager::BASE_URL.to_string(),
118 generator_uri: crate::constant::template_manager::GENERATOR_URI
119 .to_string(),
120 lister_uri: crate::constant::template_manager::LISTER_URI
121 .to_string(),
122 show_help: false,
123 show_version: false,
124 show_author: false,
125 show_list: false,
126 check_template_names: false,
127 timeout: crate::constant::template_manager::TIMEOUT_INT,
128 timeout_unit: crate::constant::template_manager::TIMEOUT_UNIT_ENUM,
129 }
130 }
131
132 /// Sets new value for `template_names` field.
133 ///
134 /// It needs to be called on struct instance and effectively mutates it.
135 ///
136 /// # Arguments
137 ///
138 /// * `template_names` - The new value to be assigned to `template_names`
139 /// field.
140 ///
141 /// # Returns
142 ///
143 /// The mutated borrowed instance.
144 pub fn with_template_names(mut self, template_names: Vec<String>) -> Self {
145 self.template_names = template_names;
146 self
147 }
148
149 /// Sets new value for `server_url` field.
150 ///
151 /// It needs to be called on struct instance and effectively mutates it.
152 ///
153 /// # Arguments
154 ///
155 /// * `server_url` - The new value to be assigned to `server_url`
156 /// field.
157 ///
158 /// # Returns
159 ///
160 /// The mutated borrowed instance.
161 pub fn with_server_url(mut self, server_url: &str) -> Self {
162 self.server_url = server_url.to_string();
163 self
164 }
165
166 /// Sets new value for `generator_uri` field.
167 ///
168 /// It needs to be called on struct instance and effectively mutates it.
169 ///
170 /// # Arguments
171 ///
172 /// * `generator_uri` - The new value to be assigned to
173 /// `generator_uri` field.
174 ///
175 /// # Returns
176 ///
177 /// The mutated borrowed instance.
178 pub fn with_generator_uri(mut self, generator_uri: &str) -> Self {
179 self.generator_uri = generator_uri.to_string();
180 self
181 }
182
183 /// Sets new value for `lister_uri` field.
184 ///
185 /// It needs to be called on struct instance and effectively mutates it.
186 ///
187 /// # Arguments
188 ///
189 /// * `lister_uri` - The new value to be assigned to `lister_uri` field.
190 ///
191 /// # Returns
192 ///
193 /// The mutated borrowed instance.
194 pub fn with_lister_uri(mut self, lister_uri: &str) -> Self {
195 self.lister_uri = lister_uri.to_string();
196 self
197 }
198
199 /// Sets new value for `show_list` field.
200 ///
201 /// It needs to be called on struct instance and effectively mutates it.
202 ///
203 /// # Arguments
204 ///
205 /// * `show_list` - The new value to be assigned to `show_list`
206 /// field.
207 ///
208 /// # Returns
209 ///
210 /// The mutated borrowed instance.
211 pub fn with_show_list(mut self, show_list: bool) -> Self {
212 self.show_list = show_list;
213 self
214 }
215
216 /// Sets new value for `check_template_names` field.
217 ///
218 /// It needs to be called on struct instance and effectively mutates it.
219 ///
220 /// # Arguments
221 ///
222 /// * `check_template_names` - The new value to be assigned to
223 /// `check_template_names` field.
224 ///
225 /// # Returns
226 ///
227 /// The mutated borrowed instance.
228 pub fn with_check_template_names(
229 mut self,
230 check_template_names: bool,
231 ) -> Self {
232 self.check_template_names = check_template_names;
233 self
234 }
235
236 /// Sets new value for `timeout` field.
237 ///
238 /// It needs to be called on struct instance and effectively mutates it.
239 ///
240 /// # Arguments
241 ///
242 /// * `timeout` - The new value to be assigned to `timeout` field.
243 ///
244 /// # Returns
245 ///
246 /// The mutated borrowed instance.
247 pub fn with_timeout(mut self, timeout: u64) -> Self {
248 self.timeout = timeout;
249 self
250 }
251
252 /// Sets new value for `timeout_unit` field.
253 ///
254 /// It needs to be called on struct instance and effectively mutates it.
255 ///
256 /// # Arguments
257 ///
258 /// * `timeout_unit` - The new value to be assigned to `timeout_unit` field.
259 ///
260 /// # Returns
261 ///
262 /// The mutated borrowed instance.
263 pub fn with_timeout_unit(mut self, timeout_unit: TimeoutUnit) -> Self {
264 self.timeout_unit = timeout_unit;
265 self
266 }
267}
268
269/// Cli args parser trait to parse CLI args and return them in an [`Args`].
270///
271/// The produced Args instance needs to comply with constraints of each
272/// one of its fields (see fields doc in [`Args`] for more infos).
273pub trait ArgsParser {
274 /// Parses given cli args and return them as an [`Args`] instance.
275 ///
276 /// * First CLI args should be the binary name
277 /// * Rely on [`ArgsParser::try_parse`] method but additionally wrap
278 /// error handling logic
279 ///
280 /// # Arguments
281 ///
282 /// * `args` - The CLI args to be parsed. Typically retrieved from
283 /// [`std::env::args_os`].
284 ///
285 /// # Returns
286 ///
287 /// An owned instance of [`Args`] containing parsing result of given args.
288 fn parse(&self, args: impl IntoIterator<Item = OsString>) -> Args;
289
290 /// Parses given cli args and return them as an [`Args`] instance if no
291 /// error or early exit occurred.
292 ///
293 /// * First CLI args should be the binary name
294 /// * Version, author and help options are considered as early program
295 /// exit
296 /// * Returned Args complies with expected constraints (see fields doc
297 /// in [`Args`] for more infos)
298 ///
299 /// # Arguments
300 ///
301 /// * `args` - The CLI args to be parsed. Typically retrieved from
302 /// [`std::env::args_os`].
303 ///
304 /// # Returns
305 ///
306 /// A result containing an owned instance of [`Args`] if successful parsing,
307 /// or a [`ProgramExit`] if any error or early exit occurred (e.g. version/
308 /// author/help infos printing, invalid cli args...)
309 fn try_parse(
310 &self,
311 args: impl IntoIterator<Item = OsString>,
312 ) -> Result<Args, ProgramExit>;
313}