1use core::{cmp::Ordering, fmt, fmt::Write, hash, iter, ops, str};
2
3use hash32;
4
5use crate::Vec;
6
7pub struct String<const N: usize> {
9 vec: Vec<u8, N>,
10}
11
12impl<const N: usize> String<N> {
13 #[inline]
29 pub const fn new() -> Self {
30 Self { vec: Vec::new() }
31 }
32
33 #[inline]
51 pub fn into_bytes(self) -> Vec<u8, N> {
52 self.vec
53 }
54
55 #[inline]
71 pub fn as_str(&self) -> &str {
72 unsafe { str::from_utf8_unchecked(self.vec.as_slice()) }
73 }
74
75 #[inline]
89 pub fn as_mut_str(&mut self) -> &mut str {
90 unsafe { str::from_utf8_unchecked_mut(self.vec.as_mut_slice()) }
91 }
92
93 pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8, N> {
118 &mut self.vec
119 }
120
121 #[inline]
139 pub fn push_str(&mut self, string: &str) -> Result<(), ()> {
140 self.vec.extend_from_slice(string.as_bytes())
141 }
142
143 #[inline]
156 pub fn capacity(&self) -> usize {
157 self.vec.capacity()
158 }
159
160 #[inline]
182 pub fn push(&mut self, c: char) -> Result<(), ()> {
183 match c.len_utf8() {
184 1 => self.vec.push(c as u8).map_err(|_| {}),
185 _ => self
186 .vec
187 .extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()),
188 }
189 }
190
191 #[inline]
219 pub fn truncate(&mut self, new_len: usize) {
220 if new_len <= self.len() {
221 assert!(self.is_char_boundary(new_len));
222 self.vec.truncate(new_len)
223 }
224 }
225
226 pub fn pop(&mut self) -> Option<char> {
248 let ch = self.chars().rev().next()?;
249
250 for _ in 0..ch.len_utf8() {
252 unsafe {
253 self.vec.pop_unchecked();
254 }
255 }
256
257 Some(ch)
258 }
259
260 #[inline]
281 pub fn clear(&mut self) {
282 self.vec.clear()
283 }
284}
285
286impl<const N: usize> Default for String<N> {
287 fn default() -> Self {
288 Self::new()
289 }
290}
291
292impl<'a, const N: usize> From<&'a str> for String<N> {
293 fn from(s: &'a str) -> Self {
294 let mut new = String::new();
295 new.push_str(s).unwrap();
296 new
297 }
298}
299
300impl<const N: usize> str::FromStr for String<N> {
301 type Err = ();
302
303 fn from_str(s: &str) -> Result<Self, Self::Err> {
304 let mut new = String::new();
305 new.push_str(s)?;
306 Ok(new)
307 }
308}
309
310impl<const N: usize> iter::FromIterator<char> for String<N> {
311 fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
312 let mut new = String::new();
313 for c in iter {
314 new.push(c).unwrap();
315 }
316 new
317 }
318}
319
320impl<'a, const N: usize> iter::FromIterator<&'a char> for String<N> {
321 fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
322 let mut new = String::new();
323 for c in iter {
324 new.push(*c).unwrap();
325 }
326 new
327 }
328}
329
330impl<'a, const N: usize> iter::FromIterator<&'a str> for String<N> {
331 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
332 let mut new = String::new();
333 for c in iter {
334 new.push_str(c).unwrap();
335 }
336 new
337 }
338}
339
340impl<const N: usize> Clone for String<N> {
341 fn clone(&self) -> Self {
342 Self {
343 vec: self.vec.clone(),
344 }
345 }
346}
347
348impl<const N: usize> fmt::Debug for String<N> {
349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350 <str as fmt::Debug>::fmt(self, f)
351 }
352}
353
354impl<const N: usize> fmt::Display for String<N> {
355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356 <str as fmt::Display>::fmt(self, f)
357 }
358}
359
360impl<const N: usize> hash::Hash for String<N> {
361 #[inline]
362 fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
363 <str as hash::Hash>::hash(self, hasher)
364 }
365}
366
367impl<const N: usize> hash32::Hash for String<N> {
368 #[inline]
369 fn hash<H: hash32::Hasher>(&self, hasher: &mut H) {
370 <str as hash32::Hash>::hash(self, hasher)
371 }
372}
373
374impl<const N: usize> fmt::Write for String<N> {
375 fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
376 self.push_str(s).map_err(|_| fmt::Error)
377 }
378
379 fn write_char(&mut self, c: char) -> Result<(), fmt::Error> {
380 self.push(c).map_err(|_| fmt::Error)
381 }
382}
383
384impl<const N: usize> ops::Deref for String<N> {
385 type Target = str;
386
387 fn deref(&self) -> &str {
388 self.as_str()
389 }
390}
391
392impl<const N: usize> ops::DerefMut for String<N> {
393 fn deref_mut(&mut self) -> &mut str {
394 self.as_mut_str()
395 }
396}
397
398impl<const N: usize> AsRef<str> for String<N> {
399 #[inline]
400 fn as_ref(&self) -> &str {
401 self
402 }
403}
404
405impl<const N: usize> AsRef<[u8]> for String<N> {
406 #[inline]
407 fn as_ref(&self) -> &[u8] {
408 self.as_bytes()
409 }
410}
411
412impl<const N1: usize, const N2: usize> PartialEq<String<N2>> for String<N1> {
413 fn eq(&self, rhs: &String<N2>) -> bool {
414 str::eq(&**self, &**rhs)
415 }
416
417 fn ne(&self, rhs: &String<N2>) -> bool {
418 str::ne(&**self, &**rhs)
419 }
420}
421
422impl<const N: usize> PartialEq<str> for String<N> {
424 #[inline]
425 fn eq(&self, other: &str) -> bool {
426 str::eq(&self[..], &other[..])
427 }
428 #[inline]
429 fn ne(&self, other: &str) -> bool {
430 str::ne(&self[..], &other[..])
431 }
432}
433
434impl<const N: usize> PartialEq<&str> for String<N> {
436 #[inline]
437 fn eq(&self, other: &&str) -> bool {
438 str::eq(&self[..], &other[..])
439 }
440 #[inline]
441 fn ne(&self, other: &&str) -> bool {
442 str::ne(&self[..], &other[..])
443 }
444}
445
446impl<const N: usize> PartialEq<String<N>> for str {
448 #[inline]
449 fn eq(&self, other: &String<N>) -> bool {
450 str::eq(&self[..], &other[..])
451 }
452 #[inline]
453 fn ne(&self, other: &String<N>) -> bool {
454 str::ne(&self[..], &other[..])
455 }
456}
457
458impl<const N: usize> PartialEq<String<N>> for &str {
460 #[inline]
461 fn eq(&self, other: &String<N>) -> bool {
462 str::eq(&self[..], &other[..])
463 }
464 #[inline]
465 fn ne(&self, other: &String<N>) -> bool {
466 str::ne(&self[..], &other[..])
467 }
468}
469
470impl<const N: usize> Eq for String<N> {}
471
472impl<const N1: usize, const N2: usize> PartialOrd<String<N2>> for String<N1> {
473 #[inline]
474 fn partial_cmp(&self, other: &String<N2>) -> Option<Ordering> {
475 PartialOrd::partial_cmp(&**self, &**other)
476 }
477}
478
479impl<const N: usize> Ord for String<N> {
480 #[inline]
481 fn cmp(&self, other: &Self) -> Ordering {
482 Ord::cmp(&**self, &**other)
483 }
484}
485
486macro_rules! impl_from_num {
487 ($num:ty, $size:expr) => {
488 impl<const N: usize> From<$num> for String<N> {
489 fn from(s: $num) -> Self {
490 let mut new = String::new();
491 write!(&mut new, "{}", s).unwrap();
492 new
493 }
494 }
495 };
496}
497
498impl_from_num!(i8, 4);
499impl_from_num!(i16, 6);
500impl_from_num!(i32, 11);
501impl_from_num!(i64, 20);
502
503impl_from_num!(u8, 3);
504impl_from_num!(u16, 5);
505impl_from_num!(u32, 10);
506impl_from_num!(u64, 20);
507
508#[cfg(test)]
509mod tests {
510 use crate::{String, Vec};
511
512 #[test]
513 fn static_new() {
514 static mut _S: String<8> = String::new();
515 }
516
517 #[test]
518 fn clone() {
519 let s1: String<20> = String::from("abcd");
520 let mut s2 = s1.clone();
521 s2.push_str(" efgh").unwrap();
522
523 assert_eq!(s1, "abcd");
524 assert_eq!(s2, "abcd efgh");
525 }
526
527 #[test]
528 fn cmp() {
529 let s1: String<4> = String::from("abcd");
530 let s2: String<4> = String::from("zzzz");
531
532 assert!(s1 < s2);
533 }
534
535 #[test]
536 fn cmp_heterogenous_size() {
537 let s1: String<4> = String::from("abcd");
538 let s2: String<8> = String::from("zzzz");
539
540 assert!(s1 < s2);
541 }
542
543 #[test]
544 fn debug() {
545 use core::fmt::Write;
546
547 let s: String<8> = String::from("abcd");
548 let mut std_s = std::string::String::new();
549 write!(std_s, "{:?}", s).unwrap();
550 assert_eq!("\"abcd\"", std_s);
551 }
552
553 #[test]
554 fn display() {
555 use core::fmt::Write;
556
557 let s: String<8> = String::from("abcd");
558 let mut std_s = std::string::String::new();
559 write!(std_s, "{}", s).unwrap();
560 assert_eq!("abcd", std_s);
561 }
562
563 #[test]
564 fn empty() {
565 let s: String<4> = String::new();
566 assert!(s.capacity() == 4);
567 assert_eq!(s, "");
568 assert_eq!(s.len(), 0);
569 assert_ne!(s.len(), 4);
570 }
571
572 #[test]
573 fn from() {
574 let s: String<4> = String::from("123");
575 assert!(s.len() == 3);
576 assert_eq!(s, "123");
577 }
578
579 #[test]
580 fn from_str() {
581 use core::str::FromStr;
582
583 let s: String<4> = String::<4>::from_str("123").unwrap();
584 assert!(s.len() == 3);
585 assert_eq!(s, "123");
586
587 let e: () = String::<2>::from_str("123").unwrap_err();
588 assert_eq!(e, ());
589 }
590
591 #[test]
592 fn from_iter() {
593 let mut v: Vec<char, 5> = Vec::new();
594 v.push('h').unwrap();
595 v.push('e').unwrap();
596 v.push('l').unwrap();
597 v.push('l').unwrap();
598 v.push('o').unwrap();
599 let string1: String<5> = v.iter().collect(); let string2: String<5> = "hello".chars().collect(); assert_eq!(string1, "hello");
602 assert_eq!(string2, "hello");
603 }
604
605 #[test]
606 #[should_panic]
607 fn from_panic() {
608 let _: String<4> = String::from("12345");
609 }
610
611 #[test]
612 fn from_num() {
613 let v: String<20> = String::from(18446744073709551615 as u64);
614 assert_eq!(v, "18446744073709551615");
615 }
616
617 #[test]
618 fn into_bytes() {
619 let s: String<4> = String::from("ab");
620 let b: Vec<u8, 4> = s.into_bytes();
621 assert_eq!(b.len(), 2);
622 assert_eq!(&['a' as u8, 'b' as u8], &b[..]);
623 }
624
625 #[test]
626 fn as_str() {
627 let s: String<4> = String::from("ab");
628
629 assert_eq!(s.as_str(), "ab");
630 }
634
635 #[test]
636 fn as_mut_str() {
637 let mut s: String<4> = String::from("ab");
638 let s = s.as_mut_str();
639 s.make_ascii_uppercase();
640 assert_eq!(s, "AB");
641 }
642
643 #[test]
644 fn push_str() {
645 let mut s: String<8> = String::from("foo");
646 assert!(s.push_str("bar").is_ok());
647 assert_eq!("foobar", s);
648 assert_eq!(s, "foobar");
649 assert!(s.push_str("tender").is_err());
650 assert_eq!("foobar", s);
651 assert_eq!(s, "foobar");
652 }
653
654 #[test]
655 fn push() {
656 let mut s: String<6> = String::from("abc");
657 assert!(s.push('1').is_ok());
658 assert!(s.push('2').is_ok());
659 assert!(s.push('3').is_ok());
660 assert!(s.push('4').is_err());
661 assert!("abc123" == s.as_str());
662 }
663
664 #[test]
665 fn as_bytes() {
666 let s: String<8> = String::from("hello");
667 assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
668 }
669
670 #[test]
671 fn truncate() {
672 let mut s: String<8> = String::from("hello");
673 s.truncate(6);
674 assert_eq!(s.len(), 5);
675 s.truncate(2);
676 assert_eq!(s.len(), 2);
677 assert_eq!("he", s);
678 assert_eq!(s, "he");
679 }
680
681 #[test]
682 fn pop() {
683 let mut s: String<8> = String::from("foo");
684 assert_eq!(s.pop(), Some('o'));
685 assert_eq!(s.pop(), Some('o'));
686 assert_eq!(s.pop(), Some('f'));
687 assert_eq!(s.pop(), None);
688 }
689
690 #[test]
691 fn pop_uenc() {
692 let mut s: String<8> = String::from("é");
693 assert_eq!(s.len(), 3);
694 match s.pop() {
695 Some(c) => {
696 assert_eq!(s.len(), 1);
697 assert_eq!(c, '\u{0301}'); ()
699 }
700 None => assert!(false),
701 };
702 }
703
704 #[test]
705 fn is_empty() {
706 let mut v: String<8> = String::new();
707 assert!(v.is_empty());
708 let _ = v.push('a');
709 assert!(!v.is_empty());
710 }
711
712 #[test]
713 fn clear() {
714 let mut s: String<8> = String::from("foo");
715 s.clear();
716 assert!(s.is_empty());
717 assert_eq!(0, s.len());
718 assert_eq!(8, s.capacity());
719 }
720}