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
/// See [SoftEq]

use core::clone::Clone;
use core::cmp::Eq;
use core::marker::Sized;

/// Define soft (partial) equality
///
/// Two elements are "softly equals" if they can be considered as two different stages of the same element, i.e. their hard parts are equals (c.f. below)
/// This is mainly used by the [Vec] implementation of [Mutable], to determine when an item as mutated
///
/// We can distinguish two parts of a SoftEq element:
/// - the hard part, which is unique for each element (a uid String, for example)
/// - the soft part, which may variate for the same element (like a charge attribute for an electrical item)
///
/// ```
/// # use mutable::cmp::SoftEq;
/// # use mutable_derive::SoftEq;
/// #[derive(SoftEq)]
/// struct Item {
///     #[softeq(uid)]
///     id: String,
///     charge: usize,
/// }
///
/// # fn main() {
/// let i0 = Item { id: "tear".to_string(), charge: 32 };
/// let i1 = Item { id: "tear".to_string(), charge: 12 };
/// let i2 = Item { id: "draktaar".to_string(), charge: 32 };
///
/// assert!(i0.se(&i1));
/// assert!(i0.nse(&i2));
/// assert!(i1.nse(&i2));
/// # }
/// ```
pub trait SoftEq where Self: Sized {
    /// The type of the hard part
    type Uid: Eq + Clone;

    /// Whether self and other are softly equals (their hard part is identical)
    fn se(&self, other: &Self) -> bool { self.uid() == other.uid() }
    /// Whether self and other are softly different (their hard part differs)
    fn nse(&self, other: &Self) -> bool { !self.se(other) }

    /// The hard part of self
    fn uid(&self) -> Self::Uid;
}