json_web_tolkien/util/
one_or_more.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
6#[serde(untagged)]
7pub enum OneOrMore {
8 One(Box<str>),
9 More(Box<[Box<str>]>),
10}
11
12pub struct OneOrMoreIterator<'a> {
13 inner: &'a OneOrMore,
14 index: usize,
15}
16
17impl OneOrMore {
18 pub fn iter(&self) -> OneOrMoreIterator<'_> {
21 OneOrMoreIterator {
22 inner: self,
23 index: 0,
24 }
25 }
26}
27
28impl<'a> IntoIterator for &'a OneOrMore {
29 type Item = &'a str;
30 type IntoIter = OneOrMoreIterator<'a>;
31
32 fn into_iter(self) -> Self::IntoIter {
33 self.iter()
34 }
35}
36
37impl<'a> Iterator for OneOrMoreIterator<'a> {
38 type Item = &'a str;
39
40 fn next(&mut self) -> Option<Self::Item> {
41 let len: usize = match self.inner {
42 OneOrMore::One(_) => 1,
43 OneOrMore::More(list) => list.len(),
44 };
45
46 if self.index < len {
47 let result: Self::Item = match self.inner {
48 OneOrMore::One(one) => one,
49 OneOrMore::More(more) => (more[self.index]).as_ref(),
50 };
51
52 self.index += 1;
53
54 Some(result)
55 } else {
56 None
57 }
58 }
59}
60
61#[cfg(test)]
62mod test {
63 use super::*;
64
65 #[test]
66 fn it_will_match_any_against_one() {
67 let v1 = OneOrMore::One("one".into());
68 let v2 = {
69 let v: Box<[Box<str>]> = ["one".into(), "two".into()].into();
70
71 OneOrMore::More(v)
72 };
73
74 assert!(v1.iter().any(|x| x == "one"));
75 assert!(v2.iter().any(|x| x == "one"));
76 assert!(v2.iter().any(|x| x == "two"));
77 assert_eq!(v1.iter().any(|x| x == "two"), false);
78 }
79}