path2regex/matcher/
builder.rs1use anyhow::Result;
3
4use crate::{
5 internal::{type_of, FnStr, FnStrWithKey},
6 try_into_with::TryIntoWith,
7 Matcher, PathRegex, PathRegexOptions,
8};
9
10#[derive(Clone)]
12pub struct MatcherOptions {
13 pub delimiter: String,
15 pub prefixes: String,
17 pub sensitive: bool,
19 pub strict: bool,
21 pub end: bool,
23 pub start: bool,
25 pub ends_with: String,
27 pub encode: FnStr,
29 pub decode: FnStrWithKey,
31}
32
33impl Default for MatcherOptions {
34 fn default() -> Self {
35 let PathRegexOptions {
36 delimiter,
37 prefixes,
38 sensitive,
39 strict,
40 end,
41 start,
42 ends_with,
43 encode,
44 } = PathRegexOptions::default();
45 Self {
46 delimiter,
47 prefixes,
48 sensitive,
49 strict,
50 end,
51 start,
52 ends_with,
53 encode,
54 decode: |x, _| x.to_owned(),
55 }
56 }
57}
58
59impl std::fmt::Display for MatcherOptions {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 std::fmt::Debug::fmt(&self, f)
62 }
63}
64
65impl std::fmt::Debug for MatcherOptions {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 f.debug_struct("MatcherOptions")
68 .field("delimiter", &self.delimiter)
69 .field("prefixes", &self.prefixes)
70 .field("sensitive", &self.sensitive)
71 .field("strict", &self.strict)
72 .field("end", &self.end)
73 .field("start", &self.start)
74 .field("ends_with", &self.ends_with)
75 .field("encode", &type_of(self.encode))
76 .field("decode", &type_of(self.decode))
77 .finish()
78 }
79}
80
81pub struct MatcherBuilder<I> {
83 source: I,
84 options: MatcherOptions,
85}
86
87impl<I> MatcherBuilder<I>
88where
89 I: TryIntoWith<PathRegex, PathRegexOptions>,
90{
91 pub fn new(source: I) -> Self {
93 Self {
94 source,
95 options: Default::default(),
96 }
97 }
98
99 pub fn new_with_options(source: I, options: MatcherOptions) -> Self {
101 Self { source, options }
102 }
103
104 pub fn build(&self) -> Result<Matcher> {
106 let re = self
107 .source
108 .clone()
109 .try_into_with(&PathRegexOptions::from(self.options.clone()))?;
110
111 Ok(Matcher {
112 re: re.clone(),
113 keys: re.keys,
114 options: self.options.clone(),
115 })
116 }
117}
118
119impl<I> MatcherBuilder<I> {
120 pub fn set_prefixes(&mut self, prefixes: impl AsRef<str>) -> &mut Self {
122 self.options.prefixes = prefixes.as_ref().to_owned();
123 self
124 }
125
126 pub fn set_sensitive(&mut self, yes: bool) -> &mut Self {
128 self.options.sensitive = yes;
129 self
130 }
131
132 pub fn set_strict(&mut self, yes: bool) -> &mut Self {
134 self.options.strict = yes;
135 self
136 }
137
138 pub fn set_end(&mut self, yes: bool) -> &mut Self {
140 self.options.end = yes;
141 self
142 }
143
144 pub fn set_start(&mut self, yes: bool) -> &mut Self {
146 self.options.start = yes;
147 self
148 }
149
150 pub fn set_delimiter(&mut self, de: impl AsRef<str>) -> &mut Self {
152 self.options.delimiter = de.as_ref().to_owned();
153 self
154 }
155
156 pub fn set_ends_with(&mut self, end: impl AsRef<str>) -> &mut Self {
158 self.options.ends_with = end.as_ref().to_owned();
159 self
160 }
161
162 pub fn set_encode(&mut self, encode: FnStr) -> &mut Self {
164 self.options.encode = encode;
165 self
166 }
167
168 pub fn set_decode(&mut self, decode: FnStrWithKey) -> &mut Self {
170 self.options.decode = decode;
171 self
172 }
173}