cheetah_string/cheetah_string/
traits.rs1use alloc::string::String;
2use alloc::vec::Vec;
3use core::borrow::Borrow;
4use core::cmp::Ordering;
5use core::fmt::{self, Display};
6use core::hash::{Hash, Hasher};
7use core::ops::Add;
8use core::str;
9
10use super::repr::INLINE_CAPACITY;
11use super::CheetahString;
12
13#[inline]
14fn concatenate(left: &str, right: &str) -> CheetahString {
15 let len = left
16 .len()
17 .checked_add(right.len())
18 .expect("concatenated string length overflow");
19
20 if len <= INLINE_CAPACITY {
21 let mut bytes = [0; INLINE_CAPACITY];
22 bytes[..left.len()].copy_from_slice(left.as_bytes());
23 bytes[left.len()..len].copy_from_slice(right.as_bytes());
24 let value =
25 str::from_utf8(&bytes[..len]).expect("concatenating valid strings must preserve UTF-8");
26 return CheetahString::from_slice(value);
27 }
28
29 let mut value = String::with_capacity(len);
30 value.push_str(left);
31 value.push_str(right);
32 CheetahString::from_string(value)
33}
34
35impl PartialEq for CheetahString {
36 #[inline]
37 fn eq(&self, other: &Self) -> bool {
38 #[cfg(all(feature = "experimental-simd", target_arch = "x86_64"))]
39 {
40 crate::simd::eq_bytes(self.as_bytes(), other.as_bytes())
41 }
42 #[cfg(not(all(feature = "experimental-simd", target_arch = "x86_64")))]
43 {
44 self.as_str() == other.as_str()
45 }
46 }
47}
48
49impl PartialEq<str> for CheetahString {
50 #[inline]
51 fn eq(&self, other: &str) -> bool {
52 #[cfg(all(feature = "experimental-simd", target_arch = "x86_64"))]
53 {
54 crate::simd::eq_bytes(self.as_bytes(), other.as_bytes())
55 }
56 #[cfg(not(all(feature = "experimental-simd", target_arch = "x86_64")))]
57 {
58 self.as_str() == other
59 }
60 }
61}
62
63impl PartialEq<String> for CheetahString {
64 #[inline]
65 fn eq(&self, other: &String) -> bool {
66 #[cfg(all(feature = "experimental-simd", target_arch = "x86_64"))]
67 {
68 crate::simd::eq_bytes(self.as_bytes(), other.as_bytes())
69 }
70 #[cfg(not(all(feature = "experimental-simd", target_arch = "x86_64")))]
71 {
72 self.as_str() == other.as_str()
73 }
74 }
75}
76
77impl PartialEq<Vec<u8>> for CheetahString {
78 #[inline]
79 fn eq(&self, other: &Vec<u8>) -> bool {
80 self.as_bytes() == other.as_slice()
81 }
82}
83
84impl<'a> PartialEq<&'a str> for CheetahString {
85 #[inline]
86 fn eq(&self, other: &&'a str) -> bool {
87 self.as_str() == *other
88 }
89}
90
91impl PartialEq<CheetahString> for str {
92 #[inline]
93 fn eq(&self, other: &CheetahString) -> bool {
94 self == other.as_str()
95 }
96}
97
98impl PartialEq<CheetahString> for String {
99 #[inline]
100 fn eq(&self, other: &CheetahString) -> bool {
101 self.as_str() == other.as_str()
102 }
103}
104
105impl PartialEq<CheetahString> for &str {
106 #[inline]
107 fn eq(&self, other: &CheetahString) -> bool {
108 *self == other.as_str()
109 }
110}
111
112impl Eq for CheetahString {}
113
114impl PartialOrd for CheetahString {
115 #[inline]
116 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
117 Some(self.cmp(other))
118 }
119}
120
121impl Ord for CheetahString {
122 #[inline]
123 fn cmp(&self, other: &Self) -> Ordering {
124 self.as_str().cmp(other.as_str())
125 }
126}
127
128impl Hash for CheetahString {
129 #[inline]
130 fn hash<H: Hasher>(&self, state: &mut H) {
131 self.as_str().hash(state);
132 }
133}
134
135impl Display for CheetahString {
136 #[inline]
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 self.as_str().fmt(f)
139 }
140}
141
142impl fmt::Debug for CheetahString {
143 #[inline]
144 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145 fmt::Debug::fmt(self.as_str(), f)
146 }
147}
148
149impl Borrow<str> for CheetahString {
150 #[inline]
151 fn borrow(&self) -> &str {
152 self.as_str()
153 }
154}
155
156impl Add<&str> for CheetahString {
159 type Output = CheetahString;
160
161 #[inline]
173 fn add(self, rhs: &str) -> Self::Output {
174 if rhs.is_empty() {
175 return self;
176 }
177
178 concatenate(self.as_str(), rhs)
179 }
180}
181
182impl Add<&CheetahString> for CheetahString {
183 type Output = CheetahString;
184
185 #[inline]
198 fn add(self, rhs: &CheetahString) -> Self::Output {
199 self + rhs.as_str()
200 }
201}
202
203impl Add<String> for CheetahString {
204 type Output = CheetahString;
205
206 #[inline]
218 fn add(self, rhs: String) -> Self::Output {
219 if rhs.is_empty() {
220 return self;
221 }
222
223 if self.is_empty() {
224 return CheetahString::from_string(rhs);
225 }
226
227 concatenate(self.as_str(), &rhs)
228 }
229}