A custom OS for the xteink x4 ebook reader
at main 91 lines 1.9 kB view raw
1// no-alloc fmt::Write buffers; silently truncate on overflow 2 3pub struct StackFmt<const N: usize> { 4 buf: [u8; N], 5 len: usize, 6} 7 8impl<const N: usize> Default for StackFmt<N> { 9 fn default() -> Self { 10 Self::new() 11 } 12} 13 14impl<const N: usize> StackFmt<N> { 15 pub const fn new() -> Self { 16 Self { 17 buf: [0u8; N], 18 len: 0, 19 } 20 } 21 22 #[inline] 23 pub fn as_str(&self) -> &str { 24 core::str::from_utf8(&self.buf[..self.len]).unwrap_or("") 25 } 26 27 #[inline] 28 pub fn is_empty(&self) -> bool { 29 self.len == 0 30 } 31 32 #[inline] 33 pub fn clear(&mut self) { 34 self.len = 0; 35 } 36} 37 38impl<const N: usize> core::fmt::Write for StackFmt<N> { 39 fn write_str(&mut self, s: &str) -> core::fmt::Result { 40 let bytes = s.as_bytes(); 41 let n = bytes.len().min(N - self.len); 42 self.buf[self.len..self.len + n].copy_from_slice(&bytes[..n]); 43 self.len += n; 44 Ok(()) 45 } 46} 47 48pub struct BorrowedFmt<'a> { 49 buf: &'a mut [u8], 50 pos: usize, 51} 52 53impl<'a> BorrowedFmt<'a> { 54 #[inline] 55 pub fn new(buf: &'a mut [u8]) -> Self { 56 Self { buf, pos: 0 } 57 } 58 59 #[inline] 60 pub fn as_str(&self) -> &str { 61 core::str::from_utf8(&self.buf[..self.pos]).unwrap_or("") 62 } 63 64 #[inline] 65 pub fn len(&self) -> usize { 66 self.pos 67 } 68 69 #[inline] 70 pub fn is_empty(&self) -> bool { 71 self.pos == 0 72 } 73} 74 75impl core::fmt::Write for BorrowedFmt<'_> { 76 fn write_str(&mut self, s: &str) -> core::fmt::Result { 77 let bytes = s.as_bytes(); 78 let room = self.buf.len() - self.pos; 79 let n = bytes.len().min(room); 80 self.buf[self.pos..self.pos + n].copy_from_slice(&bytes[..n]); 81 self.pos += n; 82 Ok(()) 83 } 84} 85 86#[inline] 87pub fn stack_fmt(buf: &mut [u8], f: impl FnOnce(&mut BorrowedFmt<'_>)) -> usize { 88 let mut w = BorrowedFmt::new(buf); 89 f(&mut w); 90 w.pos 91}