satex_matcher/
path.rs

1#![doc = include_str!("../docs/path.md")]
2
3use crate::make::MakeRouteMatcher;
4use crate::RouteMatcher;
5use async_trait::async_trait;
6use http::request::Parts;
7use matchit::Router;
8use satex_core::component::{Args, Configurable};
9use satex_core::extension::insert_url_params;
10use satex_core::util::With;
11use satex_core::Error;
12use satex_macro::make;
13
14#[make(kind = Path, shortcut_mode = Sequence)]
15struct MakePathRouteMatcher {
16    patterns: Vec<String>,
17}
18
19impl MakeRouteMatcher for MakePathRouteMatcher {
20    type Matcher = PathRouteMatcher;
21
22    fn make(&self, args: Args) -> Result<Self::Matcher, Error> {
23        Config::with_args(args)
24            .map_err(Error::new)
25            .and_then(|config| PathRouteMatcher::new(config.patterns))
26    }
27}
28
29pub struct PathRouteMatcher {
30    router: Router<()>,
31}
32
33impl PathRouteMatcher {
34    pub fn new<T: AsRef<str>, I: IntoIterator<Item = T>>(iter: I) -> Result<Self, Error> {
35        iter.into_iter()
36            .try_fold(Router::new(), |router, pattern| {
37                router.try_with(|router| router.insert(pattern.as_ref(), ()))
38            })
39            .map_err(Error::new)
40            .map(|router| PathRouteMatcher { router })
41    }
42}
43
44#[async_trait]
45impl RouteMatcher for PathRouteMatcher {
46    async fn matches(&self, parts: &mut Parts) -> Result<bool, Error> {
47        let path = parts.uri.path();
48        match self.router.at(path) {
49            Ok(m) => {
50                insert_url_params(&mut parts.extensions, m.params);
51                Ok(true)
52            }
53            Err(_) => Ok(false),
54        }
55    }
56}