pub struct ReportMut<'a, Context: ?Sized + 'static = Dynamic, ThreadSafety: 'static = SendSync> { /* private fields */ }Expand description
A mutable reference to a Report.
ReportMut provides mutable access to a report’s children and
attachments while maintaining safe borrowing semantics. Unlike owned
reports, mutable references cannot be consumed for chaining
operations like Report::context or Report::attach.
§Key Characteristics
- Not
CopyorClone: Ensures exclusive mutable access - Lifetime-bound: Tied to the lifetime of the underlying report
- Two type parameters: Has context type
Cand thread safety markerT(no ownership marker since mutable references are always uniquely owned)
§Thread Safety
Unlike Report and ReportRef, you cannot change the thread safety
marker on ReportMut:
- You cannot convert
SendSync→Localbecause that would allow adding non-thread-safe data to a report that should remain thread-safe - You cannot convert
Local→SendSyncbecause that would allow cloning a child report with thread-local data and sending it across threads
§Common Usage
use rootcause::{ReportMut, prelude::*};
let mut report: Report = report!("error message");
// Get mutable access to modify children or attachments
let mut report_mut: ReportMut<'_> = report.as_mut();
report_mut
.children_mut()
.push(report!("child error").into_cloneable());
println!("{}", report);Implementations§
Source§impl<'a, C: Sized, T> ReportMut<'a, C, T>
impl<'a, C: Sized, T> ReportMut<'a, C, T>
Sourcepub fn current_context(&self) -> &C
pub fn current_context(&self) -> &C
Returns a reference to the current context.
§Examples
let report_mut: ReportMut<'_, MyError> = report.as_mut();
let context: &MyError = report_mut.current_context();Sourcepub fn current_context_mut(&mut self) -> &mut C
pub fn current_context_mut(&mut self) -> &mut C
Returns a mutable reference to the current context.
§Examples
let mut report_mut: ReportMut<'_, String> = report.as_mut();
let context: &mut String = report_mut.current_context_mut();
context.push_str(" and that's bad");Sourcepub fn into_current_context_mut(self) -> &'a mut C
pub fn into_current_context_mut(self) -> &'a mut C
Source§impl<'a, C: ?Sized, T> ReportMut<'a, C, T>
impl<'a, C: ?Sized, T> ReportMut<'a, C, T>
Sourcepub fn children(&self) -> &ReportCollection<Dynamic, T>
pub fn children(&self) -> &ReportCollection<Dynamic, T>
Returns an immutable reference to the child reports.
§Examples
let mut report: Report = report!("error message");
let report_mut: ReportMut<'_> = report.as_mut();
let children: &ReportCollection = report_mut.children();
assert_eq!(children.len(), 0); // The report has just been created, so it has no childrenSourcepub fn children_mut(&mut self) -> &mut ReportCollection<Dynamic, T>
pub fn children_mut(&mut self) -> &mut ReportCollection<Dynamic, T>
Returns a mutable reference to the child reports.
§Examples
let mut report_mut: ReportMut<'_> = report.as_mut();
let children_mut: &mut ReportCollection = report_mut.children_mut();Sourcepub fn into_children_mut(self) -> &'a mut ReportCollection<Dynamic, T>
pub fn into_children_mut(self) -> &'a mut ReportCollection<Dynamic, T>
Sourcepub fn attachments(&self) -> &ReportAttachments<T>
pub fn attachments(&self) -> &ReportAttachments<T>
Returns an immutable reference to the attachments.
§Examples
let report_mut: ReportMut<'_> = report.as_mut();
let attachments: &ReportAttachments = report_mut.attachments();Sourcepub fn attachments_mut(&mut self) -> &mut ReportAttachments<T>
pub fn attachments_mut(&mut self) -> &mut ReportAttachments<T>
Returns a mutable reference to the attachments.
§Examples
let mut report_mut: ReportMut<'_> = report.as_mut();
let attachments_mut: &mut ReportAttachments = report_mut.attachments_mut();Sourcepub fn attach<A>(self, attachment: A) -> Self
pub fn attach<A>(self, attachment: A) -> Self
Adds a new attachment.
This is a convenience method used for chaining method calls; it consumes
the ReportMut and returns it.
If you want more direct control over the attachments, you can use the
ReportMut::attachments_mut.
§Examples
let mut report: Report = report!("error message");
let mut report_mut = report.as_mut();
report_mut = report_mut.attach("additional info");Sourcepub fn attach_custom<H, A>(self, attachment: A) -> Selfwhere
A: ObjectMarkerFor<T>,
H: AttachmentHandler<A>,
pub fn attach_custom<H, A>(self, attachment: A) -> Selfwhere
A: ObjectMarkerFor<T>,
H: AttachmentHandler<A>,
Adds a new attachment.
This is a convenience method used for chaining method calls; it consumes
the Report and returns it.
If you want more direct control over the attachments, you can use the
Report::attachments_mut.
§Examples
let mut report: Report = report!("error message");
let mut report_mut = report.as_mut();
report_mut = report_mut.attach_custom::<handlers::Display, _>("info");Sourcepub fn into_attachments_mut(self) -> &'a mut ReportAttachments<T>
pub fn into_attachments_mut(self) -> &'a mut ReportAttachments<T>
Sourcepub fn into_dynamic(self) -> ReportMut<'a, Dynamic, T>
pub fn into_dynamic(self) -> ReportMut<'a, Dynamic, T>
Changes the context type of the ReportMut to Dynamic.
Calling this method is equivalent to calling report.into(), however
this method has been restricted to only change the context mode to
Dynamic.
This method can be useful to help with type inference or to improve code readability, as it more clearly communicates intent.
This method does not actually modify the report in any way. It only has
the effect of “forgetting” that the context actually has the
type C.
To get back the report with a concrete C you can use the method
ReportMut::downcast_report.
§Examples
let report: ReportMut<'_, MyError> = report.as_mut();
let local_report: ReportMut<'_, Dynamic> = report.into_dynamic();Sourcepub fn as_ref(&self) -> ReportRef<'_, C, Uncloneable, T>
pub fn as_ref(&self) -> ReportRef<'_, C, Uncloneable, T>
Returns an immutable reference to the report.
§Examples
let report_mut: ReportMut<'_, MyError> = report.as_mut();
let report_ref: ReportRef<'_, MyError, markers::Uncloneable> = report_mut.as_ref();Sourcepub fn into_ref(self) -> ReportRef<'a, C, Uncloneable, T>
pub fn into_ref(self) -> ReportRef<'a, C, Uncloneable, T>
Sourcepub fn as_mut(&mut self) -> ReportMut<'_, C, T>
pub fn as_mut(&mut self) -> ReportMut<'_, C, T>
Reborrows the ReportMut to return a new ReportMut with a shorter
lifetime
§Examples
let mut report_mut: ReportMut<'_, MyError> = report.as_mut();
{
// Create a new mutable reference with a shorter lifetime
let mut borrowed_report_mut: ReportMut<'_, MyError> = report_mut.as_mut();
}
// After dropping the inner reference report, we can still use the outer one
let _context: &MyError = report_mut.current_context();Sourcepub fn iter_reports(&self) -> ReportIter<'_, Uncloneable, T> ⓘ
pub fn iter_reports(&self) -> ReportIter<'_, Uncloneable, T> ⓘ
Returns an iterator over the complete report hierarchy including this report.
The iterator visits reports in a depth-first order: it first visits the
current report, then recursively visits each child report and all of
their descendants before moving to the next sibling. Unlike
ReportMut::iter_sub_reports, this method includes the report on
which it was called as the first item in the iteration.
Since this is a mutable reference, the returned iterator references are
Uncloneable to ensure proper borrowing semantics.
See also: ReportMut::iter_sub_reports for iterating only over child
reports with cloneable references.
§Examples
// Create base reports
let error1: Report = report!("error 1");
let error2: Report = report!("error 2");
// Build hierarchy using .context() which creates new nodes
let with_context1 = error1.context("context for error 1");
let with_context2 = error2.context("context for error 2");
// Create root that contains both context nodes as children
let mut root = report!("root error").context("context for root error");
root.children_mut()
.push(with_context1.into_dynamic().into_cloneable());
root.children_mut()
.push(with_context2.into_dynamic().into_cloneable());
let root_mut: ReportMut<'_, &'static str> = root.as_mut();
let all_reports: Vec<String> = root_mut
.iter_reports()
.map(|report| report.format_current_context().to_string())
.collect();
assert_eq!(all_reports[0], "context for root error"); // Current report is included
assert_eq!(all_reports[1], "root error");
assert_eq!(all_reports[2], "context for error 1");
assert_eq!(all_reports.len(), 6);Sourcepub fn iter_sub_reports(&self) -> ReportIter<'_, Cloneable, T> ⓘ
pub fn iter_sub_reports(&self) -> ReportIter<'_, Cloneable, T> ⓘ
Returns an iterator over child reports in the report hierarchy (excluding this report).
The iterator visits reports in a depth-first order: it first visits the
current report’s children, then recursively visits each child report
and all of their descendants before moving to the next sibling.
Unlike ReportMut::iter_reports, this method does NOT include the
report on which it was called - only its descendants.
This method always returns cloneable report references, making it suitable for scenarios where you need to store or pass around the report references.
See also: ReportMut::iter_reports for iterating over all reports
including the current one.
§Examples
// Create base reports
let error1: Report = report!("error 1");
let error2: Report = report!("error 2");
// Build hierarchy using .context() which creates new nodes
let with_context1 = error1.context("context for error 1");
let with_context2 = error2.context("context for error 2");
// Create root that contains both context nodes as children
let mut root = report!("root error").context("context for root error");
root.children_mut()
.push(with_context1.into_dynamic().into_cloneable());
root.children_mut()
.push(with_context2.into_dynamic().into_cloneable());
let root_mut: ReportMut<'_, &'static str> = root.as_mut();
let sub_reports: Vec<String> = root_mut
.iter_sub_reports()
.map(|report| report.format_current_context().to_string())
.collect();
// Current "root" report is NOT included in the results
assert_eq!(sub_reports[0], "root error");
assert_eq!(sub_reports[1], "context for error 1");
assert_eq!(sub_reports.len(), 5);Sourcepub fn preformat(&self) -> Report<PreformattedContext, Mutable, SendSync>
pub fn preformat(&self) -> Report<PreformattedContext, Mutable, SendSync>
Creates a new report, which has the same structure as the current report, but has all the contexts and attachments preformatted.
This can be useful, as the new report is mutable because it was just
created, and additionally the new report is Send+Sync.
§Examples
let report_mut: ReportMut<'_, NonSendSyncError, markers::Local> = report.as_mut();
let preformatted: Report<PreformattedContext, markers::Mutable, markers::SendSync> =
report_mut.preformat();
assert_eq!(format!("{report}"), format!("{preformatted}"));Sourcepub fn current_context_type_id(&self) -> TypeId
pub fn current_context_type_id(&self) -> TypeId
Returns the TypeId of the current context.
§Examples
let report_mut: ReportMut<'_, MyError> = report.as_mut();
let type_id = report_mut.current_context_type_id();
assert_eq!(type_id, TypeId::of::<MyError>());
let report_mut: ReportMut<'_, Dynamic> = report_mut.into_dynamic();
let type_id = report_mut.current_context_type_id();
assert_eq!(type_id, TypeId::of::<MyError>());Sourcepub fn current_context_type_name(&self) -> &'static str
pub fn current_context_type_name(&self) -> &'static str
Returns the core::any::type_name of the current context.
§Examples
let report_mut: ReportMut<'_, MyError> = report.as_mut();
let type_name = report_mut.current_context_type_name();
assert_eq!(type_name, core::any::type_name::<MyError>());
let report_mut: ReportMut<'_, Dynamic> = report_mut.into_dynamic();
let type_name = report_mut.current_context_type_name();
assert_eq!(type_name, core::any::type_name::<MyError>());Sourcepub fn current_context_handler_type_id(&self) -> TypeId
pub fn current_context_handler_type_id(&self) -> TypeId
Returns the TypeId of the handler used for the current context.
This can be useful for debugging or introspection to understand which handler was used to format the context.
§Examples
let mut report = Report::new_sendsync_custom::<handlers::Debug>("error message");
let report_mut = report.as_mut();
let handler_type = report_mut.current_context_handler_type_id();
assert_eq!(handler_type, TypeId::of::<handlers::Debug>());Sourcepub fn current_context_error_source(&self) -> Option<&(dyn Error + 'static)>
pub fn current_context_error_source(&self) -> Option<&(dyn Error + 'static)>
Sourcepub fn format_current_context(&self) -> impl Display + Debug
pub fn format_current_context(&self) -> impl Display + Debug
Formats the current context with hook processing.
§Examples
let mut report: Report = report!("error message");
let report_mut = report.as_mut();
let formatted = report_mut.format_current_context();
println!("{formatted}");Sourcepub fn format_current_context_unhooked(&self) -> impl Display + Debug
pub fn format_current_context_unhooked(&self) -> impl Display + Debug
Formats the current context without hook processing.
§Examples
let mut report: Report = report!("error message");
let report_mut = report.as_mut();
let formatted = report_mut.format_current_context_unhooked();
println!("{formatted}");Sourcepub fn format_with<H>(&self, hook: &H) -> impl Display + Debugwhere
H: ReportFormatter,
pub fn format_with<H>(&self, hook: &H) -> impl Display + Debugwhere
H: ReportFormatter,
Formats the entire report using a specific report formatting hook.
This method allows you to format a report with a custom formatter without globally registering it. This is useful for:
- One-off custom formatting
- Testing different formatters
- Using different formatters in different parts of your application
Unlike the default Display and Debug implementations which use the
globally registered hook, this method uses the hook you provide
directly.
§Examples
use rootcause::{hooks::builtin_hooks::report_formatter::DefaultReportFormatter, prelude::*};
let mut report = report!("error message");
let report_mut = report.as_mut();
// Format with ASCII-only output (no Unicode or ANSI colors)
let formatted = report_mut.format_with(&DefaultReportFormatter::ASCII);
println!("{}", formatted);Sourcepub fn preferred_context_formatting_style(
&self,
report_formatting_function: FormattingFunction,
) -> ContextFormattingStyle
pub fn preferred_context_formatting_style( &self, report_formatting_function: FormattingFunction, ) -> ContextFormattingStyle
Gets the preferred formatting style for the context with hook processing.
§Arguments
report_formatting_function: Whether the report in which this context will be embedded is being formatted usingDisplayformatting orDebug
§Examples
let mut report: Report = report!("error message");
let report_mut = report.as_mut();
let style =
report_mut.preferred_context_formatting_style(handlers::FormattingFunction::Display);Sourcepub fn preferred_context_formatting_style_unhooked(
&self,
report_formatting_function: FormattingFunction,
) -> ContextFormattingStyle
pub fn preferred_context_formatting_style_unhooked( &self, report_formatting_function: FormattingFunction, ) -> ContextFormattingStyle
Gets the preferred formatting style for the context without hook processing.
§Arguments
report_formatting_function: Whether the report in which this context will be embedded is being formatted usingDisplayformatting orDebug
§Examples
let mut report: Report = report!("error message");
let report_mut = report.as_mut();
let style = report_mut
.preferred_context_formatting_style_unhooked(handlers::FormattingFunction::Display);Sourcepub fn strong_count(&self) -> usize
pub fn strong_count(&self) -> usize
Returns the number of references to this report.
§Examples
let mut report: Report = report!("error message");
let report_mut = report.as_mut();
assert_eq!(report_mut.strong_count(), 1);Source§impl<'a, T> ReportMut<'a, Dynamic, T>
impl<'a, T> ReportMut<'a, Dynamic, T>
Sourcepub fn downcast_current_context<C>(&self) -> Option<&C>where
C: Sized + 'static,
pub fn downcast_current_context<C>(&self) -> Option<&C>where
C: Sized + 'static,
Attempts to downcast the current context to a specific type.
Returns Some(&C) if the current context is of type C, otherwise
returns None.
§Examples
let report: Report<MyError> = report!(MyError);
let mut dyn_report: Report = report.into_dynamic();
let mut_report = dyn_report.as_mut();
let context: Option<&MyError> = mut_report.downcast_current_context();
assert!(context.is_some());Sourcepub fn downcast_current_context_mut<C>(&mut self) -> Option<&mut C>where
C: Sized + 'static,
pub fn downcast_current_context_mut<C>(&mut self) -> Option<&mut C>where
C: Sized + 'static,
Attempts to downcast the current context to a specific type.
Returns Some(&mut C) if the current context is of type C, otherwise
returns None.
§Examples
let report: Report<MyError> = report!(MyError);
let mut dyn_report: Report = report.into_dynamic();
let mut mut_report = dyn_report.as_mut();
let context: Option<&mut MyError> = mut_report.downcast_current_context_mut();
assert!(context.is_some());Sourcepub unsafe fn downcast_current_context_unchecked<C>(&self) -> &Cwhere
C: Sized + 'static,
pub unsafe fn downcast_current_context_unchecked<C>(&self) -> &Cwhere
C: Sized + 'static,
Downcasts the current context to a specific type without checking.
§Safety
The caller must ensure:
- The current context is actually of type
C(can be verified by callingcurrent_context_type_id()first)
§Examples
let report: Report<MyError> = report!(MyError);
let mut dyn_report: Report = report.into_dynamic();
let mut_report = dyn_report.as_mut();
// Verify the type first
if mut_report.current_context_type_id() == TypeId::of::<MyError>() {
// SAFETY: We verified the type matches
let context: &MyError = unsafe { mut_report.downcast_current_context_unchecked() };
}Sourcepub unsafe fn downcast_current_context_mut_unchecked<C>(&mut self) -> &mut Cwhere
C: Sized + 'static,
pub unsafe fn downcast_current_context_mut_unchecked<C>(&mut self) -> &mut Cwhere
C: Sized + 'static,
Downcasts the current context to a specific type without checking.
§Safety
The caller must ensure:
- The current context is actually of type
C(can be verified by callingcurrent_context_type_id()first)
§Examples
let report: Report<MyError> = report!(MyError);
let mut dyn_report: Report = report.into_dynamic();
let mut mut_report = dyn_report.as_mut();
// Verify the type first
if mut_report.current_context_type_id() == TypeId::of::<MyError>() {
// SAFETY: We verified the type matches
let context: &mut MyError = unsafe { mut_report.downcast_current_context_mut_unchecked() };
}Sourcepub fn downcast_report<C>(
self,
) -> Result<ReportMut<'a, C, T>, ReportMut<'a, Dynamic, T>>where
C: Sized + 'static,
pub fn downcast_report<C>(
self,
) -> Result<ReportMut<'a, C, T>, ReportMut<'a, Dynamic, T>>where
C: Sized + 'static,
Attempts to downcast the entire report to a specific context type.
Returns Ok(ReportMut<C>) if the current context is of type C,
otherwise returns Err(self) with the original report.
§Examples
let report: Report<MyError> = report!(MyError);
let mut dyn_report: Report = report.into_dynamic();
let mut_report = dyn_report.as_mut();
let downcasted: Result<_, _> = mut_report.downcast_report::<MyError>();
assert!(downcasted.is_ok());Sourcepub unsafe fn downcast_report_unchecked<C>(self) -> ReportMut<'a, C, T>where
C: Sized + 'static,
pub unsafe fn downcast_report_unchecked<C>(self) -> ReportMut<'a, C, T>where
C: Sized + 'static,
Downcasts the entire report to a specific context type without checking.
§Safety
The caller must ensure:
- The current context is actually of type
C(can be verified by callingcurrent_context_type_id()first)
§Examples
let report: Report<MyError> = report!(MyError);
let mut dyn_report: Report = report.into_dynamic();
let mut_report = dyn_report.as_mut();
// Verify the type first
if mut_report.current_context_type_id() == TypeId::of::<MyError>() {
// SAFETY: We verified the type matches
let downcasted = unsafe { mut_report.downcast_report_unchecked::<MyError>() };
}