1use crate::com::*;
2
3pub enum Parse2Err {
4 ExpectedOne,
5 Rquired,
6 ExpectedAtLeastOne,
7}
8pub enum ArgParseErr<'a> {
9 ParseErr(ParseErr<'a>),
10 Parse2Err(Parse2Err),
11}
12impl<'a> From<ParseErr<'a>> for ArgParseErr<'a> {
13 fn from(v: ParseErr<'a>) -> Self {
14 ArgParseErr::ParseErr(v)
15 }
16}
17impl<'a> From<Parse2Err> for ArgParseErr<'a> {
18 fn from(v: Parse2Err) -> Self {
19 ArgParseErr::Parse2Err(v)
20 }
21}
22pub enum ArgsParseErr<'a> {
23 UnexpectedToken(Arg<'a>, String),
24 Help(String),
25 UnknownArgs(Vec<Arg<'a>>, String),
26 Arg(&'static str, ArgParseErr<'a>, String),
27}
28impl<'a> Display for ArgsParseErr<'a> {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 use ArgsParseErr::*;
31 match self {
32 UnexpectedToken(ref a, _) => write!(f, "Unexpected token '{a}'")?,
33 Help(_) => (),
34 UnknownArgs(ref a, _) => write!(
35 f,
36 "Unknown options '{}'",
37 a.into_iter().map(|a| format!(r#""{a}""#)).join(", ")
38 )?,
39 Arg(ref a, ref e, _) => write!(f, "Error parsing option '{a}.'\n{e}")?,
40 };
41 Ok(())
42 }
43}
44impl<'a> Display for ArgParseErr<'a> {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 use ArgParseErr::*;
47 match self {
48 ParseErr(e) => write!(f, "{e}"),
49 Parse2Err(e) => write!(f, "{e}"),
50 }
51 }
52}
53impl<'a> Display for ParseErr<'a> {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 write!(
56 f,
57 "Failed to parse '{}' as '{}' because '{}'",
58 self.i, self.ty, self.e
59 )
60 }
61}
62impl Display for Parse2Err {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 use Parse2Err::*;
65 match self {
66 ExpectedOne => write!(f, "Expected one value."),
67 Rquired => write!(f, "Required."),
68 ExpectedAtLeastOne => write!(f, "Expected one value minimum."),
69 }
70 }
71}
72pub enum ArgsErr<'a> {
73 Run(String),
74 Parse(ArgsParseErr<'a>),
75}
76impl<'a> From<ArgsParseErr<'a>> for ArgsErr<'a> {
77 fn from(v: ArgsParseErr<'a>) -> Self {
78 Self::Parse(v)
79 }
80}
81
82pub const PFX: &'static str = "--";
83#[derive(Debug)]
84pub struct Key<'a> {
85 pub k: Option<&'a str>,
86 pub v: Vec<&'a str>,
87 pub used: bool,
88}
89#[derive(Debug)]
90pub struct ParsedArgs<'c> {
91 pub k: Vec<Key<'c>>,
92}
93
94impl<'c> ParsedArgs<'c> {
95 pub fn consume(&mut self, name: &str) -> Option<&Vec<&'c str>> {
96 let k = self
97 .k
98 .iter_mut()
99 .find(|k| k.k.map(|k| k == name).unwrap_or(false))?;
100 assert!(
101 !k.used,
102 "A token should not ever be consumed twice. Probably a duplicate argument: {name}"
103 );
104 k.used = true;
105 Some(&k.v)
106 }
107}
108
109pub enum ParsedArgsErr<'a> {
110 UnexpectedToken(Arg<'a>),
111}
112impl<'c> ParsedArgs<'c> {
113 pub fn new(args: &[&'c str]) -> Result<ParsedArgs<'c>, ParsedArgsErr<'c>> {
114 let mut last: Option<&str> = None;
115 let r = ParsedArgs {
116 k: args
117 .iter()
118 .filter_map(|a| {
119 if a.starts_with(PFX) {
120 last = Some(a);
121 None
122 } else {
123 Some((last, *a))
124 }
125 })
126 .into_group_map()
127 .into_iter()
128 .map(|(k, v)| Key { k, v, used: false })
129 .collect(),
130 };
131
132 Ok(r)
133 }
134}
135
136pub enum Init<C, T: Display> {
137 None,
138 Const(T),
139 Dyn(fn(&C) -> T),
140}
141
142impl<C, T: Display> Init<C, T> {
143 pub fn get(self, c: &C) -> Option<T> {
144 match self {
145 Init::None => None,
146 Init::Const(v) => Some(v),
147 Init::Dyn(f) => Some(f(&c)),
148 }
149 }
150 fn to_string(self, c: &C) -> String {
151 match self.get(c) {
152 Some(s) => format!(" (default: {s})"),
153 None => format!(""),
154 }
155 }
156}
157
158pub trait Parse2<'a, 'b, C>
159where
160 Self: Sized,
161 Self::I: Display,
162{
163 type I;
164 fn parse2(
165 i: Init<C, Self::I>,
166 k: &'static str,
167 c: &C,
168 p: &mut ParsedArgs<'b>,
169 ) -> Result<Self, ArgParseErr<'b>>;
170 fn desc2(i: Init<C, Self::I>, d: &'static str, k: &'static str, c: &C) -> [String; 4];
171 fn default2(c: &C, i: Init<C, Self::I>) -> Self;
172}
173
174impl<'a, 'b, C, T: Parse<'a> + Default> Parse2<'b, 'a, C> for T {
175 type I = T;
176 fn parse2(
177 i: Init<C, Self::I>,
178 k: &'static str,
179 c: &C,
180 p: &mut ParsedArgs<'a>,
181 ) -> Result<Self, ArgParseErr<'a>> {
182 match p.consume(k) {
183 Some(args) => {
184 if args.len() != 1 {
185 Err(Parse2Err::ExpectedOne)?
186 } else {
187 Ok(T::parse(&args[0])?)
188 }
189 }
190 None => Ok(i.get(c).ok_or(Parse2Err::Rquired)?),
191 }
192 }
193
194 fn desc2(i: Init<C, Self>, d: &'static str, k: &'static str, c: &C) -> [String; 4] {
195 [
196 k.into(),
197 format!("Req<{}>", T::desc()),
198 d.into(),
199 i.to_string(c),
200 ]
201 }
202 fn default2(c: &C, i: Init<C, Self::I>) -> Self {
203 i.get(c).unwrap_or(Self::default())
204 }
205}
206
207impl<'a, 'b, Ctx, T: Parse<'a>> Parse2<'b, 'a, Ctx> for Option<T> {
208 type I = T;
209 fn parse2(
210 i: Init<Ctx, T>,
211 k: &'static str,
212 c: &Ctx,
213 p: &mut ParsedArgs<'a>,
214 ) -> Result<Self, ArgParseErr<'a>> {
215 match p.consume(k) {
216 Some(args) => {
217 if args.len() != 1 {
218 Err(Parse2Err::ExpectedOne)?
219 } else {
220 Ok(Some(T::parse(&args[0])?))
221 }
222 }
223 None => Ok(match i.get(c) {
224 Some(e) => Some(e),
225 None => None,
226 }),
227 }
228 }
229 fn desc2(i: Init<Ctx, T>, d: &'static str, k: &'static str, c: &Ctx) -> [String; 4] {
230 [
231 k.into(),
232 format!("Opt<{}>", T::desc()),
233 d.into(),
234 i.to_string(c),
235 ]
236 }
237 fn default2(c: &Ctx, i: Init<Ctx, Self::I>) -> Self {
238 match i.get(c) {
239 Some(i) => Some(i),
240 None => None,
241 }
242 }
243}
244
245impl<'a, 'b, Ctx, T: Parse<'a> + Display> Parse2<'b, 'a, Ctx> for Vec<T> {
246 type I = DisplayVec<T>;
247 fn parse2(
248 i: Init<Ctx, Self::I>,
249 k: &'static str,
250 c: &Ctx,
251 p: &mut ParsedArgs<'a>,
252 ) -> Result<Self, ArgParseErr<'a>> {
253 match p.consume(k) {
254 Some(args) => {
255 let args = args
256 .iter()
257 .map(|a| T::parse(a))
258 .collect::<Result<Vec<_>, _>>()?;
259 if args.is_empty() {
260 Err(Parse2Err::ExpectedAtLeastOne)?
261 }
262 Ok(args)
263 }
264 None => Ok(match i.get(c) {
265 Some(e) => e.into(),
266 None => vec![],
267 }),
268 }
269 }
270
271 fn desc2(i: Init<Ctx, Self::I>, d: &'static str, k: &'static str, c: &Ctx) -> [String; 4] {
272 [
273 k.into(),
274 format!("Vec<{}>", T::desc()),
275 d.into(),
276 i.to_string(c),
277 ]
278 }
279 fn default2(c: &Ctx, i: Init<Ctx, Self::I>) -> Self {
280 match i.get(c) {
281 Some(v) => v.0,
282 None => Self::default(),
283 }
284 }
285}
286
287#[derive(Debug)]
288pub struct OptVec<T: Display>(pub Vec<T>);
289impl<T: Display> From<Vec<T>> for OptVec<T> {
290 fn from(v: Vec<T>) -> Self {
291 Self(v)
292 }
293}
294impl<T: Display> From<DisplayVec<T>> for OptVec<T> {
295 fn from(v: DisplayVec<T>) -> Self {
296 Self(v.0)
297 }
298}
299impl<'a, 'b, Ctx, T: Parse<'a>> Parse2<'b, 'a, Ctx> for OptVec<T> {
300 type I = DisplayVec<T>;
301 fn parse2(
302 i: Init<Ctx, Self::I>,
303 k: &'static str,
304 c: &Ctx,
305 p: &mut ParsedArgs<'a>,
306 ) -> Result<Self, ArgParseErr<'a>> {
307 match p.consume(k) {
308 Some(args) => {
309 let args = args
310 .iter()
311 .map(|a| T::parse(a))
312 .collect::<Result<Vec<_>, _>>()?;
313 Ok(args.into())
314 }
315 None => Ok(match i.get(c) {
316 Some(e) => e.into(),
317 None => vec![].into(),
318 }),
319 }
320 }
321
322 fn desc2(i: Init<Ctx, Self::I>, d: &'static str, k: &'static str, c: &Ctx) -> [String; 4] {
323 [
324 k.into(),
325 format!("Vec<{}>", T::desc()),
326 d.into(),
327 i.to_string(c),
328 ]
329 }
330 fn default2(c: &Ctx, i: Init<Ctx, Self::I>) -> Self {
331 Self::from(match i.get(c) {
332 Some(v) => v.0,
333 None => <Vec<T>>::default(),
334 })
335 }
336}
337impl Display for DirExist {
338 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
339 write!(f, "{}", self.s)
340 }
341}
342impl Display for FileExist {
343 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
344 write!(f, "{}", self.s)
345 }
346}