goodrouter/template/
template_pairs.rs1use 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}