elm_parser/counter/
counter_types.rs

1use numerals::roman::Roman;
2
3#[derive(Debug, Clone)]
4pub enum CounterType {
5    ARABIC,
6    ROMAN,
7    ALPHABITICAL,
8}
9
10#[derive(Debug, Clone)]
11pub enum CounterValueType {
12    ARABIC(isize),
13    ROMAN(String),
14    ALPHABITICAL(String),
15}
16
17impl CounterType {
18    pub fn is_valid(string: &str) -> bool {
19        string == "counter" || string == "roman_counter" || string == "alphabitical_counter"
20    }
21
22    pub fn from_str(string: &str) -> Option<Self> {
23        match string {
24            "counter" => Some(Self::ARABIC),
25            "roman_counter" => Some(Self::ROMAN),
26            "alphabitical_counter" => Some(Self::ALPHABITICAL),
27            _ => None,
28        }
29    }
30}
31
32impl CounterValueType {
33    fn is_valid(&self, value: &str) -> bool {
34        match self {
35            CounterValueType::ARABIC(_) => value.parse::<isize>().is_ok(),
36            CounterValueType::ROMAN(roman) => {
37                let roman = Roman::parse(roman);
38                roman.is_some()
39            }
40            CounterValueType::ALPHABITICAL(alpha) => alpha.chars().all(|c| {
41                let code_point = c as u32;
42                code_point >= 65
43            }),
44        }
45    }
46
47    fn default_value(&self, value: Option<&str>) -> Self {
48        match self {
49            CounterValueType::ARABIC(_) => {
50                if let Some(value) = value {
51                    if CounterValueType::ARABIC(0).is_valid(value) {
52                        Self::ARABIC(value.parse::<isize>().unwrap())
53                    } else {
54                        panic!("Wrong Arabic counter value")
55                    }
56                } else {
57                    Self::ARABIC(0)
58                }
59            }
60            CounterValueType::ROMAN(_) => {
61                if let Some(default_value) = value {
62                    if CounterValueType::ROMAN("".to_string()).is_valid(default_value) {
63                        Self::ROMAN(default_value.to_string())
64                    } else {
65                        panic!("Wrong Roman counter value")
66                    }
67                } else {
68                    Self::ROMAN("0".to_string())
69                }
70            }
71            CounterValueType::ALPHABITICAL(_) => {
72                if let Some(default_value) = value {
73                    if CounterValueType::ALPHABITICAL("".to_string()).is_valid(default_value) {
74                        Self::ALPHABITICAL(default_value.to_string())
75                    } else {
76                        panic!("Wrong Aphabitical counter value")
77                    }
78                } else {
79                    Self::ALPHABITICAL("0".to_string())
80                }
81            }
82        }
83    }
84
85    pub fn from_str(string: &str, default_value: Option<&str>) -> Self {
86        match string {
87            "counter" => CounterValueType::ARABIC(0).default_value(default_value),
88            "roman_counter" => CounterValueType::ROMAN("".to_string()).default_value(default_value),
89            "alphabitical_counter" => {
90                CounterValueType::ALPHABITICAL("".to_string()).default_value(default_value)
91            }
92            _ => Self::ARABIC(0),
93        }
94    }
95
96    pub fn from_type(counter_type: &CounterType, default_value: Option<&str>) -> Self {
97        match counter_type {
98            CounterType::ARABIC => CounterValueType::ARABIC(0).default_value(default_value),
99            CounterType::ROMAN => {
100                CounterValueType::ROMAN("".to_string()).default_value(default_value)
101            }
102            CounterType::ALPHABITICAL => {
103                CounterValueType::ALPHABITICAL("".to_string()).default_value(default_value)
104            }
105        }
106    }
107
108    pub fn to_string(&self) -> String {
109        match self {
110            CounterValueType::ARABIC(number) => {
111                if *number < 0 {
112                    "-".to_string()
113                } else {
114                    number.to_string()
115                }
116            }
117            CounterValueType::ROMAN(roman) => roman.to_string(),
118            CounterValueType::ALPHABITICAL(string) => string.to_string(),
119        }
120    }
121}