use core::convert::Infallible;
use crate::{
extensions::{Extensions, ExtensionsRef},
matcher::Matcher,
};
use super::{ServiceMatch, ServiceMatcher};
#[derive(Debug, Clone)]
pub struct MatcherServicePair<M, S>(pub M, pub S);
impl<M, S> MatcherServicePair<M, S> {
#[inline]
pub fn new(matcher: M, service: S) -> Self {
Self(matcher, service)
}
}
impl<M, S> From<(M, S)> for MatcherServicePair<M, S> {
fn from(value: (M, S)) -> Self {
Self(value.0, value.1)
}
}
impl<Input, M, S> ServiceMatcher<Input> for MatcherServicePair<M, S>
where
Input: Send + ExtensionsRef + 'static,
S: Send + Sync + Clone + 'static,
M: Matcher<Input>,
{
type Service = S;
type Error = Infallible;
type ModifiedInput = Input;
async fn match_service(
&self,
input: Input,
) -> Result<ServiceMatch<Input, Self::Service>, Self::Error> {
let Self(matcher, service) = self;
let ext = Extensions::new();
if matcher.matches(Some(&ext), &input) {
input.extensions().extend(&ext);
Ok(ServiceMatch {
input,
service: Some(service.clone()),
})
} else {
Ok(ServiceMatch {
input,
service: None,
})
}
}
async fn into_match_service(
self,
input: Input,
) -> Result<ServiceMatch<Input, Self::Service>, Self::Error>
where
Input: Send,
{
let Self(matcher, service) = self;
let ext = Extensions::new();
if matcher.matches(Some(&ext), &input) {
input.extensions().extend(&ext);
Ok(ServiceMatch {
input,
service: Some(service),
})
} else {
Ok(ServiceMatch {
input,
service: None,
})
}
}
}