1use core::ops::{Deref, DerefMut};
16use core::str::Utf8Error;
17
18use tiny_vec::TinyVec;
19
20pub struct TinyString<const N: usize>(TinyVec<u8, N>);
21
22impl<const N: usize> TinyString<N> {
23 #[inline]
24 pub const fn new() -> Self {
25 Self(TinyVec::new())
26 }
27
28 pub fn with_capacity(cap: usize) -> Self {
29 Self(TinyVec::with_capacity(cap))
30
31 }
32
33 pub fn from_utf8(utf8: Vec<u8>) -> Result<Self,Utf8Error> {
34 str::from_utf8(&utf8)?;
35 Ok(Self(utf8.into()))
36 }
37
38 #[inline(always)]
41 pub const unsafe fn from_utf8_unchecked(utf8: TinyVec<u8, N>) -> Self {
42 Self(utf8)
43 }
44
45 pub fn push(&mut self, c: char) {
46 let len = c.len_utf8();
47 let mut buf = [0_u8; 4];
48 c.encode_utf8(&mut buf);
49 self.0.push_slice(&buf[..len]);
50 }
51
52 pub fn push_str(&mut self, s: &str) {
53 self.0.push_slice(s.as_bytes());
54 }
55
56 pub fn shrink_to_fit(&mut self) {
57 self.0.shrink_to_fit();
58 }
59
60 pub const fn capacity(&self) -> usize { self.0.capacity() }
61}
62
63impl<const N: usize> Default for TinyString<N> {
64 fn default() -> Self {
65 Self::new()
66 }
67}
68
69impl<const N: usize> Deref for TinyString<N> {
70 type Target = str;
71
72 fn deref(&self) -> &Self::Target {
73 unsafe {
74 str::from_utf8_unchecked(&self.0)
75 }
76 }
77}
78
79impl<const N: usize> DerefMut for TinyString<N> {
80 fn deref_mut(&mut self) -> &mut Self::Target {
81 unsafe {
82 str::from_utf8_unchecked_mut(&mut self.0)
83 }
84 }
85}
86
87impl<S, const N: usize> From<S> for TinyString<N>
88where
89 S: AsRef<str>,
90{
91 fn from(value: S) -> Self {
92 let value = value.as_ref();
93 let mut s = Self::with_capacity(value.len());
94 s.push_str(value);
95 s
96 }
97}
98
99#[cfg(test)]
100mod test;