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 | |