1use std::borrow::Borrow;
2use std::cmp;
3use std::fmt;
4use std::hash::{Hash, Hasher};
5use std::ptr;
6use std::ops::{Deref, DerefMut};
7use std::str;
8use std::str::FromStr;
9use std::str::Utf8Error;
10use std::slice;
11
12use crate::array::Array;
13use crate::array::Index;
14use crate::CapacityError;
15use crate::char::encode_utf8;
16
17#[cfg(feature="serde")]
18use serde::{Serialize, Deserialize, Serializer, Deserializer};
19
20use super::MaybeUninit as MaybeUninitCopy;
21
22#[derive(Copy)]
30pub struct ArrayString<A>
31 where A: Array<Item=u8> + Copy
32{
33 xs: MaybeUninitCopy<A>,
34 len: A::Index,
35}
36
37impl<A> Default for ArrayString<A>
38 where A: Array<Item=u8> + Copy
39{
40 fn default() -> ArrayString<A> {
42 ArrayString::new()
43 }
44}
45
46impl<A> ArrayString<A>
47 where A: Array<Item=u8> + Copy
48{
49 #[cfg(not(feature="unstable-const-fn"))]
62 pub fn new() -> ArrayString<A> {
63 unsafe {
64 ArrayString {
65 xs: MaybeUninitCopy::uninitialized(),
66 len: Index::ZERO,
67 }
68 }
69 }
70
71 #[cfg(feature="unstable-const-fn")]
72 pub const fn new() -> ArrayString<A> {
73 unsafe {
74 ArrayString {
75 xs: MaybeUninitCopy::uninitialized(),
76 len: Index::ZERO,
77 }
78 }
79 }
80
81 #[inline]
83 pub fn len(&self) -> usize { self.len.to_usize() }
84
85 #[inline]
87 pub fn is_empty(&self) -> bool { self.len() == 0 }
88
89 pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
104 let mut arraystr = Self::new();
105 arraystr.try_push_str(s)?;
106 Ok(arraystr)
107 }
108
109 pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> {
119 let len = str::from_utf8(b.as_slice())?.len();
120 debug_assert_eq!(len, A::CAPACITY);
121 Ok(ArrayString {
122 xs: MaybeUninitCopy::from(*b),
123 len: Index::from(A::CAPACITY),
124 })
125 }
126
127 #[inline(always)]
136 pub fn capacity(&self) -> usize { A::CAPACITY }
137
138 pub fn is_full(&self) -> bool { self.len() == self.capacity() }
149
150 pub fn push(&mut self, c: char) {
165 self.try_push(c).unwrap();
166 }
167
168 pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
187 let len = self.len();
188 unsafe {
189 let ptr = self.xs.ptr_mut().add(len);
190 let remaining_cap = self.capacity() - len;
191 match encode_utf8(c, ptr, remaining_cap) {
192 Ok(n) => {
193 self.set_len(len + n);
194 Ok(())
195 }
196 Err(_) => Err(CapacityError::new(c)),
197 }
198 }
199 }
200
201 pub fn push_str(&mut self, s: &str) {
216 self.try_push_str(s).unwrap()
217 }
218
219 pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
240 if s.len() > self.capacity() - self.len() {
241 return Err(CapacityError::new(s));
242 }
243 unsafe {
244 let dst = self.xs.ptr_mut().add(self.len());
245 let src = s.as_ptr();
246 ptr::copy_nonoverlapping(src, dst, s.len());
247 let newl = self.len() + s.len();
248 self.set_len(newl);
249 }
250 Ok(())
251 }
252
253 pub fn pop(&mut self) -> Option<char> {
269 let ch = match self.chars().rev().next() {
270 Some(ch) => ch,
271 None => return None,
272 };
273 let new_len = self.len() - ch.len_utf8();
274 unsafe {
275 self.set_len(new_len);
276 }
277 Some(ch)
278 }
279
280 pub fn truncate(&mut self, new_len: usize) {
297 if new_len <= self.len() {
298 assert!(self.is_char_boundary(new_len));
299 unsafe {
300 self.set_len(new_len);
305 }
306 }
307 }
308
309 pub fn remove(&mut self, idx: usize) -> char {
327 let ch = match self[idx..].chars().next() {
328 Some(ch) => ch,
329 None => panic!("cannot remove a char from the end of a string"),
330 };
331
332 let next = idx + ch.len_utf8();
333 let len = self.len();
334 unsafe {
335 ptr::copy(self.xs.ptr().add(next),
336 self.xs.ptr_mut().add(idx),
337 len - next);
338 self.set_len(len - (next - idx));
339 }
340 ch
341 }
342
343 pub fn clear(&mut self) {
345 unsafe {
346 self.set_len(0);
347 }
348 }
349
350 pub unsafe fn set_len(&mut self, length: usize) {
358 debug_assert!(length <= self.capacity());
359 self.len = Index::from(length);
360 }
361
362 pub fn as_str(&self) -> &str {
364 self
365 }
366}
367
368impl<A> Deref for ArrayString<A>
369 where A: Array<Item=u8> + Copy
370{
371 type Target = str;
372 #[inline]
373 fn deref(&self) -> &str {
374 unsafe {
375 let sl = slice::from_raw_parts(self.xs.ptr(), self.len.to_usize());
376 str::from_utf8_unchecked(sl)
377 }
378 }
379}
380
381impl<A> DerefMut for ArrayString<A>
382 where A: Array<Item=u8> + Copy
383{
384 #[inline]
385 fn deref_mut(&mut self) -> &mut str {
386 unsafe {
387 let sl = slice::from_raw_parts_mut(self.xs.ptr_mut(), self.len.to_usize());
388 str::from_utf8_unchecked_mut(sl)
389 }
390 }
391}
392
393impl<A> PartialEq for ArrayString<A>
394 where A: Array<Item=u8> + Copy
395{
396 fn eq(&self, rhs: &Self) -> bool {
397 **self == **rhs
398 }
399}
400
401impl<A> PartialEq<str> for ArrayString<A>
402 where A: Array<Item=u8> + Copy
403{
404 fn eq(&self, rhs: &str) -> bool {
405 &**self == rhs
406 }
407}
408
409impl<A> PartialEq<ArrayString<A>> for str
410 where A: Array<Item=u8> + Copy
411{
412 fn eq(&self, rhs: &ArrayString<A>) -> bool {
413 self == &**rhs
414 }
415}
416
417impl<A> Eq for ArrayString<A>
418 where A: Array<Item=u8> + Copy
419{ }
420
421impl<A> Hash for ArrayString<A>
422 where A: Array<Item=u8> + Copy
423{
424 fn hash<H: Hasher>(&self, h: &mut H) {
425 (**self).hash(h)
426 }
427}
428
429impl<A> Borrow<str> for ArrayString<A>
430 where A: Array<Item=u8> + Copy
431{
432 fn borrow(&self) -> &str { self }
433}
434
435impl<A> AsRef<str> for ArrayString<A>
436 where A: Array<Item=u8> + Copy
437{
438 fn as_ref(&self) -> &str { self }
439}
440
441impl<A> fmt::Debug for ArrayString<A>
442 where A: Array<Item=u8> + Copy
443{
444 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
445}
446
447impl<A> fmt::Display for ArrayString<A>
448 where A: Array<Item=u8> + Copy
449{
450 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
451}
452
453impl<A> fmt::Write for ArrayString<A>
455 where A: Array<Item=u8> + Copy
456{
457 fn write_char(&mut self, c: char) -> fmt::Result {
458 self.try_push(c).map_err(|_| fmt::Error)
459 }
460
461 fn write_str(&mut self, s: &str) -> fmt::Result {
462 self.try_push_str(s).map_err(|_| fmt::Error)
463 }
464}
465
466impl<A> Clone for ArrayString<A>
467 where A: Array<Item=u8> + Copy
468{
469 fn clone(&self) -> ArrayString<A> {
470 *self
471 }
472 fn clone_from(&mut self, rhs: &Self) {
473 self.clear();
475 self.try_push_str(rhs).ok();
476 }
477}
478
479impl<A> PartialOrd for ArrayString<A>
480 where A: Array<Item=u8> + Copy
481{
482 fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
483 (**self).partial_cmp(&**rhs)
484 }
485 fn lt(&self, rhs: &Self) -> bool { **self < **rhs }
486 fn le(&self, rhs: &Self) -> bool { **self <= **rhs }
487 fn gt(&self, rhs: &Self) -> bool { **self > **rhs }
488 fn ge(&self, rhs: &Self) -> bool { **self >= **rhs }
489}
490
491impl<A> PartialOrd<str> for ArrayString<A>
492 where A: Array<Item=u8> + Copy
493{
494 fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> {
495 (**self).partial_cmp(rhs)
496 }
497 fn lt(&self, rhs: &str) -> bool { &**self < rhs }
498 fn le(&self, rhs: &str) -> bool { &**self <= rhs }
499 fn gt(&self, rhs: &str) -> bool { &**self > rhs }
500 fn ge(&self, rhs: &str) -> bool { &**self >= rhs }
501}
502
503impl<A> PartialOrd<ArrayString<A>> for str
504 where A: Array<Item=u8> + Copy
505{
506 fn partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering> {
507 self.partial_cmp(&**rhs)
508 }
509 fn lt(&self, rhs: &ArrayString<A>) -> bool { self < &**rhs }
510 fn le(&self, rhs: &ArrayString<A>) -> bool { self <= &**rhs }
511 fn gt(&self, rhs: &ArrayString<A>) -> bool { self > &**rhs }
512 fn ge(&self, rhs: &ArrayString<A>) -> bool { self >= &**rhs }
513}
514
515impl<A> Ord for ArrayString<A>
516 where A: Array<Item=u8> + Copy
517{
518 fn cmp(&self, rhs: &Self) -> cmp::Ordering {
519 (**self).cmp(&**rhs)
520 }
521}
522
523impl<A> FromStr for ArrayString<A>
524 where A: Array<Item=u8> + Copy
525{
526 type Err = CapacityError;
527
528 fn from_str(s: &str) -> Result<Self, Self::Err> {
529 Self::from(s).map_err(CapacityError::simplify)
530 }
531}
532
533#[cfg(feature="serde")]
534impl<A> Serialize for ArrayString<A>
536 where A: Array<Item=u8> + Copy
537{
538 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
539 where S: Serializer
540 {
541 serializer.serialize_str(&*self)
542 }
543}
544
545#[cfg(feature="serde")]
546impl<'de, A> Deserialize<'de> for ArrayString<A>
548 where A: Array<Item=u8> + Copy
549{
550 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
551 where D: Deserializer<'de>
552 {
553 use serde::de::{self, Visitor};
554 use std::marker::PhantomData;
555
556 struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>);
557
558 impl<'de, A: Copy + Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> {
559 type Value = ArrayString<A>;
560
561 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
562 write!(formatter, "a string no more than {} bytes long", A::CAPACITY)
563 }
564
565 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
566 where E: de::Error,
567 {
568 ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self))
569 }
570
571 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
572 where E: de::Error,
573 {
574 let s = str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self))?;
575
576 ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self))
577 }
578 }
579
580 deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData))
581 }
582}