Add `BorrowFormatter`, a formatter that writes to an array or slice buffer. This formatter is backed by the existing `Formatter`. Signed-off-by: Andreas Hindborg <a.hindborg@xxxxxxxxxx> --- rust/kernel/str.rs | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index 488b0e97004ee..78b2f95eb3171 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -6,6 +6,7 @@ use crate::prelude::*; use core::{ fmt::{self, Write}, + marker::PhantomData, ops::{self, Deref, DerefMut, Index}, }; @@ -702,7 +703,7 @@ fn test_bstr_debug() -> Result { /// /// The memory region between `pos` (inclusive) and `end` (exclusive) is valid for writes if `pos` /// is less than `end`. -pub(crate) struct RawFormatter { +pub struct RawFormatter { // Use `usize` to use `saturating_*` functions. beg: usize, pos: usize, @@ -760,7 +761,7 @@ pub(crate) fn pos(&self) -> *mut u8 { } /// Returns the number of bytes written to the formatter. - pub(crate) fn bytes_written(&self) -> usize { + pub fn bytes_written(&self) -> usize { self.pos - self.beg } } @@ -794,7 +795,7 @@ fn write_str(&mut self, s: &str) -> fmt::Result { /// Allows formatting of [`fmt::Arguments`] into a raw buffer. /// /// Fails if callers attempt to write more than will fit in the buffer. -pub(crate) struct Formatter(RawFormatter); +pub struct Formatter(RawFormatter); impl Formatter { /// Creates a new instance of [`Formatter`] with the given buffer. @@ -830,6 +831,35 @@ fn write_str(&mut self, s: &str) -> fmt::Result { } } +/// A mutable reference to a byte buffer where a string can be written into. +pub struct BorrowFormatter<'a>(Formatter, PhantomData<&'a mut ()>); + +impl<'a> BorrowFormatter<'a> { + /// Create a new [`Self`] instance. + pub fn new(buffer: &'a mut [u8]) -> Result<BorrowFormatter<'a>> { + Ok(Self( + // SAFETY: `buffer` is valid for writes for the entire length for + // the lifetime of `Self`. + unsafe { Formatter::from_buffer(buffer.as_mut_ptr(), buffer.len()) }, + PhantomData, + )) + } +} + +impl Deref for BorrowFormatter<'_> { + type Target = Formatter; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for BorrowFormatter<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + /// An owned string that is guaranteed to have exactly one `NUL` byte, which is at the end. /// /// Used for interoperability with kernel APIs that take C strings. -- 2.47.2