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}
81impl<'a> Display for ArgsErr<'a> {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 use ArgsErr::*;
84 let e = match self {
85 Run(e) => e.to_string(),
86 Parse(e) => e.to_string(),
87 };
88 write!(f, "{e}")
89 }
90}
91
92pub const PFX: &'static str = "--";
93#[derive(Debug)]
94pub struct Key<'a> {
95 pub k: Option<&'a str>,
96 pub v: Vec<&'a str>,
97 pub used: bool,
98}
99#[derive(Debug)]
100pub struct ParsedArgs<'c> {
101 pub k: Vec<Key<'c>>,
102}
103
104impl<'c> ParsedArgs<'c> {
105 pub fn consume(&mut self, name: &str) -> Option<&Vec<&'c str>> {
106 let k = self
107 .k
108 .iter_mut()
109 .find(|k| k.k.map(|k| k == name).unwrap_or(false))?;
110 assert!(
111 !k.used,
112 "A token should not ever be consumed twice. Probably a duplicate argument: {name}"
113 );
114 k.used = true;
115 Some(&k.v)
116 }
117}
118
119pub enum ParsedArgsErr<'a> {
120 UnexpectedToken(Arg<'a>),
121}
122impl<'c> ParsedArgs<'c> {
123 pub fn new(args: &[&'c str]) -> Result<ParsedArgs<'c>, ParsedArgsErr<'c>> {
124 let mut last: Option<&str> = None;
125 let r = ParsedArgs {
126 k: args
127 .iter()
128 .filter_map(|a| {
129 if a.starts_with(PFX) {
130 last = Some(a);
131 None
132 } else {
133 Some((last, *a))
134 }
135 })
136 .into_group_map()
137 .into_iter()
138 .map(|(k, v)| Key { k, v, used: false })
139 .collect(),
140 };
141
142 Ok(r)
143 }
144}
145
146pub enum Init<C, T: Display> {
147 None,
148 Const(T),
149 Dyn(fn(&C) -> T),
150}
151
152impl<C, T: Display> Init<C, T> {
153 pub fn get(self, c: &C) -> Option<T> {
154 match self {
155 Init::None => None,
156 Init::Const(v) => Some(v),
157 Init::Dyn(f) => Some(f(&c)),
158 }
159 }
160 fn to_string(self, c: &C) -> String {
161 match self.get(c) {
162 Some(s) => format!(" (default: {s})"),
163 None => format!(""),
164 }
165 }
166}
167
168pub trait Parse2<'a, 'b, C>
169where
170 Self: Sized,
171 Self::I: Display,
172{
173 type I;
174 fn parse2(
175 i: Init<C, Self::I>,
176 k: &'static str,
177 c: &C,
178 p: &mut ParsedArgs<'b>,
179 ) -> Result<Self, ArgParseErr<'b>>;
180 fn desc2(i: Init<C, Self::I>, d: &'static str, k: &'static str, c: &C) -> [String; 4];
181 fn default2(c: &C, i: Init<C, Self::I>) -> Self;
182}
183
184impl<'a, 'b, C, T: Parse<'a> + Default> Parse2<'b, 'a, C> for T {
185 type I = T;
186 fn parse2(
187 i: Init<C, Self::I>,
188 k: &'static str,
189 c: &C,
190 p: &mut ParsedArgs<'a>,
191 ) -> Result<Self, ArgParseErr<'a>> {
192 match p.consume(k) {
193 Some(args) => {
194 if args.len() != 1 {
195 Err(Parse2Err::ExpectedOne)?
196 } else {
197 Ok(T::parse(&args[0])?)
198 }
199 }
200 None => Ok(i.get(c).ok_or(Parse2Err::Rquired)?),
201 }
202 }
203
204 fn desc2(i: Init<C, Self>, d: &'static str, k: &'static str, c: &C) -> [String; 4] {
205 [
206 k.into(),
207 format!("Req<{}>", T::desc()),
208 d.into(),
209 i.to_string(c),
210 ]
211 }
212 fn default2(c: &C, i: Init<C, Self::I>) -> Self {
213 i.get(c).unwrap_or(Self::default())
214 }
215}
216
217impl<'a, 'b, Ctx, T: Parse<'a>> Parse2<'b, 'a, Ctx> for Option<T> {
218 type I = T;
219 fn parse2(
220 i: Init<Ctx, T>,
221 k: &'static str,
222 c: &Ctx,
223 p: &mut ParsedArgs<'a>,
224 ) -> Result<Self, ArgParseErr<'a>> {
225 match p.consume(k) {
226 Some(args) => {
227 if args.len() != 1 {
228 Err(Parse2Err::ExpectedOne)?
229 } else {
230 Ok(Some(T::parse(&args[0])?))
231 }
232 }
233 None => Ok(match i.get(c) {
234 Some(e) => Some(e),
235 None => None,
236 }),
237 }
238 }
239 fn desc2(i: Init<Ctx, T>, d: &'static str, k: &'static str, c: &Ctx) -> [String; 4] {
240 [
241 k.into(),
242 format!("Opt<{}>", T::desc()),
243 d.into(),
244 i.to_string(c),
245 ]
246 }
247 fn default2(c: &Ctx, i: Init<Ctx, Self::I>) -> Self {
248 match i.get(c) {
249 Some(i) => Some(i),
250 None => None,
251 }
252 }
253}
254
255impl<'a, 'b, Ctx, T: Parse<'a> + Display> Parse2<'b, 'a, Ctx> for Vec<T> {
256 type I = DisplayVec<T>;
257 fn parse2(
258 i: Init<Ctx, Self::I>,
259 k: &'static str,
260 c: &Ctx,
261 p: &mut ParsedArgs<'a>,
262 ) -> Result<Self, ArgParseErr<'a>> {
263 match p.consume(k) {
264 Some(args) => {
265 let args = args
266 .iter()
267 .map(|a| T::parse(a))
268 .collect::<Result<Vec<_>, _>>()?;
269 if args.is_empty() {
270 Err(Parse2Err::ExpectedAtLeastOne)?
271 }
272 Ok(args)
273 }
274 None => Ok(match i.get(c) {
275 Some(e) => e.into(),
276 None => vec![],
277 }),
278 }
279 }
280
281 fn desc2(i: Init<Ctx, Self::I>, d: &'static str, k: &'static str, c: &Ctx) -> [String; 4] {
282 [
283 k.into(),
284 format!("Vec<{}>", T::desc()),
285 d.into(),
286 i.to_string(c),
287 ]
288 }
289 fn default2(c: &Ctx, i: Init<Ctx, Self::I>) -> Self {
290 match i.get(c) {
291 Some(v) => v.0,
292 None => Self::default(),
293 }
294 }
295}
296
297#[derive(Debug)]
298pub struct OptVec<T: Display>(pub Vec<T>);
299impl<T: Display> From<Vec<T>> for OptVec<T> {
300 fn from(v: Vec<T>) -> Self {
301 Self(v)
302 }
303}
304impl<T: Display> From<DisplayVec<T>> for OptVec<T> {
305 fn from(v: DisplayVec<T>) -> Self {
306 Self(v.0)
307 }
308}
309impl<'a, 'b, Ctx, T: Parse<'a>> Parse2<'b, 'a, Ctx> for OptVec<T> {
310 type I = DisplayVec<T>;
311 fn parse2(
312 i: Init<Ctx, Self::I>,
313 k: &'static str,
314 c: &Ctx,
315 p: &mut ParsedArgs<'a>,
316 ) -> Result<Self, ArgParseErr<'a>> {
317 match p.consume(k) {
318 Some(args) => {
319 let args = args
320 .iter()
321 .map(|a| T::parse(a))
322 .collect::<Result<Vec<_>, _>>()?;
323 Ok(args.into())
324 }
325 None => Ok(match i.get(c) {
326 Some(e) => e.into(),
327 None => vec![].into(),
328 }),
329 }
330 }
331
332 fn desc2(i: Init<Ctx, Self::I>, d: &'static str, k: &'static str, c: &Ctx) -> [String; 4] {
333 [
334 k.into(),
335 format!("Vec<{}>", T::desc()),
336 d.into(),
337 i.to_string(c),
338 ]
339 }
340 fn default2(c: &Ctx, i: Init<Ctx, Self::I>) -> Self {
341 Self::from(match i.get(c) {
342 Some(v) => v.0,
343 None => <Vec<T>>::default(),
344 })
345 }
346}
347impl Display for DirExist {
348 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
349 write!(f, "{}", self.s)
350 }
351}
352impl Display for FileExist {
353 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
354 write!(f, "{}", self.s)
355 }
356}