1 | use crate::fmt; |
2 | use crate::mem::MaybeUninit; |
3 | use crate::str; |
4 | |
5 | /// Used for slow path in `Display` implementations when alignment is required. |
6 | pub struct DisplayBuffer<const SIZE: usize> { |
7 | buf: [MaybeUninit<u8>; SIZE], |
8 | len: usize, |
9 | } |
10 | |
11 | impl<const SIZE: usize> DisplayBuffer<SIZE> { |
12 | #[inline ] |
13 | pub const fn new() -> Self { |
14 | Self { buf: MaybeUninit::uninit_array(), len: 0 } |
15 | } |
16 | |
17 | #[inline ] |
18 | pub fn as_str(&self) -> &str { |
19 | // SAFETY: `buf` is only written to by the `fmt::Write::write_str` implementation |
20 | // which writes a valid UTF-8 string to `buf` and correctly sets `len`. |
21 | unsafe { |
22 | let s: &[u8] = MaybeUninit::slice_assume_init_ref(&self.buf[..self.len]); |
23 | str::from_utf8_unchecked(s) |
24 | } |
25 | } |
26 | } |
27 | |
28 | impl<const SIZE: usize> fmt::Write for DisplayBuffer<SIZE> { |
29 | fn write_str(&mut self, s: &str) -> fmt::Result { |
30 | let bytes: &[u8] = s.as_bytes(); |
31 | |
32 | if let Some(buf: &mut [MaybeUninit]) = self.buf.get_mut(self.len..(self.len + bytes.len())) { |
33 | MaybeUninit::copy_from_slice(this:buf, src:bytes); |
34 | self.len += bytes.len(); |
35 | Ok(()) |
36 | } else { |
37 | Err(fmt::Error) |
38 | } |
39 | } |
40 | } |
41 | |