goodrouter/template/
template_pairs.rs

1use super::template_parts::{parse_template_parts, TemplateParts};
2use regex::Regex;
3
4pub fn parse_template_pairs<'r>(template: &'r str, re: &'r Regex) -> TemplatePairs<'r> {
5    TemplatePairs::new(template, re)
6}
7
8pub struct TemplatePairs<'r> {
9    parts: TemplateParts<'r>,
10    index: usize,
11    is_finished: bool,
12}
13
14impl<'r> TemplatePairs<'r> {
15    fn new(template: &'r str, re: &'r Regex) -> Self {
16        let parts = parse_template_parts(template, re);
17        let index = 0;
18        let is_finished = false;
19
20        Self {
21            parts,
22            index,
23            is_finished,
24        }
25    }
26}
27
28impl<'r> Iterator for TemplatePairs<'r> {
29    type Item = (&'r str, Option<&'r str>);
30
31    fn next(&mut self) -> Option<Self::Item> {
32        if self.is_finished {
33            return None;
34        }
35
36        let result = if let Some(part) = self.parts.next() {
37            if self.index == 0 {
38                Some((part, None))
39            } else {
40                let anchor = self.parts.next().unwrap();
41                Some((anchor, Some(part)))
42            }
43        } else {
44            None
45        };
46
47        self.index += 1;
48
49        if result.is_none() {
50            self.is_finished = true;
51        }
52
53        result
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::super::TEMPLATE_PLACEHOLDER_REGEX;
60    use super::*;
61
62    #[test]
63    fn parse_template_pairs_test() {
64        let pairs: Vec<_> =
65            parse_template_pairs("/a/{b}/{c}", &TEMPLATE_PLACEHOLDER_REGEX).collect();
66
67        assert_eq!(
68            pairs,
69            vec![("/a/", None), ("/", Some("b")), ("", Some("c"))]
70        );
71
72        let pairs: Vec<_> =
73            parse_template_pairs("/a/{b}/{c}/", &TEMPLATE_PLACEHOLDER_REGEX).collect();
74
75        assert_eq!(
76            pairs,
77            vec![("/a/", None), ("/", Some("b")), ("/", Some("c"))]
78        );
79
80        let pairs: Vec<_> = parse_template_pairs("", &TEMPLATE_PLACEHOLDER_REGEX).collect();
81
82        assert_eq!(pairs, vec![("", None)])
83    }
84}