type_cli/
args.rs

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);