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