pub trait ContextHandler<C>: 'static {
// Required methods
fn source(value: &C) -> Option<&(dyn Error + 'static)>;
fn display(value: &C, formatter: &mut Formatter<'_>) -> Result;
fn debug(value: &C, formatter: &mut Formatter<'_>) -> Result;
// Provided method
fn preferred_formatting_style(
value: &C,
report_formatting_function: FormattingFunction,
) -> ContextFormattingStyle { ... }
}Expand description
Trait for implementing custom formatting and error-chaining behavior for report contexts.
This trait defines how a context type should be formatted when displayed or debugged as part of an error report, and how to navigate to its error source (if any).
§When to Implement
You typically don’t need to implement this trait directly. The rootcause
library provides built-in handlers (Error, Display, Debug, Any) that
cover most use cases.
Implement this trait when you need custom formatting behavior that the built-in handlers don’t provide, such as:
- Custom source chain navigation for types that don’t implement
std::error::Error - Special display formatting that differs from the type’s
Displayimplementation - Dynamic formatting based on the context value
§Required Methods
source: Returns the underlying error source, if anydisplay: Formats the context for display outputdebug: Formats the context for debug output
§Optional Methods
preferred_formatting_style: Specifies whether to use display or debug formatting when embedded in a report. The default implementation always prefers display formatting.
§Examples
use std::error::Error;
use rootcause_internals::handlers::{
ContextFormattingStyle, ContextHandler, FormattingFunction,
};
// Custom context type
struct CustomError {
message: String,
code: i32,
}
// Custom handler with special formatting
struct CustomHandler;
impl ContextHandler<CustomError> for CustomHandler {
fn source(_context: &CustomError) -> Option<&(dyn Error + 'static)> {
None
}
fn display(context: &CustomError, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Error {}: {}", context.code, context.message)
}
fn debug(context: &CustomError, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"CustomError {{ code: {}, message: {:?} }}",
context.code, context.message
)
}
}Required Methods§
Sourcefn source(value: &C) -> Option<&(dyn Error + 'static)>
fn source(value: &C) -> Option<&(dyn Error + 'static)>
Returns the underlying error source for this context, if any.
This method enables error chain traversal, allowing you to navigate from a context to its underlying cause. It’s used when displaying the full error chain in a report.
§Returns
Some(&dyn Error)if this context has an underlying error sourceNoneif this context is a leaf in the error chain
§Examples
For types implementing std::error::Error, delegate to their source
method:
use std::error::Error;
use rootcause_internals::handlers::ContextHandler;
struct ErrorHandler;
impl<C: Error> ContextHandler<C> for ErrorHandler {
fn source(context: &C) -> Option<&(dyn Error + 'static)> {
context.source()
}
}Sourcefn display(value: &C, formatter: &mut Formatter<'_>) -> Result
fn display(value: &C, formatter: &mut Formatter<'_>) -> Result
Formats the context using display-style formatting.
This method is called when the context needs to be displayed as part of an error report. It should produce human-readable output suitable for end users.
§Examples
use rootcause_internals::handlers::ContextHandler;
struct DisplayHandler;
impl<C: std::fmt::Display + std::fmt::Debug> ContextHandler<C> for DisplayHandler {
fn source(_context: &C) -> Option<&(dyn std::error::Error + 'static)> {
None
}
fn display(context: &C, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(context, f)
}
}Sourcefn debug(value: &C, formatter: &mut Formatter<'_>) -> Result
fn debug(value: &C, formatter: &mut Formatter<'_>) -> Result
Formats the context using debug-style formatting.
This method is called when the context needs to be debug-formatted. It should produce detailed output suitable for developers, potentially including internal state and implementation details.
§Examples
use rootcause_internals::handlers::ContextHandler;
struct DebugHandler;
impl<C: std::fmt::Debug> ContextHandler<C> for DebugHandler {
fn source(_context: &C) -> Option<&(dyn std::error::Error + 'static)> {
None
}
fn display(context: &C, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Context of type `{}`", core::any::type_name::<C>())
}
fn debug(context: &C, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(context, f)
}
}Provided Methods§
Sourcefn preferred_formatting_style(
value: &C,
report_formatting_function: FormattingFunction,
) -> ContextFormattingStyle
fn preferred_formatting_style( value: &C, report_formatting_function: FormattingFunction, ) -> ContextFormattingStyle
Specifies the preferred formatting style when this context is embedded in a report.
This method allows the handler to choose between display and debug
formatting based on how the report itself is being formatted. The
default implementation always returns
FormattingFunction::Display, meaning the context will use
its display method even when the report is
being debug-formatted.
§Arguments
value: The context valuereport_formatting_function: How the report itself is being formatted (DisplayorDebug)
§Default Behavior
The default implementation ignores the report’s formatting style and always uses display formatting. This is the behavior of all built-in handlers.
§Examples
Custom handler that mirrors the report’s formatting:
use rootcause_internals::handlers::{
ContextFormattingStyle, ContextHandler, FormattingFunction,
};
struct MirrorHandler;
impl<C: std::fmt::Display + std::fmt::Debug> ContextHandler<C> for MirrorHandler {
fn source(_context: &C) -> Option<&(dyn std::error::Error + 'static)> {
None
}
fn display(context: &C, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(context, f)
}
fn debug(context: &C, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(context, f)
}
fn preferred_formatting_style(
_value: &C,
report_formatting_function: FormattingFunction,
) -> ContextFormattingStyle {
// Use the same formatting as the report
ContextFormattingStyle {
function: report_formatting_function,
}
}
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.