1use core::mem;
2
3pub struct Buffer<T> {
7 inner: core::mem::MaybeUninit<T>,
8 offset: u8,
9}
10
11impl<S: Sized> Buffer<S> {
12 #[inline]
13 pub const fn new() -> Self {
15 Self {
16 inner: core::mem::MaybeUninit::uninit(),
17 offset: 0,
18 }
19 }
20
21 #[inline]
22 pub const fn as_ptr(&self) -> *const u8 {
24 &self.inner as *const _ as *const u8
25 }
26
27 #[inline]
28 pub const fn capacity() -> usize {
30 mem::size_of::<S>()
31 }
32
33 #[inline(always)]
34 pub fn as_str(&self) -> &str {
38 unsafe {
39 let slice = core::slice::from_raw_parts(self.as_ptr().offset(self.offset as isize), Self::capacity() - self.offset as usize);
40 core::str::from_utf8_unchecked(slice)
41 }
42 }
43
44 #[inline]
45 pub fn write<T: crate::ToStr>(&mut self, val: T) -> &str {
50 self.offset = (Self::capacity() - self.format(val).len()) as u8;
51 self.as_str()
52 }
53
54 #[inline(always)]
55 pub fn format<T: crate::ToStr>(&mut self, val: T) -> &str {
59 debug_assert!(Self::capacity() <= u8::max_value() as usize);
62 debug_assert!(T::TEXT_SIZE <= Self::capacity());
63
64 val.to_str(unsafe {
65 &mut *core::ptr::slice_from_raw_parts_mut(self.as_ptr() as *mut u8, Self::capacity())
66 })
67 }
68
69 #[inline(always)]
70 pub fn fmt<T: crate::ToStr>(val: T) -> Self {
72 let mut this = Self::new();
73 this.write(val);
74 this
75 }
76}
77
78impl<S: Sized> AsRef<str> for Buffer<S> {
79 #[inline(always)]
80 fn as_ref(&self) -> &str {
81 self.as_str()
82 }
83}
84
85impl<S: Sized> core::fmt::Display for Buffer<S> {
86 #[inline(always)]
87 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
88 f.write_str(self.as_str())
89 }
90}
91
92impl<S: Sized> core::fmt::Debug for Buffer<S> {
93 #[inline(always)]
94 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
95 f.write_str(self.as_str())
96 }
97}