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 const fn as_mut_ptr(&mut self) -> *mut u8 {
30 self.inner.as_mut_ptr() as _
31 }
32
33 #[inline]
34 pub const fn capacity() -> usize {
36 mem::size_of::<S>()
37 }
38
39 #[inline(always)]
40 pub fn as_str(&self) -> &str {
44 unsafe {
45 let slice = core::slice::from_raw_parts(self.as_ptr().offset(self.offset as isize), Self::capacity() - self.offset as usize);
46 core::str::from_utf8_unchecked(slice)
47 }
48 }
49
50 #[inline]
51 pub fn write<T: crate::ToStr>(&mut self, val: T) -> &str {
56 self.offset = (Self::capacity() - self.format(val).len()) as u8;
57 self.as_str()
58 }
59
60 #[inline(always)]
61 pub fn format<T: crate::ToStr>(&mut self, val: T) -> &str {
65 debug_assert!(Self::capacity() <= u8::max_value() as usize);
68 debug_assert!(T::TEXT_SIZE <= Self::capacity());
69
70 val.to_str(unsafe {
71 &mut *core::ptr::slice_from_raw_parts_mut(self.as_mut_ptr() as *mut u8, Self::capacity())
72 })
73 }
74
75 #[inline(always)]
76 pub fn fmt<T: crate::ToStr>(val: T) -> Self {
78 let mut this = Self::new();
79 this.write(val);
80 this
81 }
82}
83
84impl<S: Sized> AsRef<str> for Buffer<S> {
85 #[inline(always)]
86 fn as_ref(&self) -> &str {
87 self.as_str()
88 }
89}
90
91impl<S: Sized> core::fmt::Display for Buffer<S> {
92 #[inline(always)]
93 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
94 f.write_str(self.as_str())
95 }
96}
97
98impl<S: Sized> core::fmt::Debug for Buffer<S> {
99 #[inline(always)]
100 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
101 f.write_str(self.as_str())
102 }
103}