1use std::{convert::AsRef, str::FromStr};
2use super::{Error, ArgRef};
3use std::error::Error as StdError;
4
5pub trait Argument : Sized {
6 fn parse(arg: impl AsRef<str>, arg: ArgRef) -> Result<Self, Error>;
7}
8
9impl<T: FromStr> Argument for T
10where <T as FromStr>::Err : StdError + 'static
11{
12 fn parse(val: impl AsRef<str>, arg: ArgRef) -> Result<Self, Error> {
13 let val = val.as_ref();
14 T::from_str(val).map_err(|e| Error::Parse(arg, Box::new(e)))
15 }
16}
17
18
19pub trait OptionalArg : Sized {
20 fn parse(arg: impl AsRef<str>, arg: ArgRef) -> Result<Self, Error>;
21 fn default() -> Self;
22
23 fn map_parse(val: Option<impl AsRef<str>>, arg: ArgRef) -> Result<Self, Error> {
24 match val {
25 Some(val) => Self::parse(val, arg),
26 None => Ok(Self::default())
27 }
28 }
29}
30
31impl<T: Argument> OptionalArg for Option<T> {
32 fn parse(val: impl AsRef<str>, arg: ArgRef) -> Result<Self, Error> {
33 Some(T::parse(val, arg)).transpose()
34 }
35 fn default() -> Self {
36 None
37 }
38}
39
40
41pub trait Flag : Default {
42 fn increment(&mut self);
43}
44
45impl Flag for bool {
46 fn increment(&mut self) {
47 *self = true;
48 }
49}
50
51impl Flag for Option<()> {
52 fn increment(&mut self) {
53 *self = Some(());
54 }
55}
56
57macro_rules! int_flag {
58 ($int: ty) => {
59 impl $crate::Flag for $int {
60 fn increment(&mut self){
61 *self += 1;
62 }
63 }
64 }
65}
66
67int_flag!(usize);
68int_flag!(u8);
69int_flag!(u16);
70int_flag!(u32);
71int_flag!(u64);
72int_flag!(isize);
73int_flag!(i8);
74int_flag!(i16);
75int_flag!(i32);
76int_flag!(i64);