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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use std::sync::Arc;
use std::fmt;
use std::any::type_name;

use crate::*;
use crate::any::*;
use crate::ops::function::*;

pub trait RawValueFilter: Value + Sync + Send {
    fn filter_raw(&self, value: Box<dyn Value>) -> Option<Box<dyn Value>>;

as_trait!(RawValueFilter);
as_boxed!(RawValueFilter);
}

boxed_value_trait!(RawValueFilter);

pub trait ValueFilter<V: ?Sized + ValueConstraint>: RawValueFilter {
    fn filter(&self, value: Box<V>) -> Option<Box<V>>;

as_boxed!(ValueFilter<V>);
}

boxed_value_trait!(ValueFilter<V: ?Sized + ValueConstraint>);

#[derive(Clone)]
pub struct DefaultValueFilter<V: ?Sized + ValueConstraint> {
    filter: Function<Box<V>, Option<Box<V>>>
}

impl<V: ?Sized + ValueConstraint> DefaultValueFilter<V> {
    pub fn new(filter: Box<dyn Fn(Box<V>) -> Option<Box<V>>>) -> Self {
        Self::wrap(Arc::new(filter))
    }

    pub fn wrap(filter: Arc<Box<dyn Fn(Box<V>) -> Option<Box<V>>>>) -> Self {
        Self {
            filter: filter
        }
    }
}

impl<V: ?Sized + ValueConstraint> ValueFilter<V>
    for DefaultValueFilter<V> {
    fn filter(&self, value: Box<V>) -> Option<Box<V>> {
        self.filter.as_ref()(value)
    }

as_boxed!(impl ValueFilter<V>);
}

impl<V: ?Sized + ValueConstraint> PartialEq for DefaultValueFilter<V> {
    fn eq(&self, other: &Self) -> bool {
        self.filter.as_ref().reference_equals(other.filter.as_ref())
    }
}

impl<V: ?Sized + ValueConstraint> Eq for DefaultValueFilter<V> { }

impl<V: ?Sized + ValueConstraint> fmt::Debug for DefaultValueFilter<V> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {{ filter: {} }}", type_name::<DefaultValueFilter<V>>(), self.filter.type_name())
    }
}

unsafe impl<V: ?Sized + ValueConstraint> Sync for DefaultValueFilter<V> { }
unsafe impl<V: ?Sized + ValueConstraint> Send for DefaultValueFilter<V> { }

impl<V: ?Sized + ValueConstraint> RawValueFilter for DefaultValueFilter<V> {
    fn filter_raw(&self, value: Box<dyn Value>) -> Option<Box<dyn Value>> {
        match value.as_ref().as_any_ref().downcast_ref::<V>() {
            Some(value) => self.filter.as_ref()(Box::new(value.clone())).map(|v|Value::clone_boxed(v.as_ref())),
            None => None
        }
    }

as_trait!(impl RawValueFilter);
as_boxed!(impl RawValueFilter);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn value_filter_test() {
        let filter = DefaultValueFilter::<i32>::new(Box::new(|v|{
            if *v > 10 { Some(v) } else { None }
        }));
        let v = filter.filter(Box::new(10));
        assert_eq!(None, v);
        let v = filter.filter(Box::new(11));
        assert_eq!(Box::new(11), v.unwrap());
        let v = RawValueFilter::filter_raw(&filter, Box::new(11));
        let expected: Box<dyn Value> = Box::new(11);
        assert_eq!(&expected, &v.unwrap());
    }
}