use crate::context::Extensions;
use crate::{Context, matcher::Matcher};
use std::marker::PhantomData;
pub fn match_fn<F, A>(f: F) -> MatchFnBox<F, A> {
MatchFnBox {
f,
_marker: PhantomData,
}
}
pub trait MatchFn<S, Request, A>: private::Sealed<S, Request, A> + Send + Sync + 'static {}
impl<F, S, Request> MatchFn<S, Request, ()> for F where F: Fn() -> bool + Send + Sync + 'static {}
impl<F, S, Request> MatchFn<S, Request, (Request,)> for F where
F: Fn(&Request) -> bool + Send + Sync + 'static
{
}
impl<F, S, Request> MatchFn<S, Request, (Context<S>, Request)> for F where
F: Fn(&Context<S>, &Request) -> bool + Send + Sync + 'static
{
}
impl<F, S, Request> MatchFn<S, Request, (Option<&mut Extensions>, Context<S>, Request)> for F where
F: Fn(Option<&mut Extensions>, &Context<S>, &Request) -> bool + Send + Sync + 'static
{
}
impl<F, S, Request> MatchFn<S, Request, ((), (), Option<&mut Extensions>, Request)> for F where
F: Fn(Option<&mut Extensions>, &Request) -> bool + Send + Sync + 'static
{
}
impl<F, S, Request> MatchFn<S, Request, ((), (), (), (), Option<&mut Extensions>)> for F where
F: Fn(Option<&mut Extensions>) -> bool + Send + Sync + 'static
{
}
impl<F, S, Request> MatchFn<S, Request, ((), (), (), (), (), Context<S>)> for F where
F: Fn(&Context<S>) -> bool + Send + Sync + 'static
{
}
impl<F, S, Request>
MatchFn<S, Request, ((), (), (), (), (), (), Option<&mut Extensions>, Context<S>)> for F
where
F: Fn(Option<&mut Extensions>, &Context<S>) -> bool + Send + Sync + 'static,
{
}
pub struct MatchFnBox<F, A> {
f: F,
_marker: PhantomData<fn(A) -> ()>,
}
impl<F, A> Clone for MatchFnBox<F, A>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_marker: PhantomData,
}
}
}
impl<F, A> std::fmt::Debug for MatchFnBox<F, A> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MatchFnBox").finish()
}
}
impl<F, S, Request, A> Matcher<S, Request> for MatchFnBox<F, A>
where
A: Send + 'static,
F: MatchFn<S, Request, A>,
{
fn matches(&self, ext: Option<&mut Extensions>, ctx: &Context<S>, req: &Request) -> bool {
self.f.call(ext, ctx, req)
}
}
mod private {
use super::*;
pub trait Sealed<S, Request, A> {
fn call(&self, ext: Option<&mut Extensions>, ctx: &Context<S>, req: &Request) -> bool;
}
impl<F, S, Request> Sealed<S, Request, ()> for F
where
F: Fn() -> bool + Send + Sync + 'static,
{
fn call(&self, _ext: Option<&mut Extensions>, _ctx: &Context<S>, _req: &Request) -> bool {
(self)()
}
}
impl<F, S, Request> Sealed<S, Request, (Request,)> for F
where
F: Fn(&Request) -> bool + Send + Sync + 'static,
{
fn call(&self, _ext: Option<&mut Extensions>, _ctx: &Context<S>, req: &Request) -> bool {
(self)(req)
}
}
impl<F, S, Request> Sealed<S, Request, (Context<S>, Request)> for F
where
F: Fn(&Context<S>, &Request) -> bool + Send + Sync + 'static,
{
fn call(&self, _ext: Option<&mut Extensions>, ctx: &Context<S>, req: &Request) -> bool {
(self)(ctx, req)
}
}
impl<F, S, Request> Sealed<S, Request, (Option<&mut Extensions>, Context<S>, Request)> for F
where
F: Fn(Option<&mut Extensions>, &Context<S>, &Request) -> bool + Send + Sync + 'static,
{
fn call(&self, ext: Option<&mut Extensions>, ctx: &Context<S>, req: &Request) -> bool {
(self)(ext, ctx, req)
}
}
impl<F, S, Request> Sealed<S, Request, ((), (), Option<&mut Extensions>, Request)> for F
where
F: Fn(Option<&mut Extensions>, &Request) -> bool + Send + Sync + 'static,
{
fn call(&self, ext: Option<&mut Extensions>, _ctx: &Context<S>, req: &Request) -> bool {
(self)(ext, req)
}
}
impl<F, S, Request> Sealed<S, Request, ((), (), (), (), Option<&mut Extensions>)> for F
where
F: Fn(Option<&mut Extensions>) -> bool + Send + Sync + 'static,
{
fn call(&self, ext: Option<&mut Extensions>, _ctx: &Context<S>, _req: &Request) -> bool {
(self)(ext)
}
}
impl<F, S, Request> Sealed<S, Request, ((), (), (), (), (), Context<S>)> for F
where
F: Fn(&Context<S>) -> bool + Send + Sync + 'static,
{
fn call(&self, _ext: Option<&mut Extensions>, ctx: &Context<S>, _req: &Request) -> bool {
(self)(ctx)
}
}
impl<F, S, Request>
Sealed<S, Request, ((), (), (), (), (), (), Option<&mut Extensions>, Context<S>)> for F
where
F: Fn(Option<&mut Extensions>, &Context<S>) -> bool + Send + Sync + 'static,
{
fn call(&self, ext: Option<&mut Extensions>, ctx: &Context<S>, _req: &Request) -> bool {
(self)(ext, ctx)
}
}
}