yewtil/
not_equal_assign.rs

1//! Module for `neq_assign` utility function.
2
3use std::borrow::BorrowMut;
4use yew::html::ShouldRender;
5
6/// Blanket trait to provide a convenience method for assigning props in `changed` or updating values in `update`.
7pub trait NeqAssign<NEW> {
8    /// If `self` and `new` aren't equal, assigns `new` to `self` and returns true, otherwise returns false.
9    ///
10    /// Short for "Not equal assign".
11    ///
12    /// # Example
13    /// ```
14    /// # use yew::{Component, ShouldRender, ComponentLink};
15    /// # use yewtil::NeqAssign;
16    /// # use yew::Properties;
17    ///# use yew::virtual_dom::VNode;
18    /// ##[derive(Clone, Properties, PartialEq)]
19    ///  struct Props {
20    ///     field1: String,
21    ///     field2: usize
22    ///  }
23    ///  struct Model {
24    ///     props: Props
25    ///  }
26    ///  impl Component for Model {
27    /// #    type Message = ();
28    ///     type Properties = Props;
29    ///     // ...
30    /// #
31    /// #    fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
32    /// #        unimplemented!()
33    /// #    }
34    /// #    fn update(&mut self, msg: ()) -> ShouldRender {
35    /// #        unimplemented!()
36    /// #    }
37    /// #
38    ///     fn change(&mut self, props: Self::Properties) -> ShouldRender{
39    ///         self.props.neq_assign(props)
40    ///     }
41    ///#
42    ///#     fn view(&self) -> VNode {
43    ///#         unimplemented!()
44    ///#     }
45    ///  }
46    ///
47    /// let mut foo = 1;
48    ///
49    /// assert_eq!(foo.neq_assign(42), true);
50    /// assert_eq!(foo, 42);
51    ///
52    /// assert_eq!(foo.neq_assign(42), false);
53    /// ```
54    fn neq_assign(&mut self, new: NEW) -> ShouldRender;
55}
56
57impl<T: BorrowMut<U>, U: PartialEq> NeqAssign<U> for T {
58    fn neq_assign(&mut self, new: U) -> bool {
59        self.neq_assign_by(new, |x, y| x == y)
60    }
61}
62/// Blanket trait to provide a convenience method for assigning props in `changed` or updating values in `update`.
63///
64/// Like `neq_assign`, but for cases where `self` doesn't impl `PartialEq` or a nonstandard equality comparison is needed.
65///
66/// Useful for `Result<T, E: !PartialEq>`.
67pub trait NeqAssignBy<NEW> {
68    /// ```
69    /// # use yewtil::{NeqAssign, NeqAssignBy};
70    /// ##[derive(Clone, Debug)]
71    /// struct NonComparableError;
72    ///
73    /// fn eq_by_ok<T, E>(a: &Result<T, E>, b: &Result<T, E>) -> bool
74    /// where
75    ///     T: PartialEq,
76    /// {
77    ///     match (a, b) {
78    ///         (Ok(_), Err(_))
79    ///         | (Err(_), Ok(_))
80    ///         | (Err(_), Err(_)) => false,
81    ///         (Ok(a), Ok(b)) => a == b,
82    ///     }
83    /// }
84    ///
85    /// let mut foo: Result<u32, NonComparableError> = Ok(1);
86    ///
87    /// // Won't compile
88    /// // assert_eq!(foo.neq_assign(Ok(42)), true)
89    ///
90    /// assert_eq!(foo.neq_assign_by(Ok(42), eq_by_ok), true);
91    /// assert_eq!(foo.clone().unwrap(), 42);
92    ///
93    /// assert_eq!(foo.neq_assign_by(Err(NonComparableError), eq_by_ok), true);
94    /// assert!(foo.is_err());
95    ///
96    /// // The tradeoff: all assignments of an `Err` value will count as updates, even if they are
97    /// // "the same" for all practical intents and purposes.
98    /// assert_eq!(foo.neq_assign_by(Err(NonComparableError), eq_by_ok), true);
99    /// assert_eq!(foo.neq_assign_by(Err(NonComparableError), eq_by_ok), true);
100    /// assert_eq!(foo.neq_assign_by(Err(NonComparableError), eq_by_ok), true);
101    /// ```
102    ///
103    fn neq_assign_by<F>(&mut self, new: NEW, eq: F) -> ShouldRender
104    where
105        F: FnOnce(&NEW, &NEW) -> bool;
106}
107
108impl<T: BorrowMut<U>, U> NeqAssignBy<U> for T {
109    fn neq_assign_by<F>(&mut self, new: U, eq: F) -> ShouldRender
110    where
111        F: FnOnce(&U, &U) -> bool,
112    {
113        if !eq(self.borrow(), &new) {
114            *self.borrow_mut() = new;
115            true
116        } else {
117            false
118        }
119    }
120}