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 99 100 101 102 103 104 105 106 107 108 109 110
use super::{ReactiveValue, ReadonlyReactiveValue}; use std::sync::Arc; impl<T: 'static> ReactiveValue<T> { /// Returns a ReactiveValue that only changes when the content of the original ReactiveValue /// passes a test (specified by `filter_function`). The output ReactiveValue will be equal /// to `default_value` until the original ReactiveValue passes the test. /// /// *Note:* This function is roughly equivalent to the `filter` operator on Streams, but /// is renamed to clarify its behavior. /// /// # Examples /// ``` /// use epoxy_streams::ReactiveValue; /// /// let original = ReactiveValue::new(1_i32); /// let only_even = ReactiveValue::sanitize(&original, |val| val % 2 == 0, 0); /// assert_eq!(*only_even.get(), 0); /// /// original.set(2); /// assert_eq!(*only_even.get(), 2); /// /// original.set(3); /// assert_eq!(*only_even.get(), 2); /// /// original.set(4); /// assert_eq!(*only_even.get(), 4); /// ``` pub fn sanitize<F>( value: &ReactiveValue<T>, filter_function: F, default_value: T, ) -> ReadonlyReactiveValue<T> where F: Fn(&T) -> bool, F: 'static, { value .as_stream() .filter(filter_function) .to_reactive_value_with_default(default_value) } /// Returns a ReactiveValue that reverts to a given value when the filter test fails. /// /// # Examples /// ``` /// use epoxy_streams::ReactiveValue; /// /// let original = ReactiveValue::new(1_i32); /// let only_even = ReactiveValue::sanitize(&original, |val| val % 2 == 0, 0); /// assert_eq!(*only_even.get(), 0); /// /// original.set(2); /// assert_eq!(*only_even.get(), 2); /// /// original.set(3); /// assert_eq!(*only_even.get(), 2); /// /// original.set(4); /// assert_eq!(*only_even.get(), 4); /// ``` pub fn fallback<F>( value: &ReactiveValue<T>, filter_function: F, fallback_value: T, ) -> ReadonlyReactiveValue<T> where F: Fn(&T) -> bool, F: 'static, { let fallback_value_rc = Arc::new(fallback_value); let inner_rc = fallback_value_rc.clone(); value .as_stream() .map_rc(move |val| if filter_function(&*val) { val } else { inner_rc.clone() }) .to_reactive_value_with_default_rc(fallback_value_rc) } /// Returns a ReactiveValue whose content is the result of running the content of the original /// ReactiveValue through a mapping function. /// /// # Examples /// /// ``` /// use epoxy_streams::ReactiveValue; /// /// let original = ReactiveValue::new("Bread"); /// let thing_that_is_cool = ReactiveValue::map(&original, |str| { /// format!("{} is cool", str) /// }); /// assert_eq!(*thing_that_is_cool.get(), "Bread is cool"); /// /// original.set("Cheese"); /// assert_eq!(*thing_that_is_cool.get(), "Cheese is cool"); /// /// ``` pub fn map<U, F>(value: &ReactiveValue<T>, map_function: F) -> ReadonlyReactiveValue<U> where U: 'static, F: Fn(&T) -> U, F: 'static, { let default = map_function(&*value.get()); value .as_stream() .map(map_function) .to_reactive_value_with_default(default) } }