pub struct BoxedFmt<F>where
F: MessageFormatter,{ /* private fields */ }Expand description
A specialized Service for dynamically dispatched string-based logging.
§Why this exists (The “Orphan Rule” Workaround)
In Rust, std::fmt::Write is not implemented for Box<dyn std::fmt::Write>.
While we could use a type alias for byte-based writers (BoxedFmt service),
doing so for string-based writers would require implementing a foreign trait on
a foreign type, which is forbidden by Rust’s “Orphan Rules.”
BoxedFmt service solves this by providing a concrete struct that “wraps”
the boxed trait object, allowing us to manually dispatch the write calls in the
work method.
Implementations§
Source§impl<F> BoxedFmt<F>where
F: MessageFormatter,
impl<F> BoxedFmt<F>where
F: MessageFormatter,
Sourcepub fn new(writer: Box<dyn Write + Send + Sync>) -> Box<Self>
pub fn new(writer: Box<dyn Write + Send + Sync>) -> Box<Self>
Creates a new BoxedFmt service on the heap.
§Parameters
writer: A boxed trait object. This is useful when the exact type of the string writer (e.g., a custom UI buffer vs. a standardString) is not known at compile time.formatter: TheMessageFormatterimplementation.
Sourcepub fn with_formatter(
writer: Box<dyn Write + Send + Sync>,
formatter: F,
) -> Box<Self>
pub fn with_formatter( writer: Box<dyn Write + Send + Sync>, formatter: F, ) -> Box<Self>
Creates a new BoxedFmt service on the heap with a custom formatter.
§Parameters
writer: A boxed trait object. This is useful when the exact type of the string writer (e.g., a custom UI buffer vs. a standardString) is not known at compile time.formatter: TheMessageFormatterimplementation.
Sourcepub fn inspect_writer<R>(
&self,
f: impl FnOnce(&Box<dyn Write + Send + Sync>) -> R,
) -> Option<R>
pub fn inspect_writer<R>( &self, f: impl FnOnce(&Box<dyn Write + Send + Sync>) -> R, ) -> Option<R>
Allows safe, read-only access to the internal buffer without stopping the logger.
Use this to “peek” at logs while the application is still running—perfect for health-check endpoints that expose recent logs or for verifying state in tests.
§Thread Safety
This method acquires a mutex lock. While the closure f is executing, any
incoming logs from other threads will block until the closure returns.
Keep the logic inside the closure as fast as possible.
§Returns
Sourcepub fn take_writer(self) -> Result<Box<dyn Write + Send + Sync>, ServiceError>
pub fn take_writer(self) -> Result<Box<dyn Write + Send + Sync>, ServiceError>
Destroys the Service and reclaims ownership of the underlying buffer or writer.
Use this at the end of a program, a test case, or a lifecycle stage to extract
all recorded logs and free up the resources used by the Service.
§Ownership & Lifecycle
This method consumes self, meaning the BoxedFmt service can no longer be
used after this call. This is the only way to get full, non-cloned ownership
of the internal writer (e.g., a String or Vec<u8>).
§Guarantees
Because this takes ownership of the Service, it is compile-time guaranteed
that no other threads can be writing to the buffer when this is called.
Trait Implementations§
Source§impl<F> Fallback for BoxedFmt<F>where
F: MessageFormatter + 'static,
impl<F> Fallback for BoxedFmt<F>where
F: MessageFormatter + 'static,
Source§fn fallback(&self, error: &ServiceError, msg: &Message)
fn fallback(&self, error: &ServiceError, msg: &Message)
Emergency fallback that redirects output to stdout.
If the primary boxed writer is inaccessible or failing, the message is formatted using the standard I/O fallback path.
Source§impl<F> Service for BoxedFmt<F>where
F: MessageFormatter + 'static,
impl<F> Service for BoxedFmt<F>where
F: MessageFormatter + 'static,
Source§fn status(&self) -> LoggerStatus
fn status(&self) -> LoggerStatus
Returns the current operational status.
Source§fn work(&self, msg: &Message) -> Result<(), ServiceError>
fn work(&self, msg: &Message) -> Result<(), ServiceError>
Acquires the lock and dispatches the write to the boxed trait object.
§Internal Mechanics
Since Box<dyn std::fmt::Write> doesn’t implement std::fmt::Write, this method uses
Box::as_mut() to obtain a mutable reference to the underlying
trait object before passing it to the formatter.
§Errors
ServiceError::LockPoisonedif the mutex is poisoned- Forwards any
ServiceErrorreturned by the formatter.
Auto Trait Implementations§
impl<F> !Freeze for BoxedFmt<F>
impl<F> RefUnwindSafe for BoxedFmt<F>
impl<F> Send for BoxedFmt<F>
impl<F> Sync for BoxedFmt<F>
impl<F> Unpin for BoxedFmt<F>where
F: Unpin,
impl<F> UnwindSafe for BoxedFmt<F>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more