1#![forbid(missing_docs, missing_debug_implementations)]
2
3type Stack<'a, T> = &'a mut Vec<T>;
6type Parser<N, T> = fn(Stack<T>) -> Option<N>;
7
8pub fn enum_parse<N, T>(f: fn(&T) -> Option<N>, stack: Stack<T>) -> Option<N> {
12 match stack.pop() {
13 Some(t) => match f(&t) {
14 Some(n) => Some(n),
15 None => {
16 stack.push(t);
17 None
18 }
19 },
20 None => None,
21 }
22}
23
24pub fn options_parse<N, T: Clone>(l: &[Parser<N, T>], stack: Stack<T>) -> Option<N> {
28 for p in l.iter() {
29 if let Some(n) = p(stack) {
30 return Some(n);
31 }
32 }
33 None
34}
35
36pub fn repeated_parse<N, T>(p: Parser<N, T>, stack: Stack<T>) -> Vec<N> {
38 let mut res: Vec<N> = Vec::new();
39 loop {
40 match p(stack) {
41 Some(s) => res.push(s),
42 None => return res,
43 };
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use crate::{enum_parse, options_parse, repeated_parse, Stack};
50
51 #[derive(Debug, PartialEq)]
52 enum Enum1 {
53 Even,
54 Odd,
55 Zero,
56 }
57
58 fn enum_parse_1(stack: Stack<i32>) -> Option<Enum1> {
59 enum_parse(
60 |&n| {
61 if n < 0 {
62 None
63 } else if n == 0 {
64 Some(Enum1::Zero)
65 } else if n % 2 == 0 {
66 Some(Enum1::Even)
67 } else {
68 Some(Enum1::Odd)
69 }
70 },
71 stack,
72 )
73 }
74
75 #[test]
76 fn enum_parse_1_ok() {
77 assert_eq!(enum_parse_1(&mut vec![-32, 25, 0]), Some(Enum1::Zero));
78 assert_eq!(enum_parse_1(&mut vec![-32, 25, 23]), Some(Enum1::Odd));
79 assert_eq!(enum_parse_1(&mut vec![-32, 25, 2]), Some(Enum1::Even));
80 }
81
82 #[test]
83 fn enum_parse_1_err() {
84 assert_eq!(enum_parse_1(&mut vec![-32, 25, -2]), None);
85 assert_eq!(enum_parse_1(&mut vec![]), None);
86 }
87
88 #[derive(Debug, PartialEq)]
89 enum Enum2 {
90 Small,
91 Tiny,
92 }
93
94 fn enum_parse_2(stack: Stack<i32>) -> Option<Enum2> {
95 enum_parse(
96 |&n| {
97 if n > -10 && n < 0 {
98 Some(Enum2::Small)
99 } else if n <= -10 {
100 Some(Enum2::Tiny)
101 } else {
102 None
103 }
104 },
105 stack,
106 )
107 }
108
109 #[test]
110 fn enum_parse_2_ok() {
111 assert_eq!(enum_parse_2(&mut vec![-32, 25, -5]), Some(Enum2::Small));
112 assert_eq!(enum_parse_2(&mut vec![-32, 25, -20]), Some(Enum2::Tiny));
113 }
114
115 #[test]
116 fn enum_parse_2_err() {
117 assert_eq!(enum_parse_2(&mut vec![-32, 25, 2]), None);
118 assert_eq!(enum_parse_2(&mut vec![]), None);
119 }
120
121 #[derive(Debug, PartialEq)]
122 enum Enum1And2 {
123 Is1(Enum1),
124 Is2(Enum2),
125 }
126
127 fn options_parse_1(stack: Stack<i32>) -> Option<Enum1And2> {
128 options_parse(
129 &[
130 |s| enum_parse_1(s).map(Enum1And2::Is1),
131 |s| enum_parse_2(s).map(Enum1And2::Is2),
132 ],
133 stack,
134 )
135 }
136
137 #[test]
138 fn options_parse_1_ok() {
139 assert_eq!(
140 options_parse_1(&mut vec![5]),
141 Some(Enum1And2::Is1(Enum1::Odd))
142 );
143 assert_eq!(
144 options_parse_1(&mut vec![0]),
145 Some(Enum1And2::Is1(Enum1::Zero))
146 );
147 assert_eq!(
148 options_parse_1(&mut vec![-1]),
149 Some(Enum1And2::Is2(Enum2::Small))
150 );
151 assert_eq!(
152 options_parse_1(&mut vec![-20]),
153 Some(Enum1And2::Is2(Enum2::Tiny))
154 );
155 }
156
157 fn repeated_parse_1(stack: Stack<i32>) -> Vec<Enum1> {
158 repeated_parse(enum_parse_1, stack)
159 }
160
161 #[test]
162 fn repeated_parse_1_ok() {
163 assert_eq!(
164 repeated_parse_1(&mut vec![-1, 3, 2, 1]),
165 vec![Enum1::Odd, Enum1::Even, Enum1::Odd]
166 );
167 assert_eq!(repeated_parse_1(&mut vec![]), vec![]);
168 assert_eq!(repeated_parse_1(&mut vec![-1]), vec![]);
169 }
170
171 fn repeated_parse_2(stack: Stack<i32>) -> Vec<Enum1And2> {
172 repeated_parse(options_parse_1, stack)
173 }
174
175 #[test]
176 fn repeated_parse_2_ok() {
177 assert_eq!(
178 repeated_parse_2(&mut vec![-1, 3, 2, 1]),
179 vec![
180 Enum1And2::Is1(Enum1::Odd),
181 Enum1And2::Is1(Enum1::Even),
182 Enum1And2::Is1(Enum1::Odd),
183 Enum1And2::Is2(Enum2::Small)
184 ]
185 );
186 }
187}