1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use super::Filter;

pub trait WrapSealed<F: Filter> {
    type Wrapped: Filter;

    fn wrap(&self, filter: F) -> Self::Wrapped;
}

impl<'a, T, F> WrapSealed<F> for &'a T
where
    T: WrapSealed<F>,
    F: Filter,
{
    type Wrapped = T::Wrapped;
    fn wrap(&self, filter: F) -> Self::Wrapped {
        (*self).wrap(filter)
    }
}

pub trait Wrap<F: Filter>: WrapSealed<F> {}

impl<T, F> Wrap<F> for T
where
    T: WrapSealed<F>,
    F: Filter,
{
}

/// Function that receives a filter to be combined with pre and after filters
pub fn wrap_fn<F, T, U>(func: F) -> WrapFn<F>
where
    F: Fn(T) -> U,
    T: Filter,
    U: Filter,
{
    WrapFn { func }
}

#[derive(Debug)]
pub struct WrapFn<F> {
    func: F,
}

impl<F, T, U> WrapSealed<T> for WrapFn<F>
where
    F: Fn(T) -> U,
    T: Filter,
    U: Filter,
{
    type Wrapped = U;

    fn wrap(&self, filter: T) -> Self::Wrapped {
        (self.func)(filter)
    }
}