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
use super::*;

pub trait FilterFn {
    type Input;
    type Output;
    /// Map the given `input` item into an output item.
    fn map(&self, input: Self::Input) -> Option<Self::Output>;
}

pub struct FilterWrap<F: FilterFn>(pub F);

impl<F: FilterFn> FlatMapFn for FilterWrap<F> {
    type Input = F::Input;
    type OutputList = Option<F::Output>;
    fn map(&self, input: Self::Input) -> Self::OutputList {
        self.0.map(input)
    }
}

pub trait Filter: ListFn {
    fn filter<F: FilterFn<Input = Self::Item>>(self, f: F) -> FlatMapList<Self, FilterWrap<F>> {
        self.flat_map(FilterWrap(f))
    }
}

impl<L: ListFn> Filter for L {}