gitignore_template_generator/parser/api.rs
1use std::ffi::OsString;
2
3use clap::ValueEnum;
4
5use crate::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 /// Sets new value for `template_names` field.
115 ///
116 /// It needs to be called on struct instance and effectively mutates it.
117 ///
118 /// # Arguments
119 ///
120 /// * `template_names` - The new value to be assigned to `template_names`
121 /// field.
122 ///
123 /// # Returns
124 ///
125 /// The mutated borrowed instance.
126 pub fn with_template_names(mut self, template_names: Vec<String>) -> Self {
127 self.template_names = template_names;
128 self
129 }
130
131 /// Sets new value for `server_url` field.
132 ///
133 /// It needs to be called on struct instance and effectively mutates it.
134 ///
135 /// # Arguments
136 ///
137 /// * `server_url` - The new value to be assigned to `server_url`
138 /// field.
139 ///
140 /// # Returns
141 ///
142 /// The mutated borrowed instance.
143 pub fn with_server_url(mut self, server_url: &str) -> Self {
144 self.server_url = server_url.to_string();
145 self
146 }
147
148 /// Sets new value for `generator_uri` field.
149 ///
150 /// It needs to be called on struct instance and effectively mutates it.
151 ///
152 /// # Arguments
153 ///
154 /// * `generator_uri` - The new value to be assigned to
155 /// `generator_uri` field.
156 ///
157 /// # Returns
158 ///
159 /// The mutated borrowed instance.
160 pub fn with_generator_uri(mut self, generator_uri: &str) -> Self {
161 self.generator_uri = generator_uri.to_string();
162 self
163 }
164
165 /// Sets new value for `lister_uri` field.
166 ///
167 /// It needs to be called on struct instance and effectively mutates it.
168 ///
169 /// # Arguments
170 ///
171 /// * `lister_uri` - The new value to be assigned to `lister_uri` field.
172 ///
173 /// # Returns
174 ///
175 /// The mutated borrowed instance.
176 pub fn with_lister_uri(mut self, lister_uri: &str) -> Self {
177 self.lister_uri = lister_uri.to_string();
178 self
179 }
180
181 /// Sets new value for `show_list` field.
182 ///
183 /// It needs to be called on struct instance and effectively mutates it.
184 ///
185 /// # Arguments
186 ///
187 /// * `show_list` - The new value to be assigned to `show_list`
188 /// field.
189 ///
190 /// # Returns
191 ///
192 /// The mutated borrowed instance.
193 pub fn with_show_list(mut self, show_list: bool) -> Self {
194 self.show_list = show_list;
195 self
196 }
197
198 /// Sets new value for `check_template_names` field.
199 ///
200 /// It needs to be called on struct instance and effectively mutates it.
201 ///
202 /// # Arguments
203 ///
204 /// * `check_template_names` - The new value to be assigned to
205 /// `check_template_names` field.
206 ///
207 /// # Returns
208 ///
209 /// The mutated borrowed instance.
210 pub fn with_check_template_names(
211 mut self,
212 check_template_names: bool,
213 ) -> Self {
214 self.check_template_names = check_template_names;
215 self
216 }
217
218 /// Sets new value for `timeout` field.
219 ///
220 /// It needs to be called on struct instance and effectively mutates it.
221 ///
222 /// # Arguments
223 ///
224 /// * `timeout` - The new value to be assigned to `timeout` field.
225 ///
226 /// # Returns
227 ///
228 /// The mutated borrowed instance.
229 pub fn with_timeout(mut self, timeout: u64) -> Self {
230 self.timeout = timeout;
231 self
232 }
233
234 /// Sets new value for `timeout_unit` field.
235 ///
236 /// It needs to be called on struct instance and effectively mutates it.
237 ///
238 /// # Arguments
239 ///
240 /// * `timeout_unit` - The new value to be assigned to `timeout_unit` field.
241 ///
242 /// # Returns
243 ///
244 /// The mutated borrowed instance.
245 pub fn with_timeout_unit(mut self, timeout_unit: TimeoutUnit) -> Self {
246 self.timeout_unit = timeout_unit;
247 self
248 }
249}
250
251/// Cli args parser trait to parse CLI args and return them in an [`Args`].
252///
253/// The produced Args instance needs to comply with constraints of each
254/// one of its fields (see fields doc in [`Args`] for more infos).
255pub trait ArgsParser {
256 /// Parses given cli args and return them as an [`Args`] instance.
257 ///
258 /// * First CLI args should be the binary name
259 /// * Rely on [`ArgsParser::try_parse`] method but additionally wrap
260 /// error handling logic
261 ///
262 /// # Arguments
263 ///
264 /// * `args` - The CLI args to be parsed. Typically retrieved from
265 /// [`std::env::args_os`].
266 ///
267 /// # Returns
268 ///
269 /// An owned instance of [`Args`] containing parsing result of given args.
270 fn parse(&self, args: impl IntoIterator<Item = OsString>) -> Args;
271
272 /// Parses given cli args and return them as an [`Args`] instance if no
273 /// error or early exit occurred.
274 ///
275 /// * First CLI args should be the binary name
276 /// * Version, author and help options are considered as early program
277 /// exit
278 /// * Returned Args complies with expected constraints (see fields doc
279 /// in [`Args`] for more infos)
280 ///
281 /// # Arguments
282 ///
283 /// * `args` - The CLI args to be parsed. Typically retrieved from
284 /// [`std::env::args_os`].
285 ///
286 /// # Returns
287 ///
288 /// A result containing an owned instance of [`Args`] if successful parsing,
289 /// or a [`ProgramExit`] if any error or early exit occurred (e.g. version/
290 /// author/help infos printing, invalid cli args...)
291 fn try_parse(
292 &self,
293 args: impl IntoIterator<Item = OsString>,
294 ) -> Result<Args, ProgramExit>;
295}