gitignore_template_generator/parser/
api.rs

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