devela/text/fmt/
buf.rs
1use crate::{iif, FmtResult, FmtWrite, _core::cmp::min};
7crate::_use! {compat::from_utf8}
8
9#[macro_export]
27#[cfg_attr(cargo_primary_package, doc(hidden))]
28macro_rules! format_buf {
29 ($buf:expr, $($arg:tt)*) => {
30 $crate::Fmt::format_buf($buf, $crate::format_args![$($arg)*])
31 };
32}
33#[doc(inline)]
34pub use format_buf;
35
36#[derive(Debug)]
38pub(super) struct WriteTo<'a> {
39 buf: &'a mut [u8],
40 len: usize,
42 pub(super) truncated: bool,
44}
45impl<'a> WriteTo<'a> {
46 pub(super) const fn new(buf: &'a mut [u8]) -> Self {
47 WriteTo { buf, len: 0, truncated: false }
48 }
49
50 pub(super) fn as_str(self) -> &'a str {
55 match from_utf8(&self.buf[..self.len]) {
56 Ok(valid_str) => valid_str,
57 Err(e) => {
58 let valid_len = e.valid_up_to();
59 #[cfg(any(feature = "safe_text", not(feature = "unsafe_str")))]
60 {
61 from_utf8(&self.buf[..valid_len]).unwrap()
62 }
63 #[cfg(all(not(feature = "safe_text"), feature = "unsafe_str"))]
64 {
65 unsafe { ::core::str::from_utf8_unchecked(&self.buf[..valid_len]) }
67 }
68 }
69 }
70 }
71}
72impl FmtWrite for WriteTo<'_> {
73 fn write_str(&mut self, s: &str) -> FmtResult<()> {
74 let available = self.buf.len().saturating_sub(self.len);
75 let s_bytes = s.as_bytes();
76 let n = min(s_bytes.len(), available);
77 iif![n > 0; self.buf[self.len..self.len + n].copy_from_slice(&s_bytes[..n])];
78 iif![n < s_bytes.len(); self.truncated = true];
79 self.len += n;
80 Ok(())
81 }
82}