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}