Skip to main content

hipstr/bytes/
cmp.rs

1//! Comparison trait implementations for `HipByt`
2
3use alloc::borrow::Cow;
4use alloc::boxed::Box;
5use alloc::vec::Vec;
6
7use super::HipByt;
8use crate::macros::{symmetric_eq, symmetric_ord};
9use crate::Backend;
10
11// Equality
12
13impl<B> Eq for HipByt<'_, B> where B: Backend {}
14
15impl<'b1, B1, B2> PartialEq<HipByt<'b1, B1>> for HipByt<'_, B2>
16where
17    B1: Backend,
18    B2: Backend,
19{
20    #[inline]
21    fn eq(&self, other: &HipByt<'b1, B1>) -> bool {
22        self.inherent_eq(other)
23    }
24}
25
26#[inline]
27pub(super) fn eq_slice(a: impl AsRef<[u8]>, b: impl AsRef<[u8]>) -> bool {
28    a.as_ref() == b.as_ref()
29}
30
31symmetric_eq! {
32    [B] [where B: Backend] ([u8], HipByt<'_, B>) = eq_slice;
33    [B] [where B: Backend] (&[u8], HipByt<'_, B>) = eq_slice;
34
35    [B, const N: usize] [where B: Backend] ([u8; N], HipByt<'_, B>) = eq_slice;
36    [B, const N: usize] [where B: Backend] (&[u8; N], HipByt<'_, B>) = eq_slice;
37
38    [B] [where B: Backend] (Vec<u8>, HipByt<'_, B>) = eq_slice;
39    [B] [where B: Backend] (&Vec<u8>, HipByt<'_, B>) = eq_slice;
40
41    [B] [where B: Backend] (Box<[u8]>, HipByt<'_, B>) = eq_slice;
42    [B] [where B: Backend] (&Box<[u8]>, HipByt<'_, B>) = eq_slice;
43
44    [B] [where B: Backend] (Cow<'_, [u8]>, HipByt<'_, B>) = eq_slice;
45    [B] [where B: Backend] (&Cow<'_, [u8]>, HipByt<'_, B>) = eq_slice;
46
47}
48
49// Order
50
51impl<B> Ord for HipByt<'_, B>
52where
53    B: Backend,
54{
55    #[inline]
56    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
57        self.as_slice().cmp(other.as_slice())
58    }
59}
60
61impl<B1, B2> PartialOrd<HipByt<'_, B1>> for HipByt<'_, B2>
62where
63    B1: Backend,
64    B2: Backend,
65{
66    #[inline]
67    fn partial_cmp(&self, other: &HipByt<'_, B1>) -> Option<core::cmp::Ordering> {
68        self.as_slice().partial_cmp(other.as_slice())
69    }
70}
71
72#[inline]
73pub(super) fn cmp_slice(a: impl AsRef<[u8]>, b: impl AsRef<[u8]>) -> Option<core::cmp::Ordering> {
74    a.as_ref().partial_cmp(b.as_ref())
75}
76
77symmetric_ord! {
78    [B] [where B: Backend] ([u8], HipByt<'_, B>) = cmp_slice;
79    [B] [where B: Backend] (&[u8], HipByt<'_, B>) = cmp_slice;
80
81    [B, const N: usize] [where B: Backend] ([u8; N], HipByt<'_, B>) = cmp_slice;
82    [B, const N: usize] [where B: Backend] (&[u8; N], HipByt<'_, B>) = cmp_slice;
83
84    [B] [where B: Backend] (Vec<u8>, HipByt<'_, B>) = cmp_slice;
85    [B] [where B: Backend] (&Vec<u8>, HipByt<'_, B>) = cmp_slice;
86
87    [B] [where B: Backend] (Box<[u8]>, HipByt<'_, B>) = cmp_slice;
88    [B] [where B: Backend] (&Box<[u8]>, HipByt<'_, B>) = cmp_slice;
89
90    [B] [where B: Backend] (Cow<'_, [u8]>, HipByt<'_, B>) = cmp_slice;
91    [B] [where B: Backend] (&Cow<'_, [u8]>, HipByt<'_, B>) = cmp_slice;
92}
93
94#[cfg(test)]
95mod tests {
96    use alloc::borrow::Cow;
97    use alloc::boxed::Box;
98    use alloc::vec::Vec;
99    use core::cmp::Ordering;
100
101    use crate::HipByt;
102
103    #[test]
104    fn test_eq() {
105        let arr = [32; 32];
106        let s: &[u8] = &arr;
107        let v = Vec::from(arr);
108        let b: Box<[u8]> = Box::from(arr);
109        let c: Cow<[u8]> = Cow::Borrowed(&arr);
110        let h = HipByt::from(arr.as_slice());
111        let h2 = HipByt::borrowed(arr.as_slice());
112
113        assert_eq!(h, h);
114        assert_eq!(h, h2);
115        assert_ne!(h2, h2.slice(0..4));
116
117        assert_eq!(h, arr);
118        assert_eq!(arr, h);
119
120        assert_eq!(h, s);
121        assert_eq!(s, h);
122        assert!(<[u8] as PartialEq<HipByt>>::eq(arr.as_slice(), &h));
123
124        assert_eq!(h, &arr);
125        assert_eq!(&arr, h);
126
127        assert_eq!(h, v);
128        assert_eq!(v, h);
129
130        assert_eq!(h, b);
131        assert_eq!(b, h);
132
133        assert_eq!(h, c);
134        assert_eq!(c, h);
135    }
136
137    #[test]
138    fn test_ord() {
139        let h1 = HipByt::borrowed(b"abc");
140        let h2 = HipByt::from(b"abd");
141
142        assert_eq!(h1.partial_cmp(&h1), Some(Ordering::Equal));
143        assert_eq!(h1.cmp(&h1), Ordering::Equal);
144
145        assert!(h1 < h2);
146        assert_eq!(h1.cmp(&h2), Ordering::Less);
147        assert_eq!(h1.partial_cmp(&h2), Some(Ordering::Less));
148        assert_eq!(h2.cmp(&h1), Ordering::Greater);
149        assert_eq!(h2.partial_cmp(&h1), Some(Ordering::Greater));
150    }
151
152    static H: HipByt = HipByt::from_static(b"abc");
153
154    #[test]
155    fn test_ord_other() {
156        assert_eq!(H.partial_cmp(b"abc".as_slice()), Some(Ordering::Equal));
157        assert_eq!(H.partial_cmp(b"abc"), Some(Ordering::Equal));
158        assert!(H < b"abd");
159        assert!(&H < b"abd");
160        assert!(H < b"abd".as_slice());
161        assert!(&H < b"abd".as_slice());
162        assert!(H < Vec::from(b"abd"));
163        assert!(H < Cow::Borrowed(b"abd".as_slice()));
164    }
165}