1use crate::{generic::ArraySlice, prelude::*};
4use core::fmt::{self, Debug, Display, Formatter, Write};
5use core::iter::FromIterator;
6use core::ops::{Add, Deref, DerefMut, Index, IndexMut};
7use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
8use core::str::{self, FromStr};
9use core::{borrow::Borrow, borrow::BorrowMut, cmp::Ordering, hash::Hash, hash::Hasher};
10
11impl<SIZE> Default for ArrayString<SIZE>
12where
13 SIZE: Capacity,
14{
15 #[inline]
16 fn default() -> Self {
17 Self {
18 array: SIZE::Array::zeroed(),
19 size: Default::default(),
20 }
21 }
22}
23
24impl<SIZE: Capacity + Copy> Copy for ArrayString<SIZE> where SIZE::Array: Copy {}
25
26impl<SIZE> AsRef<str> for ArrayString<SIZE>
27where
28 SIZE: Capacity,
29{
30 #[inline]
31 fn as_ref(&self) -> &str {
32 unsafe { str::from_utf8_unchecked(self.as_ref()) }
33 }
34}
35
36impl<SIZE> AsMut<str> for ArrayString<SIZE>
37where
38 SIZE: Capacity,
39{
40 #[inline]
41 fn as_mut(&mut self) -> &mut str {
42 let len = self.size as usize;
43 let slice = unsafe { self.array.as_mut_slice().get_unchecked_mut(..len) };
44 unsafe { str::from_utf8_unchecked_mut(slice) }
45 }
46}
47
48impl<SIZE> AsRef<[u8]> for ArrayString<SIZE>
49where
50 SIZE: Capacity,
51{
52 #[inline]
53 fn as_ref(&self) -> &[u8] {
54 unsafe { self.array.as_slice().get_unchecked(..self.size.into()) }
55 }
56}
57
58impl<'a, SIZE> From<&'a str> for ArrayString<SIZE>
59where
60 SIZE: Capacity,
61{
62 #[inline]
63 fn from(s: &str) -> Self {
64 Self::from_str_truncate(s)
65 }
66}
67
68impl<SIZE> FromStr for ArrayString<SIZE>
69where
70 SIZE: Capacity,
71{
72 type Err = OutOfBounds;
73
74 #[inline]
75 fn from_str(s: &str) -> Result<Self, Self::Err> {
76 Self::try_from_str(s)
77 }
78}
79
80impl<SIZE> Debug for ArrayString<SIZE>
81where
82 SIZE: Capacity,
83{
84 #[inline]
85 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
86 f.debug_struct("ArrayString")
87 .field("array", &self.as_str())
88 .field("size", &self.size)
89 .finish()
90 }
91}
92
93impl<'a, 'b, SIZE> PartialEq<str> for ArrayString<SIZE>
94where
95 SIZE: Capacity,
96{
97 #[inline]
98 fn eq(&self, other: &str) -> bool {
99 self.as_str().eq(other)
100 }
101}
102
103impl<SIZE> Borrow<str> for ArrayString<SIZE>
104where
105 SIZE: Capacity,
106{
107 #[inline]
108 fn borrow(&self) -> &str {
109 self.as_str()
110 }
111}
112
113impl<SIZE> BorrowMut<str> for ArrayString<SIZE>
114where
115 SIZE: Capacity,
116{
117 #[inline]
118 fn borrow_mut(&mut self) -> &mut str {
119 self.as_mut_str()
120 }
121}
122
123impl<SIZE> Hash for ArrayString<SIZE>
124where
125 SIZE: Capacity,
126{
127 #[inline]
128 fn hash<H: Hasher>(&self, hasher: &mut H) {
129 self.as_str().hash(hasher);
130 }
131}
132
133impl<SIZE> PartialEq for ArrayString<SIZE>
134where
135 SIZE: Capacity,
136{
137 #[inline]
138 fn eq(&self, other: &Self) -> bool {
139 self.as_str().eq(other.as_str())
140 }
141}
142impl<SIZE: Capacity> Eq for ArrayString<SIZE> {}
143
144impl<SIZE> Ord for ArrayString<SIZE>
145where
146 SIZE: Capacity,
147{
148 #[inline]
149 fn cmp(&self, other: &Self) -> Ordering {
150 self.as_str().cmp(other.as_str())
151 }
152}
153
154impl<SIZE> PartialOrd for ArrayString<SIZE>
155where
156 SIZE: Capacity,
157{
158 #[inline]
159 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
160 Some(self.cmp(other))
161 }
162}
163
164impl<'a, SIZE> Add<&'a str> for ArrayString<SIZE>
165where
166 SIZE: Capacity,
167{
168 type Output = Self;
169
170 #[inline]
171 fn add(self, other: &str) -> Self::Output {
172 let mut out = unsafe { Self::from_str_unchecked(self) };
173 out.push_str(other);
174 out
175 }
176}
177
178impl<SIZE> Write for ArrayString<SIZE>
179where
180 SIZE: Capacity,
181{
182 #[inline]
183 fn write_str(&mut self, slice: &str) -> fmt::Result {
184 self.try_push_str(slice).map_err(|_| fmt::Error)
185 }
186}
187
188impl<SIZE> Display for ArrayString<SIZE>
189where
190 SIZE: Capacity,
191{
192 #[inline]
193 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
194 write!(f, "{}", self.as_str())
195 }
196}
197
198impl<SIZE> Deref for ArrayString<SIZE>
199where
200 SIZE: Capacity,
201{
202 type Target = str;
203
204 #[inline]
205 fn deref(&self) -> &Self::Target {
206 self.as_ref()
207 }
208}
209
210impl<SIZE> DerefMut for ArrayString<SIZE>
211where
212 SIZE: Capacity,
213{
214 #[inline]
215 fn deref_mut(&mut self) -> &mut Self::Target {
216 self.as_mut()
217 }
218}
219
220impl<SIZE> FromIterator<char> for ArrayString<SIZE>
221where
222 SIZE: Capacity,
223{
224 fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Self {
225 Self::from_chars(iter)
226 }
227}
228
229impl<'a, SIZE> FromIterator<&'a str> for ArrayString<SIZE>
230where
231 SIZE: Capacity,
232{
233 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
234 Self::from_iterator(iter)
235 }
236}
237
238impl<SIZE> Extend<char> for ArrayString<SIZE>
239where
240 SIZE: Capacity,
241{
242 fn extend<I: IntoIterator<Item = char>>(&mut self, iterable: I) {
243 self.push_str(Self::from_chars(iterable))
244 }
245}
246
247impl<'a, SIZE> Extend<&'a char> for ArrayString<SIZE>
248where
249 SIZE: Capacity,
250{
251 fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {
252 self.extend(iter.into_iter().cloned());
253 }
254}
255
256impl<'a, SIZE> Extend<&'a str> for ArrayString<SIZE>
257where
258 SIZE: Capacity,
259{
260 fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iterable: I) {
261 self.push_str(Self::from_iterator(iterable))
262 }
263}
264
265impl<SIZE> IndexMut<RangeFrom<u8>> for ArrayString<SIZE>
266where
267 SIZE: Capacity,
268{
269 #[inline]
270 fn index_mut(&mut self, index: RangeFrom<u8>) -> &mut str {
271 let start = index.start as usize;
272 self.as_mut_str().index_mut(RangeFrom { start })
273 }
274}
275
276impl<SIZE> IndexMut<RangeTo<u8>> for ArrayString<SIZE>
277where
278 SIZE: Capacity,
279{
280 #[inline]
281 fn index_mut(&mut self, index: RangeTo<u8>) -> &mut str {
282 let end = index.end as usize;
283 self.as_mut_str().index_mut(RangeTo { end })
284 }
285}
286
287impl<SIZE> IndexMut<RangeFull> for ArrayString<SIZE>
288where
289 SIZE: Capacity,
290{
291 #[inline]
292 fn index_mut(&mut self, index: RangeFull) -> &mut str {
293 self.as_mut_str().index_mut(index)
294 }
295}
296
297impl<SIZE> IndexMut<Range<u8>> for ArrayString<SIZE>
298where
299 SIZE: Capacity,
300{
301 #[inline]
302 fn index_mut(&mut self, index: Range<u8>) -> &mut str {
303 let (start, end) = (index.start as usize, index.end as usize);
304 let range = Range { start, end };
305 self.as_mut_str().index_mut(range)
306 }
307}
308
309impl<SIZE> IndexMut<RangeToInclusive<u8>> for ArrayString<SIZE>
310where
311 SIZE: Capacity,
312{
313 #[inline]
314 fn index_mut(&mut self, index: RangeToInclusive<u8>) -> &mut str {
315 let end = index.end as usize;
316 let range = RangeToInclusive { end };
317 self.as_mut_str().index_mut(range)
318 }
319}
320
321impl<SIZE> IndexMut<RangeInclusive<u8>> for ArrayString<SIZE>
322where
323 SIZE: Capacity,
324{
325 #[inline]
326 fn index_mut(&mut self, index: RangeInclusive<u8>) -> &mut str {
327 let (start, end) = (*index.start() as usize, *index.end() as usize);
328 let range = RangeInclusive::new(start, end);
329 self.as_mut_str().index_mut(range)
330 }
331}
332
333impl<SIZE> Index<RangeFrom<u8>> for ArrayString<SIZE>
334where
335 SIZE: Capacity,
336{
337 type Output = str;
338
339 #[inline]
340 fn index(&self, index: RangeFrom<u8>) -> &Self::Output {
341 let start = index.start as usize;
342 self.as_str().index(RangeFrom { start })
343 }
344}
345
346impl<SIZE> Index<RangeTo<u8>> for ArrayString<SIZE>
347where
348 SIZE: Capacity,
349{
350 type Output = str;
351
352 #[inline]
353 fn index(&self, index: RangeTo<u8>) -> &Self::Output {
354 let end = index.end as usize;
355 self.as_str().index(RangeTo { end })
356 }
357}
358
359impl<SIZE> Index<RangeFull> for ArrayString<SIZE>
360where
361 SIZE: Capacity,
362{
363 type Output = str;
364
365 #[inline]
366 fn index(&self, index: RangeFull) -> &Self::Output {
367 self.as_str().index(index)
368 }
369}
370
371impl<SIZE> Index<Range<u8>> for ArrayString<SIZE>
372where
373 SIZE: Capacity,
374{
375 type Output = str;
376
377 #[inline]
378 fn index(&self, index: Range<u8>) -> &Self::Output {
379 let (start, end) = (index.start as usize, index.end as usize);
380 self.as_str().index(Range { start, end })
381 }
382}
383
384impl<SIZE> Index<RangeToInclusive<u8>> for ArrayString<SIZE>
385where
386 SIZE: Capacity,
387{
388 type Output = str;
389
390 #[inline]
391 fn index(&self, index: RangeToInclusive<u8>) -> &Self::Output {
392 let end = index.end as usize;
393 self.as_str().index(RangeToInclusive { end })
394 }
395}
396
397impl<SIZE> Index<RangeInclusive<u8>> for ArrayString<SIZE>
398where
399 SIZE: Capacity,
400{
401 type Output = str;
402
403 #[inline]
404 fn index(&self, index: RangeInclusive<u8>) -> &Self::Output {
405 let (start, end) = (*index.start() as usize, *index.end() as usize);
406 let range = RangeInclusive::new(start, end);
407 self.as_str().index(range)
408 }
409}