leodos_protocols/utils/
fmt.rs1pub struct BufWriter<'a> {
5 pub buf: &'a mut [u8],
7 pub pos: usize,
9}
10
11impl core::fmt::Write for BufWriter<'_> {
12 fn write_str(&mut self, s: &str) -> core::fmt::Result {
13 let b = s.as_bytes();
14 let end = self.pos + b.len();
15 if end > self.buf.len() {
16 return Err(core::fmt::Error);
17 }
18 self.buf[self.pos..end].copy_from_slice(b);
19 self.pos = end;
20 Ok(())
21 }
22}
23
24#[macro_export]
26macro_rules! fmt {
27 ($buf:expr, $($arg:tt)*) => {{
28 let mut w = $crate::utils::fmt::BufWriter { buf: $buf, pos: 0 };
29 match core::fmt::Write::write_fmt(&mut w, format_args!($($arg)*)) {
30 Ok(()) => Ok(w.pos),
31 Err(_) => Err(core::fmt::Error),
32 }
33 }};
34}
35
36pub struct CStrBuf<const N: usize> {
38 #[doc(hidden)]
39 pub buf: [u8; N],
40 #[doc(hidden)]
41 pub len: usize,
42}
43
44impl<const N: usize> CStrBuf<N> {
45 pub fn as_cstr(&self) -> &core::ffi::CStr {
47 core::ffi::CStr::from_bytes_until_nul(&self.buf[..self.len + 1]).unwrap()
48 }
49}
50
51impl<const N: usize> core::ops::Deref for CStrBuf<N> {
52 type Target = core::ffi::CStr;
53 fn deref(&self) -> &core::ffi::CStr {
54 self.as_cstr()
55 }
56}
57
58#[macro_export]
64macro_rules! fmt_cstr {
65 ($n:literal, $($arg:tt)*) => {{
66 let mut buf = [0u8; $n];
67 let mut w = $crate::utils::fmt::BufWriter { buf: &mut buf, pos: 0 };
68 match core::fmt::Write::write_fmt(&mut w, format_args!($($arg)*)) {
69 Ok(()) if w.pos < w.buf.len() => {
70 w.buf[w.pos] = 0;
71 let len = w.pos;
72 Ok($crate::utils::fmt::CStrBuf { buf, len })
73 }
74 _ => Err(core::fmt::Error),
75 }
76 }};
77 ($buf:expr, $($arg:tt)*) => {{
78 let buf: &mut [u8] = &mut $buf;
79 let mut w = $crate::utils::fmt::BufWriter { buf, pos: 0 };
80 match core::fmt::Write::write_fmt(&mut w, format_args!($($arg)*)) {
81 Ok(()) if w.pos < w.buf.len() => {
82 w.buf[w.pos] = 0;
83 Ok(core::ffi::CStr::from_bytes_until_nul(&w.buf[..w.pos + 1]).unwrap())
84 }
85 _ => Err(core::fmt::Error),
86 }
87 }};
88}