path2regex/matcher/
builder.rs

1//! The Builder of the [`Matcher`](struct.Matcher.html)
2use anyhow::Result;
3
4use crate::{
5    internal::{type_of, FnStr, FnStrWithKey},
6    try_into_with::TryIntoWith,
7    Matcher, PathRegex, PathRegexOptions,
8};
9
10/// The Configuration of the [`Matcher`](struct.Matcher.html)
11#[derive(Clone)]
12pub struct MatcherOptions {
13    /// Set the default delimiter for repeat parameters. (default: `'/#?'`)
14    pub delimiter: String,
15    /// List of characters to automatically consider prefixes when parsing.
16    pub prefixes: String,
17    /// When `true` the regexp will be case sensitive. (default: `false`)
18    pub sensitive: bool,
19    /// When `true` the regexp won't allow an optional trailing delimiter to match. (default: `false`)
20    pub strict: bool,
21    /// When `true` the regexp will match to the end of the string. (default: `true`)
22    pub end: bool,
23    /// When `true` the regexp will match from the beginning of the string. (default: `true`)
24    pub start: bool,
25    /// List of characters that can also be "end" characters.
26    pub ends_with: String,
27    /// Encode path tokens for use in the `Regex`.
28    pub encode: FnStr,
29    /// Function for decoding strings for params.
30    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
81/// The Builder of the [`Matcher`](struct.Matcher.html)
82pub struct MatcherBuilder<I> {
83    source: I,
84    options: MatcherOptions,
85}
86
87impl<I> MatcherBuilder<I>
88where
89    I: TryIntoWith<PathRegex, PathRegexOptions>,
90{
91    /// Create a builder of the [`Matcher`](struct.Matcher.html)
92    pub fn new(source: I) -> Self {
93        Self {
94            source,
95            options: Default::default(),
96        }
97    }
98
99    /// Create a builder of the [`Matcher`](struct.Matcher.html) with the options
100    pub fn new_with_options(source: I, options: MatcherOptions) -> Self {
101        Self { source, options }
102    }
103
104    /// build a builder of the [`Matcher`](struct.Matcher.html)
105    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    /// List of characters to automatically consider prefixes when parsing.
121    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    /// When `true` the regexp will be case sensitive. (default: `false`)
127    pub fn set_sensitive(&mut self, yes: bool) -> &mut Self {
128        self.options.sensitive = yes;
129        self
130    }
131
132    /// When `true` the regexp won't allow an optional trailing delimiter to match. (default: `false`)
133    pub fn set_strict(&mut self, yes: bool) -> &mut Self {
134        self.options.strict = yes;
135        self
136    }
137
138    /// When `true` the regexp will match to the end of the string. (default: `true`)
139    pub fn set_end(&mut self, yes: bool) -> &mut Self {
140        self.options.end = yes;
141        self
142    }
143
144    /// When `true` the regexp will match from the beginning of the string. (default: `true`)
145    pub fn set_start(&mut self, yes: bool) -> &mut Self {
146        self.options.start = yes;
147        self
148    }
149
150    /// Set the default delimiter for repeat parameters. (default: `'/'`)
151    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    /// List of characters that can also be "end" characters.
157    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    /// Function for encoding input strings for output.
163    pub fn set_encode(&mut self, encode: FnStr) -> &mut Self {
164        self.options.encode = encode;
165        self
166    }
167
168    /// Function for decoding strings for params.
169    pub fn set_decode(&mut self, decode: FnStrWithKey) -> &mut Self {
170        self.options.decode = decode;
171        self
172    }
173}