1use crate::Error;
2
3#[derive(Copy, Clone)]
4pub struct String<const N: usize> {
5 bytes: [u8; N],
6 len: u32, }
8
9impl<const N: usize> String<N> {
10 pub fn new() -> String<N> { String { bytes: [0; N], len: 0 } }
11
12 pub fn as_bytes(&self) -> [u8; N] { self.bytes }
13
14 pub fn as_str(&self) -> core::result::Result<&str, core::str::Utf8Error> {
15 core::str::from_utf8(&self.bytes[0..self.len as usize])
16 }
17
18 pub fn len(&self) -> usize { self.len as usize }
19
20 pub fn is_empty(&self) -> bool { self.len == 0 }
21
22 pub fn clear(&mut self) {
24 self.len = 0;
25 self.bytes = [0; N];
26 }
27
28 pub fn to_str(&self) -> &str { unsafe { core::str::from_utf8_unchecked(&self.bytes[0..self.len()]) } }
29
30 pub fn push(&mut self, ch: char) -> core::result::Result<usize, Error> {
31 match ch.len_utf8() {
32 1 => {
33 if self.len() < self.bytes.len() {
34 self.bytes[self.len()] = ch as u8;
35 self.len += 1;
36 Ok(1)
37 } else {
38 Err(Error::OutOfMemory)
39 }
40 }
41 _ => {
42 let mut bytes: usize = 0;
43 let mut data: [u8; 4] = [0; 4];
44 let subslice = ch.encode_utf8(&mut data);
45 if self.len() + subslice.len() < self.bytes.len() {
46 for c in subslice.bytes() {
47 self.bytes[self.len()] = c;
48 self.len += 1;
49 bytes += 1;
50 }
51 Ok(bytes)
52 } else {
53 Err(Error::OutOfMemory)
54 }
55 }
56 }
57 }
58
59 pub fn append(&mut self, s: &str) -> core::result::Result<usize, Error> {
60 let mut bytes_added = 0;
61 for ch in s.chars() {
62 if let Ok(bytes) = self.push(ch) {
63 bytes_added += bytes;
64 } else {
65 return Err(Error::OutOfMemory);
66 }
67 }
68 Ok(bytes_added)
69 }
70
71 pub fn push_byte(&mut self, b: u8) -> core::result::Result<(), Error> {
72 if self.len() < self.bytes.len() {
73 self.bytes[self.len()] = b;
74 self.len += 1;
75 Ok(())
76 } else {
77 Err(Error::OutOfMemory)
78 }
79 }
80}
81
82impl<const N: usize> Default for String<N> {
83 fn default() -> Self { Self::new() }
84}
85
86impl<const N: usize> core::str::FromStr for String<N> {
87 type Err = &'static str;
88
89 fn from_str(src: &str) -> core::result::Result<String<N>, &'static str> {
90 let mut s = Self::new();
91 for (&src_byte, dest_byte) in src.as_bytes().iter().zip(&mut s.bytes) {
93 *dest_byte = src_byte;
94 }
95 s.len = s.bytes.len().min(src.as_bytes().len()) as u32;
98
99 if s.as_str().is_err() {
101 s.len = 0;
102 }
103 Ok(s)
104 }
105}
106
107impl<const N: usize> core::fmt::Display for String<N> {
108 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.to_str()) }
109}
110
111impl<const N: usize> core::fmt::Write for String<N> {
112 fn write_str(&mut self, s: &str) -> core::result::Result<(), core::fmt::Error> {
113 for c in s.bytes() {
114 if self.len() < self.bytes.len() {
115 self.bytes[self.len()] = c;
116 self.len += 1;
117 }
118 }
119 Ok(())
120 }
121}
122
123impl<const N: usize> core::fmt::Debug for String<N> {
124 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.to_str()) }
125}
126
127impl<const N: usize> core::convert::AsRef<str> for String<N> {
128 fn as_ref(&self) -> &str { self.to_str() }
129}
130
131impl<const N: usize> PartialEq for String<N> {
132 fn eq(&self, other: &Self) -> bool {
133 self.bytes[..self.len as usize] == other.bytes[..other.len as usize] && self.len == other.len
134 }
135}
136
137impl<const N: usize> Eq for String<N> {}