1use std::any::type_name;
2use std::marker::PhantomData;
3use std::str::FromStr;
4
5use mddd_traits::IParser;
6
7#[derive(Default)]
8pub struct BoolParser;
9
10#[derive(Default)]
11pub struct FromStrParser<T> {
12 phantom: PhantomData<T>,
13}
14
15#[derive(Default)]
16pub struct StringParser;
17
18#[derive(Default)]
19pub struct OptParser<T> {
20 phantom: PhantomData<T>,
21}
22
23impl IParser<bool> for BoolParser {
24 fn parse(src: &str) -> Result<bool, String> {
25 const VARIANTS: &[(&str, bool)] = &[
26 ("1", true),
27 ("y", true),
28 ("t", true),
29 ("0", false),
30 ("n", false),
31 ("f", false),
32 ];
33 let param = src.to_lowercase();
34 for (var, val) in VARIANTS.iter() {
35 if *var == param {
36 return Ok(*val);
37 }
38 }
39 Err("not a bool value".to_string())
40 }
41}
42
43impl<T: FromStr + 'static> IParser<T> for FromStrParser<T> {
44 fn parse(src: &str) -> Result<T, String> {
45 if let Ok(val) = T::from_str(src) {
46 return Ok(val);
47 }
48 let msg = format!("expected type {}", type_name::<T>());
49 Err(msg)
50 }
51}
52
53impl<T: 'static, P: IParser<T>> IParser<Option<T>> for OptParser<P> {
54 fn parse(src: &str) -> Result<Option<T>, String> {
55 Ok(Some(P::parse(src)?))
56 }
57}
58
59impl IParser<String> for StringParser {
60 fn parse(src: &str) -> Result<String, String> {
61 Ok(src.to_string())
62 }
63}