Skip to main content

physdes/
generic.rs

1/// Trait for checking whether two values overlap.
2///
3/// # Examples
4///
5/// ```
6/// use physdes::generic::Overlap;
7///
8/// let a: i32 = 42;
9/// let b: i32 = 42;
10/// assert!(a.overlaps(&b));
11///
12/// let a: i32 = 42;
13/// let b: i32 = 24;
14/// assert!(!a.overlaps(&b));
15/// ```
16pub trait Overlap<T> {
17    fn overlaps(&self, other: &T) -> bool;
18}
19
20/// Checks if two `i32` values are equal.
21///
22/// Two scalars "overlap" iff they are equal: $a \cap b \iff a = b$
23///
24/// # Examples
25///
26/// ```
27/// use physdes::generic::Overlap;
28///
29/// let a: i32 = 42;
30/// let b: i32 = 42;
31/// assert!(a.overlaps(&b));
32///
33/// let a: i32 = 42;
34/// let b: i32 = 24;
35/// assert!(!a.overlaps(&b));
36/// ```
37impl Overlap<i32> for i32 {
38    /// Checks if two `i32` values are equal.
39    ///
40    /// Two scalars "overlap" iff they are equal: $a \cap b \iff a = b$
41    #[inline]
42    fn overlaps(&self, other: &i32) -> bool {
43        self == other
44    }
45}
46
47/// Trait for checking if one value contains another.
48///
49/// # Examples
50///
51/// ```
52/// use physdes::generic::Contain;
53///
54/// let a: i32 = 42;
55/// let b: i32 = 42;
56/// assert!(a.contains(&b));
57///
58/// let a: i32 = 42;
59/// let b: i32 = 24;
60/// assert!(!a.contains(&b));
61/// ```
62pub trait Contain<T> {
63    fn contains(&self, other: &T) -> bool;
64}
65
66/// `Contain` implementation for `i32`: returns true when values are equal.
67///
68/// Scalar $a$ "contains" $b$ iff $a = b$.
69///
70/// # Examples
71///
72/// ```
73/// use physdes::generic::Contain;
74///
75/// let a: i32 = 42;
76/// let b: i32 = 42;
77/// assert!(a.contains(&b));
78///
79/// let a: i32 = 42;
80/// let b: i32 = 24;
81/// assert!(!a.contains(&b));
82/// ```
83impl Contain<i32> for i32 {
84    /// Checks if the current `i32` value equals the provided value.
85    ///
86    /// Scalar $a$ "contains" $b$ iff $a = b$.
87    #[inline]
88    fn contains(&self, other: &i32) -> bool {
89        self == other
90    }
91}
92
93/// Trait for calculating the minimum distance between two values.
94///
95/// # Examples
96///
97/// ```
98/// use physdes::generic::MinDist;
99///
100/// let a: i32 = 10;
101/// let b: i32 = 5;
102/// let distance = a.min_dist_with(&b);
103/// assert_eq!(distance, 5);
104/// ```
105pub trait MinDist<T> {
106    /// Calculates the minimum distance between the current value and the provided value.
107    ///
108    /// # Arguments
109    /// * `other` - A reference to the other value to compare against.
110    ///
111    /// # Returns
112    /// The minimum distance between the current value and the provided value, as a `u32`.
113    fn min_dist_with(&self, other: &T) -> u32;
114}
115
116/// Computes the absolute difference between two `i32` values.
117///
118/// $$d = |a - b|$$
119///
120/// # Examples
121///
122/// ```
123/// use physdes::generic::MinDist;
124///
125/// let a: i32 = 10;
126/// let b: i32 = 5;
127/// let distance = a.min_dist_with(&b);
128/// assert_eq!(distance, 5);
129/// ```
130impl MinDist<i32> for i32 {
131    /// Minimum distance between two scalars is the absolute difference:
132    ///
133    /// $$d = |a - b|$$
134    #[inline]
135    fn min_dist_with(&self, other: &i32) -> u32 {
136        (self - other).unsigned_abs()
137    }
138}
139
140/// Trait for computing the displacement between two values.
141///
142/// # Examples
143///
144/// ```
145/// use physdes::generic::Displacement;
146///
147/// let a: i32 = 10;
148/// let b: i32 = 5;
149/// let displacement = a.displace(&b);
150/// assert_eq!(displacement, 5);
151/// ```
152pub trait Displacement<T: ?Sized> {
153    type Output;
154
155    /// Displace the current value by the provided `other` value.
156    fn displace(&self, other: &T) -> Self::Output;
157}
158
159/// Computes the displacement (difference) between two `i32` values: `self - other`.
160///
161/// $$d = a - b$$
162///
163/// # Examples
164///
165/// ```
166/// use physdes::generic::Displacement;
167///
168/// let a: i32 = 10;
169/// let b: i32 = 5;
170/// let displacement = a.displace(&b);
171/// assert_eq!(displacement, 5);
172/// ```
173impl Displacement<i32> for i32 {
174    type Output = i32;
175
176    /// Displacement (difference) between two scalars:
177    ///
178    /// $$d = a - b$$
179    #[inline]
180    fn displace(&self, other: &i32) -> Self::Output {
181        self - other
182    }
183}
184
185#[cfg(test)]
186mod tests {
187    use super::*;
188
189    #[test]
190    fn test_overlap() {
191        assert!(1.overlaps(&1));
192        assert!(!1.overlaps(&2));
193    }
194
195    #[test]
196    fn test_contain() {
197        assert!(1.contains(&1));
198        assert!(!1.contains(&2));
199    }
200
201    #[test]
202    fn test_min_dist() {
203        assert_eq!(1.min_dist_with(&1), 0);
204        assert_eq!(1.min_dist_with(&2), 1);
205        assert_eq!(2.min_dist_with(&1), 1);
206    }
207
208    #[test]
209    fn test_displace() {
210        assert_eq!(1.displace(&1), 0);
211        assert_eq!(1.displace(&2), -1);
212        assert_eq!(2.displace(&1), 1);
213    }
214}