1use std::str;
2
3pub unsafe trait Str<'de>: 'de + Sized {
12 fn len(&self) -> usize;
14
15 fn as_bytes(&self) -> &[u8];
17
18 fn is_empty(&self) -> bool {
20 self.len() == 0
21 }
22
23 unsafe fn get_u8_char(&self, i: usize) -> Option<u8>;
34
35 unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self>;
47
48 unsafe fn find(&self, i: usize, char: u8) -> Option<usize>;
63
64 unsafe fn range_from(&self, i: usize) -> Self;
70
71 unsafe fn range(&self, i: usize, j: usize) -> Self;
77}
78
79unsafe impl<'de> Str<'de> for &'de str {
80 fn len(&self) -> usize {
81 str::len(*self)
82 }
83
84 fn as_bytes(&self) -> &[u8] {
85 str::as_bytes(*self)
86 }
87
88 unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
89 debug_assert!(i < self.len());
91 debug_assert!(self.is_char_boundary(i));
92
93 if self.is_char_boundary(i + 1) {
94 Some(*self.as_bytes().get_unchecked(i))
95 } else {
96 None
97 }
98 }
99
100 unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
101 debug_assert!(i < self.len());
103 debug_assert!(self.is_char_boundary(i));
104
105 if self.is_char_boundary(j) {
106 let bytes = str::as_bytes(*self).get_unchecked(i..j);
107 Some(str::from_utf8_unchecked(bytes)) } else {
109 None
110 }
111 }
112
113 unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
114 self.as_bytes().find(i, char)
115 }
116
117 unsafe fn range_from(&self, i: usize) -> Self {
118 debug_assert!(i <= self.len());
119 debug_assert!(self.is_char_boundary(i));
120
121 self.get_unchecked(i..)
122 }
123
124 unsafe fn range(&self, i: usize, j: usize) -> Self {
125 debug_assert!(i <= j);
126 debug_assert!(j <= self.len());
127 debug_assert!(self.is_char_boundary(i));
128 debug_assert!(self.is_char_boundary(j));
129
130 self.get_unchecked(i..j)
131 }
132}
133
134unsafe impl<'de> Str<'de> for String {
135 fn len(&self) -> usize {
136 str::len(self.as_str())
137 }
138
139 fn as_bytes(&self) -> &[u8] {
140 str::as_bytes(self.as_str())
141 }
142
143 unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
144 self.as_str().get_u8_char(i)
145 }
146
147 unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
148 self.as_str().clone_slice(i, j).map(|s| s.to_string())
149 }
150
151 unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
152 self.as_bytes().find(i, char)
153 }
154
155 unsafe fn range_from(&self, i: usize) -> Self {
156 self.as_str().range_from(i).to_string()
157 }
158
159 unsafe fn range(&self, i: usize, j: usize) -> Self {
160 self.as_str().range(i, j).to_string()
161 }
162}
163
164unsafe impl<'de> Str<'de> for &'de [u8] {
165 fn len(&self) -> usize {
166 <[u8]>::len(*self)
167 }
168
169 fn as_bytes(&self) -> &[u8] {
170 *self
171 }
172
173 unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
174 debug_assert!(i < self.len());
176
177 Some(*self.get_unchecked(i))
178 }
179
180 unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
181 debug_assert!(i < self.len());
183
184 Some(self.get_unchecked(i..j))
185 }
186
187 unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
188 debug_assert!(i < self.len());
190
191 let slice = self.get_unchecked((i + 1)..);
192 let index = slice.iter().position(|&other| char == other);
196 index.map(|index| i + 1 + index)
197 }
198
199 unsafe fn range_from(&self, i: usize) -> Self {
200 self.get_unchecked(i..)
201 }
202
203 unsafe fn range(&self, i: usize, j: usize) -> Self {
204 self.get_unchecked(i..j)
205 }
206}
207
208unsafe impl<'de> Str<'de> for Vec<u8> {
209 fn len(&self) -> usize {
210 <[u8]>::len(self.as_slice())
211 }
212
213 fn as_bytes(&self) -> &[u8] {
214 self.as_slice()
215 }
216
217 unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
218 self.as_slice().get_u8_char(i)
219 }
220
221 unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
222 self.as_slice().clone_slice(i, j).map(|s| s.to_vec())
223 }
224
225 unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
226 self.as_slice().find(i, char)
227 }
228
229 unsafe fn range_from(&self, i: usize) -> Self {
230 self.get_unchecked(i..).to_vec()
231 }
232
233 unsafe fn range(&self, i: usize, j: usize) -> Self {
234 self.get_unchecked(i..j).to_vec()
235 }
236}