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()); } }