titan_router/
segment.rs

1#[derive(Debug, Hash, Clone, PartialEq, Eq)]
2pub(crate) enum Segment {
3  Slash,
4  Exact(String),
5  Param(String),
6}
7
8impl std::fmt::Display for Segment {
9  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10    match self {
11      Segment::Slash => f.write_str("/"),
12      Segment::Exact(string) => f.write_str(string),
13      Segment::Param(param) => f.write_str(format!(":{}", param).as_str()),
14    }
15  }
16}
17
18pub(crate) trait CompareSegment {
19  fn eq(&self, may_be_dynamic: &Self) -> CompareSegmentOut;
20}
21
22#[derive(Debug, PartialEq, Eq)]
23pub(crate) enum CompareSegmentOut {
24  NoMatch,
25  Match(Option<(String, String)>),
26}
27
28impl CompareSegment for Segment {
29  fn eq(&self, from_request: &Self) -> CompareSegmentOut {
30    match self {
31      Segment::Slash => {
32        if matches!(from_request, Segment::Slash) {
33          CompareSegmentOut::Match(None)
34        } else {
35          CompareSegmentOut::NoMatch
36        }
37      }
38
39      Segment::Exact(str) => match from_request {
40        Segment::Exact(str_contract) if str_contract == str => {
41          CompareSegmentOut::Match(None)
42        }
43
44        _ => CompareSegmentOut::NoMatch,
45      },
46      Segment::Param(param_name) => match from_request {
47        Segment::Exact(param_value) => CompareSegmentOut::Match(Some((
48          param_name.clone(),
49          param_value.clone(),
50        ))),
51        _ => CompareSegmentOut::NoMatch,
52      },
53    }
54  }
55}
56
57#[cfg(test)]
58mod testing {
59  use super::CompareSegmentOut;
60
61  use super::{CompareSegment, Segment};
62
63  #[test]
64  fn test_compare_segment_param_value() {
65    let contract = Segment::Param("variable".to_string());
66    let request = Segment::Exact("value".to_string());
67    let request2 = Segment::Slash;
68
69    assert_eq!(
70      CompareSegment::eq(&contract, &request),
71      CompareSegmentOut::Match(Some((
72        "variable".to_string(),
73        "value".to_string(),
74      )))
75    );
76
77    assert_eq!(
78      CompareSegment::eq(&contract, &request2),
79      CompareSegmentOut::NoMatch
80    );
81  }
82
83  #[test]
84  fn test_compare_segment_exact() {
85    let contract = Segment::Exact("value".to_string());
86    let request = Segment::Exact("value".to_string());
87
88    assert_eq!(
89      CompareSegment::eq(&contract, &request),
90      CompareSegmentOut::Match(None)
91    );
92
93    let contract = Segment::Exact("value1".to_string());
94    let request = Segment::Exact("value".to_string());
95
96    assert_eq!(
97      CompareSegment::eq(&contract, &request),
98      CompareSegmentOut::NoMatch,
99    );
100  }
101
102  #[test]
103  fn test_compare_segment_slash() {
104    let contract = Segment::Slash;
105    let request = Segment::Slash;
106
107    assert_eq!(
108      CompareSegment::eq(&contract, &request),
109      CompareSegmentOut::Match(None)
110    );
111
112    let request2 = Segment::Exact("something".to_string());
113
114    assert_eq!(
115      CompareSegment::eq(&contract, &request2),
116      CompareSegmentOut::NoMatch,
117    );
118  }
119}