1use alloc::borrow::Cow;
4use alloc::boxed::Box;
5use alloc::string::String;
6
7use super::HipStr;
8use crate::macros::{symmetric_eq, symmetric_ord};
9use crate::Backend;
10
11impl<B> Eq for HipStr<'_, B> where B: Backend {}
14
15impl<B1, B2> PartialEq<HipStr<'_, B1>> for HipStr<'_, B2>
16where
17 B1: Backend,
18 B2: Backend,
19{
20 #[inline]
21 fn eq(&self, other: &HipStr<B1>) -> bool {
22 self.0 == other.0
23 }
24}
25
26#[inline]
27fn str_eq(a: impl AsRef<str>, b: impl AsRef<str>) -> bool {
28 a.as_ref() == b.as_ref()
29}
30
31symmetric_eq! {
32 [B] [where B: Backend] (str, HipStr<'_, B>) = str_eq;
33 [B] [where B: Backend] (&str, HipStr<'_, B>) = str_eq;
34 [B] [where B: Backend] (String, HipStr<'_, B>) = str_eq;
35 [B] [where B: Backend] (Box<str>, HipStr<'_, B>) = str_eq;
36 [B] [where B: Backend] (Cow<'_, str>, HipStr<'_, B>) = str_eq;
37}
38
39#[cfg(feature = "std")]
40#[inline]
41fn os_str_eq(a: impl AsRef<std::ffi::OsStr>, b: impl AsRef<str>) -> bool {
42 a.as_ref() == b.as_ref()
43}
44
45#[cfg(feature = "std")]
46symmetric_eq! {
47 [B] [where B: Backend] (std::ffi::OsStr, HipStr<'_, B>) = os_str_eq;
48 [B] [where B: Backend] (&std::ffi::OsStr, HipStr<'_, B>) = os_str_eq;
49 [B] [where B: Backend] (std::ffi::OsString, HipStr<'_, B>) = os_str_eq;
50 [B] [where B: Backend] (&std::ffi::OsString, HipStr<'_, B>) = os_str_eq;
51}
52
53impl<B> Ord for HipStr<'_, B>
56where
57 B: Backend,
58{
59 #[inline]
60 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
61 self.as_str().cmp(other.as_str())
62 }
63}
64
65impl<B1, B2> PartialOrd<HipStr<'_, B1>> for HipStr<'_, B2>
66where
67 B1: Backend,
68 B2: Backend,
69{
70 #[inline]
71 fn partial_cmp(&self, other: &HipStr<'_, B1>) -> Option<core::cmp::Ordering> {
72 self.as_str().partial_cmp(other.as_str())
73 }
74}
75
76#[inline]
77fn str_cmp(a: impl AsRef<str>, b: impl AsRef<str>) -> Option<core::cmp::Ordering> {
78 a.as_ref().partial_cmp(b.as_ref())
79}
80
81symmetric_ord! {
82 [B] [where B: Backend] (str, HipStr<'_, B>) = str_cmp;
83 [B] [where B: Backend] (&str, HipStr<'_, B>) = str_cmp;
84 [B] [where B: Backend] (String, HipStr<'_, B>) = str_cmp;
85}
86
87#[cfg(feature = "std")]
88#[inline]
89fn os_str_cmp(a: impl AsRef<std::ffi::OsStr>, b: impl AsRef<str>) -> Option<core::cmp::Ordering> {
90 a.as_ref().partial_cmp(b.as_ref())
91}
92
93#[cfg(feature = "std")]
94symmetric_ord! {
95 [B] [where B: Backend] (std::ffi::OsStr, HipStr<'_, B>) = os_str_cmp;
96 [B] [where B: Backend] (&std::ffi::OsStr, HipStr<'_, B>) = os_str_cmp;
97 [B] [where B: Backend] (std::ffi::OsString, HipStr<'_, B>) = os_str_cmp;
98 [B] [where B: Backend] (&std::ffi::OsString, HipStr<'_, B>) = os_str_cmp;
99}
100
101#[cfg(test)]
102mod tests {
103 use alloc::borrow::Cow;
104 use alloc::boxed::Box;
105 use core::cmp::Ordering;
106
107 use crate::HipStr;
108
109 #[test]
110 fn test_eq() {
111 let string = "A".repeat(42);
112 let slice: &str = &string;
113 let b: Box<str> = Box::from(slice);
114 let c: Cow<str> = Cow::Borrowed(slice);
115 let h = HipStr::from(slice);
116 let h2 = HipStr::borrowed(slice);
117
118 assert_eq!(h, h);
119 assert_eq!(h2, h2);
120 assert_eq!(h, h2);
121 assert_ne!(h2, h2.slice(0..4));
122
123 assert_eq!(h, slice);
124 assert_eq!(slice, h);
125
126 assert_eq!(h, *slice);
127 assert_eq!(*slice, h);
128
129 assert_eq!(h, string);
130 assert_eq!(string, h);
131
132 assert_eq!(h, b);
133 assert_eq!(b, h);
134
135 assert_eq!(h, c);
136 assert_eq!(c, h);
137 }
138
139 #[test]
140 #[cfg(feature = "std")]
141 fn test_eq_os_str() {
142 let s = "abc";
143 let os: &std::ffi::OsStr = s.as_ref();
144 let h = HipStr::from(s);
145 assert_eq!(h, os);
146 assert_eq!(os, h);
147 assert_eq!(&h, os);
148 assert_eq!(os, &h);
149 }
150
151 #[test]
152 #[cfg(feature = "std")]
153 fn test_eq_os_string() {
154 let s = "abc";
155 let os: &std::ffi::OsStr = s.as_ref();
156 let oss = os.to_os_string();
157 let h = HipStr::from(s);
158 assert_eq!(h, oss);
159 assert_eq!(oss, h);
160 }
161
162 #[cfg(feature = "bstr")]
163 #[test]
164 fn test_eq_bstr() {
165 let s = "abc";
166 let b: &bstr::BStr = s.as_ref();
167 let h = HipStr::from(s);
168 assert_eq!(h, b);
169 assert_eq!(b, h);
170 assert_eq!(&h, b);
171 assert_eq!(b, &h);
172 }
173
174 #[cfg(feature = "bstr")]
175 #[test]
176 fn test_eq_bstring() {
177 let s = "abc";
178 let bs = bstr::BString::from(s);
179 let h = HipStr::from(s);
180 assert_eq!(h, bs);
181 assert_eq!(bs, h);
182 }
183
184 static BB_H: HipStr = HipStr::borrowed("bb");
185 static BC_H: HipStr = HipStr::borrowed("bc");
186
187 #[test]
188 fn test_cmp() {
189 assert_eq!(BB_H.partial_cmp(&BB_H), Some(Ordering::Equal));
190 assert_eq!(BB_H.cmp(&BB_H), Ordering::Equal);
191
192 assert!(BB_H < BC_H);
193 assert_eq!(BB_H.cmp(&BC_H), Ordering::Less);
194 assert_eq!(BB_H.partial_cmp(&BC_H), Some(Ordering::Less));
195 assert_eq!(BC_H.cmp(&BB_H), Ordering::Greater);
196 assert_eq!(BC_H.partial_cmp(&BB_H), Some(Ordering::Greater));
197 }
198
199 #[test]
200 fn test_cmp_str() {
201 assert!(&BB_H < "bc");
202 assert!(&BB_H > "ba");
203 assert!(&BB_H >= "bb");
204
205 assert!("bc" > &BB_H);
206 assert!("ba" < &BB_H);
207 assert!("bb" <= &BB_H);
208
209 assert!(BB_H < "bc");
210 assert!(BB_H > "ba");
211 assert!(BB_H >= "bb");
212
213 assert!("bc" > BB_H);
214 assert!("ba" < BB_H);
215 assert!("bb" <= BB_H);
216 }
217
218 #[test]
219 fn test_cmp_string() {
220 use alloc::string::String;
221
222 assert!(BB_H < String::from("bc"));
223 assert!(BB_H > String::from("ba"));
224 assert!(BB_H >= String::from("bb"));
225
226 assert!(String::from("bc") > BB_H);
227 assert!(String::from("ba") < BB_H);
228 assert!(String::from("bb") <= BB_H);
229 }
230
231 #[test]
232 #[cfg(feature = "std")]
233 fn test_cmp_os_str() {
234 use std::ffi::OsStr;
235
236 assert!(OsStr::new("bc") > &BB_H);
237 assert!(OsStr::new("ba") < &BB_H);
238 assert!(OsStr::new("bb") <= &BB_H);
239
240 assert!(&BB_H < OsStr::new("bc"));
241 assert!(&BB_H > OsStr::new("ba"));
242 assert!(&BB_H >= OsStr::new("bb"));
243
244 assert!(OsStr::new("bc") > BB_H);
245 assert!(OsStr::new("ba") < BB_H);
246 assert!(OsStr::new("bb") <= BB_H);
247
248 assert!(BB_H < OsStr::new("bc"));
249 assert!(BB_H > OsStr::new("ba"));
250 assert!(BB_H >= OsStr::new("bb"));
251 }
252
253 #[test]
254 #[cfg(feature = "std")]
255 fn test_cmp_os_string() {
256 use std::ffi::OsString;
257
258 assert!(OsString::from("bc") > BB_H);
259 assert!(OsString::from("ba") < BB_H);
260 assert!(OsString::from("bb") <= BB_H);
261
262 assert!(BB_H < OsString::from("bc"));
263 assert!(BB_H > OsString::from("ba"));
264 assert!(BB_H >= OsString::from("bb"));
265 }
266
267 #[cfg(feature = "bstr")]
268 #[test]
269 fn test_cmp_bstr() {
270 use bstr::BStr;
271
272 assert!(BStr::new("bc") > &BB_H);
273 assert!(BStr::new("ba") < &BB_H);
274 assert!(BStr::new("bb") <= &BB_H);
275
276 assert!(&BB_H < BStr::new("bc"));
277 assert!(&BB_H > BStr::new("ba"));
278 assert!(&BB_H >= BStr::new("bb"));
279
280 assert!(BStr::new("bc") > BB_H);
281 assert!(BStr::new("ba") < BB_H);
282 assert!(BStr::new("bb") <= BB_H);
283
284 assert!(BB_H < BStr::new("bc"));
285 assert!(BB_H > BStr::new("ba"));
286 assert!(BB_H >= BStr::new("bb"));
287 }
288
289 #[cfg(feature = "bstr")]
290 #[test]
291 fn test_cmp_bstring() {
292 use bstr::BString;
293
294 assert!(BString::from("bc") > BB_H);
295 assert!(BString::from("ba") < BB_H);
296 assert!(BString::from("bb") <= BB_H);
297
298 assert!(BB_H < BString::from("bc"));
299 assert!(BB_H > BString::from("ba"));
300 assert!(BB_H >= BString::from("bb"));
301 }
302}