use anyhow::Result;
use crate::{
internal::{type_of, FnStr, FnStrWithKey},
try_into_with::TryIntoWith,
Matcher, PathRegex, PathRegexOptions,
};
#[derive(Clone)]
pub struct MatcherOptions {
pub delimiter: String,
pub prefixes: String,
pub sensitive: bool,
pub strict: bool,
pub end: bool,
pub start: bool,
pub ends_with: String,
pub encode: FnStr,
pub decode: FnStrWithKey,
}
impl Default for MatcherOptions {
fn default() -> Self {
let PathRegexOptions {
delimiter,
prefixes,
sensitive,
strict,
end,
start,
ends_with,
encode,
} = PathRegexOptions::default();
Self {
delimiter,
prefixes,
sensitive,
strict,
end,
start,
ends_with,
encode,
decode: |x, _| x.to_owned(),
}
}
}
impl std::fmt::Display for MatcherOptions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self, f)
}
}
impl std::fmt::Debug for MatcherOptions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MatcherOptions")
.field("delimiter", &self.delimiter)
.field("prefixes", &self.prefixes)
.field("sensitive", &self.sensitive)
.field("strict", &self.strict)
.field("end", &self.end)
.field("start", &self.start)
.field("ends_with", &self.ends_with)
.field("encode", &type_of(self.encode))
.field("decode", &type_of(self.decode))
.finish()
}
}
pub struct MatcherBuilder<I> {
source: I,
options: MatcherOptions,
}
impl<I> MatcherBuilder<I>
where
I: TryIntoWith<PathRegex, PathRegexOptions>,
{
pub fn new(source: I) -> Self {
Self {
source,
options: Default::default(),
}
}
pub fn new_with_options(source: I, options: MatcherOptions) -> Self {
Self { source, options }
}
pub fn build(&self) -> Result<Matcher> {
let re = self
.source
.clone()
.try_into_with(&PathRegexOptions::from(self.options.clone()))?;
Ok(Matcher {
re: re.clone(),
keys: re.keys,
options: self.options.clone(),
})
}
}
impl<I> MatcherBuilder<I> {
pub fn set_prefixes(&mut self, prefixes: impl AsRef<str>) -> &mut Self {
self.options.prefixes = prefixes.as_ref().to_owned();
self
}
pub fn set_sensitive(&mut self, yes: bool) -> &mut Self {
self.options.sensitive = yes;
self
}
pub fn set_strict(&mut self, yes: bool) -> &mut Self {
self.options.strict = yes;
self
}
pub fn set_end(&mut self, yes: bool) -> &mut Self {
self.options.end = yes;
self
}
pub fn set_start(&mut self, yes: bool) -> &mut Self {
self.options.start = yes;
self
}
pub fn set_delimiter(&mut self, de: impl AsRef<str>) -> &mut Self {
self.options.delimiter = de.as_ref().to_owned();
self
}
pub fn set_ends_with(&mut self, end: impl AsRef<str>) -> &mut Self {
self.options.ends_with = end.as_ref().to_owned();
self
}
pub fn set_encode(&mut self, encode: FnStr) -> &mut Self {
self.options.encode = encode;
self
}
pub fn set_decode(&mut self, decode: FnStrWithKey) -> &mut Self {
self.options.decode = decode;
self
}
}