diff --git a/.envrc b/.envrc index 3550a30..8392d15 100644 --- a/.envrc +++ b/.envrc @@ -1 +1 @@ -use flake +use flake \ No newline at end of file diff --git a/.github/instructions/rootcause.instructions.md b/.github/instructions/rootcause.instructions.md index 70bf612..7f9ba40 100644 --- a/.github/instructions/rootcause.instructions.md +++ b/.github/instructions/rootcause.instructions.md @@ -44,7 +44,7 @@ Different visibility levels require different levels of documentation detail: ````rust /// Creates a report with the given context. /// -/// This is the primary way to create reports. Use the `report!()` macro +/// This is the primary way to create reports. Use the [`report!()`](crate::report) macro /// for more convenient report creation with format string support. /// /// # Examples diff --git a/.gitignore b/.gitignore index 6abfe1b..bf14f74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /.direnv +/.claude \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index ed82044..6a8ea67 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,4 +3,5 @@ "cSpell.userWords": [], "cSpell.flagWords": [], "cSpell.ignoreWords": [], + "rust-analyzer.cargo.features": "all" } \ No newline at end of file diff --git a/examples/anyhow_interop.rs b/examples/anyhow_interop.rs index c0b6a1f..0a9dcac 100644 --- a/examples/anyhow_interop.rs +++ b/examples/anyhow_interop.rs @@ -13,13 +13,17 @@ //! # Conversion Overview //! //! ## From Anyhow to Rootcause -//! - `.into_rootcause()` - Convert `anyhow::Result` or `anyhow::Error` +//! - [`.into_rootcause()`] - Convert [`anyhow::Result`] or [`anyhow::Error`] //! //! ## From Rootcause to Anyhow -//! - `.into_anyhow()` - Convert `Result` or `Report` -//! - `.into()` - Use `From` for automatic conversion -//! - `?` operator - Automatically converts `Report` to `anyhow::Error` in +//! - [`.into_anyhow()`] - Convert [`Result`] or [`Report`] +//! - [`.into()`](Into::into) - Use [`From`] for automatic conversion +//! - `?` operator - Automatically converts [`Report`] to [`anyhow::Error`] in //! anyhow functions +//! +//! [`.into_rootcause()`]: rootcause::compat::IntoRootcause::into_rootcause +//! [`.attach()`]: rootcause::Report::attach +//! [`.into_anyhow()`]: rootcause::compat::anyhow1::IntoAnyhow::into_anyhow // Import only what we need to avoid conflicting with anyhow's Context trait use rootcause::{ diff --git a/examples/anyhow_migration.rs b/examples/anyhow_migration.rs index 8e34307..dd87b54 100644 --- a/examples/anyhow_migration.rs +++ b/examples/anyhow_migration.rs @@ -28,8 +28,8 @@ //! you control all the code but want to be cautious about breaking changes. //! //! The example treats each component as if it came from a separate crate: -//! - `metrics`: A metrics collection library (pretend you depend on this) -//! - `kv_store`: A key-value store (pretend you depend on this too) +//! - [`metrics`](v1_original_anyhow::metrics): A metrics collection library (pretend you depend on this) +//! - [`kv_store`](v1_original_anyhow::kv_store): A key-value store (pretend you depend on this too) //! - Your application: The code you're migrating //! //! # Migration Stages diff --git a/examples/anyhow_migration/stage2.rs b/examples/anyhow_migration/stage2.rs index 70ffcba..7a2f517 100644 --- a/examples/anyhow_migration/stage2.rs +++ b/examples/anyhow_migration/stage2.rs @@ -5,8 +5,8 @@ //! features like `.attach()` without touching any dependencies. //! //! **What changed:** -//! - Application's `main` module now returns `Result<(), Report>` -//! - Use `.into_rootcause()` when calling dependency methods +//! - Application's [`main`] module now returns [`Result<(), Report>`] +//! - Use [`.into_rootcause()`](crate""") when calling dependency methods //! - Can now use `.attach()`, rich context, and other rootcause features //! //! **What stayed the same:** diff --git a/examples/anyhow_migration/stage3.rs b/examples/anyhow_migration/stage3.rs index 5396ce4..ed45828 100644 --- a/examples/anyhow_migration/stage3.rs +++ b/examples/anyhow_migration/stage3.rs @@ -5,12 +5,16 @@ //! users. //! //! **What changed:** -//! - Internal methods like `flush_internal()` now use rootcause -//! - Can add rich context (`.attach()`) in internal implementation -//! - Use `.into_anyhow()` to convert back when returning from trait methods +//! - Internal methods like [`.flush_internal()`] now use rootcause +//! - Can add rich context ([`.attach()`]) in internal implementation +//! - Use [`.into_anyhow()`] to convert back when returning from trait methods +//! +//! [`.flush_internal()`]: metrics::MetricsCollector::flush_internal +//! [`.attach()`]: rootcause::Report::attach +//! [`.into_anyhow()`]: rootcause::compat::anyhow1::IntoAnyhow::into_anyhow //! //! **What stayed the same:** -//! - Public `Metrics` trait still uses `anyhow::Result` (no breaking change) +//! - Public [`Metrics`](metrics::Metrics) trait still uses [`anyhow::Result`] (no breaking change) //! - KV store and application unchanged from stage 2 // ------------------------------------------------------------------------- diff --git a/examples/anyhow_migration/stage4.rs b/examples/anyhow_migration/stage4.rs index 81093eb..c1cba68 100644 --- a/examples/anyhow_migration/stage4.rs +++ b/examples/anyhow_migration/stage4.rs @@ -6,12 +6,16 @@ //! **What changed:** //! - KV store methods split into public (anyhow) and internal (rootcause) //! versions -//! - Use `.into_rootcause()` when calling metrics (still anyhow) -//! - Use `.into_anyhow()` when returning from public methods -//! - Rich error context with `.attach()` in internal methods +//! - Use [`.into_rootcause()`] when calling metrics (still anyhow) +//! - Use [`.into_anyhow()`] when returning from public methods +//! - Rich error context with [`.attach()`] in internal methods +//! +//! [`.into_rootcause()`]: rootcause::compat::IntoRootcause::into_rootcause +//! [`.attach()`]: rootcause::Report::attach +//! [`.into_anyhow()`]: rootcause::compat::anyhow1::IntoAnyhow::into_anyhow //! //! **What stayed the same:** -//! - Public KV store API still uses `anyhow::Result` (no breaking change) +//! - Public KV store API still uses [`anyhow::Result`] (no breaking change) //! - Metrics and application unchanged from stage 3 pub mod metrics { use std::collections::HashMap; diff --git a/examples/anyhow_migration/stage5.rs b/examples/anyhow_migration/stage5.rs index d94cc3c..b3d142b 100644 --- a/examples/anyhow_migration/stage5.rs +++ b/examples/anyhow_migration/stage5.rs @@ -4,10 +4,13 @@ //! This stage shows the final, clean state with no conversions needed. //! //! **What changed:** -//! - `Metrics` trait now uses `Result<(), Report>` (**breaking change**) -//! - All `.into_rootcause()` and `.into_anyhow()` calls removed +//! - [`Metrics`](metrics::Metrics) trait now uses [`Result<(), Report>`] (**breaking change**) +//! - All [`.into_rootcause()`] and [`.into_anyhow()`] calls removed //! - Clean, consistent rootcause usage throughout //! +//! [`.into_rootcause()`]: rootcause::compat::IntoRootcause::into_rootcause +//! [`.into_anyhow()`]: rootcause::compat::anyhow1::IntoAnyhow::into_anyhow +//! //! **Benefits:** //! - No conversion overhead //! - Consistent error handling patterns across all crates diff --git a/examples/boxed_error_interop.rs b/examples/boxed_error_interop.rs index 662a725..f2bd437 100644 --- a/examples/boxed_error_interop.rs +++ b/examples/boxed_error_interop.rs @@ -1,7 +1,7 @@ //! Quick reference for bidirectional boxed error interoperability. //! //! This example demonstrates all the ways to convert between rootcause -//! [`Report`]s and boxed error trait objects (`Box`). This is +//! [`Report`]s and boxed error trait objects ([`Box`]). This is //! useful for integrating with APIs that expect standard Rust error types. //! //! # Conversion Overview @@ -11,9 +11,9 @@ //! Error>` //! //! ## From Rootcause to Boxed Errors -//! - `.into_boxed_error()` - Convert `Result` or `Report` -//! - `.into()` - Use `From` for automatic conversion -//! - `?` operator - Automatically converts `Report` to `Box` in +//! - [`.into_boxed_error()`] - Convert [`Result`] or [`Report`] +//! - [`.into()`](Into::into) - Use [`From`] for automatic conversion +//! - `?` operator - Automatically converts [`Report`] to [`Box`] in //! functions returning boxed errors //! //! # Thread Safety diff --git a/examples/context_methods.rs b/examples/context_methods.rs index 5e52ce1..c093275 100644 --- a/examples/context_methods.rs +++ b/examples/context_methods.rs @@ -2,10 +2,15 @@ //! //! This example compares four methods for transforming report contexts: //! -//! - `context()`: Wraps report as child under new context -//! - `context_to()`: Uses `ReportConversion` trait implementation -//! - `context_transform()`: Changes context type in-place -//! - `context_transform_nested()`: Preformats and wraps as child +//! - [`.context()`]: Wraps report as child under new context +//! - [`.context_to()`]: Uses [`ReportConversion`] trait implementation +//! - [`.context_transform()`]: Changes context type in-place +//! - [`.context_transform_nested()`]: Preformats and wraps as child +//! +//! [`.context()`]: Report::context +//! [`.context_to()`]: Report::context_to +//! [`.context_transform()`]: Report::context_transform +//! [`.context_transform_nested()`]: Report::context_transform_nested //! //! The focus is on understanding **what each method does to the report //! structure** and **what information is preserved or lost**. diff --git a/rootcause-backtrace/src/lib.rs b/rootcause-backtrace/src/lib.rs index 1a62d6f..399ab92 100644 --- a/rootcause-backtrace/src/lib.rs +++ b/rootcause-backtrace/src/lib.rs @@ -913,7 +913,7 @@ impl FramePath { /// Extension trait for attaching backtraces to reports. /// /// This trait provides methods to easily attach a captured backtrace to a -/// report or to the error contained within a `Result`. +/// report or to the error contained within a [`Result`]. /// /// # Examples /// @@ -928,7 +928,7 @@ impl FramePath { /// let report = report!(io::Error::other("An error occurred")).attach_backtrace(); /// ``` /// -/// Attach backtrace to a `Result`: +/// Attach backtrace to a [`Result`]: /// /// ``` /// use std::io; diff --git a/rootcause-internals/src/attachment/data.rs b/rootcause-internals/src/attachment/data.rs index 486587f..5997d5a 100644 --- a/rootcause-internals/src/attachment/data.rs +++ b/rootcause-internals/src/attachment/data.rs @@ -41,7 +41,7 @@ pub(crate) struct AttachmentData { /// The following safety invariants are guaranteed to be upheld as long as /// this struct exists: /// - /// 1. The vtable must always point to an `AttachmentVtable` created for the + /// 1. The vtable must always point to an [`AttachmentVtable`] created for the /// actual attachment type `A` stored below. This is true even when /// accessed via type-erased pointers. vtable: &'static AttachmentVtable, diff --git a/rootcause-internals/src/attachment/raw.rs b/rootcause-internals/src/attachment/raw.rs index c0a776e..cbf6e11 100644 --- a/rootcause-internals/src/attachment/raw.rs +++ b/rootcause-internals/src/attachment/raw.rs @@ -52,12 +52,12 @@ pub struct RawAttachment { /// this struct exists: /// /// 1. The pointer must have been created from a `Box>` - /// for some `A` using `Box::into_raw`. - /// 2. The pointer will point to the same `AttachmentData` for the entire - /// lifetime of this object. + /// for some `A` using [`Box::into_raw`]. + /// 2. The pointer will point to the same [`AttachmentData`](AttachmentData) + /// for the entire lifetime of this object. /// 3. The pointee is properly initialized for the entire lifetime of this - /// object, except during the execution of the `Drop` implementation. - /// 4. The pointer is the sole owner of the `AttachmentData` instance. + /// object, except during the execution of the [`Drop`] implementation. + /// 4. The pointer is the sole owner of the [`AttachmentData`] instance. ptr: NonNull>, } @@ -161,13 +161,12 @@ pub struct RawAttachmentRef<'a> { /// The following safety invariants are guaranteed to be upheld as long as /// this struct exists: /// - /// 1. The pointer must have been created from a `Box>` - /// for some `A` using `Box::into_raw`. - /// 2. The pointer will point to the same `AttachmentData` for the entire + /// 1. The pointer must have been created from a [`Box>`] + /// for some `A` using [`Box::into_raw`]. + /// 2. The pointer will point to the same [`AttachmentData`](AttachmentData) for the entire /// lifetime of this object. - /// 3. This pointer represents read-only access to the `AttachmentData` for - /// the lifetime `'a` with the same semantics as a `&'a - /// AttachmentData`. + /// 3. This pointer represents read-only access to the [`AttachmentData`] for + /// the lifetime `'a` with the same semantics as a [`&'a AttachmentData`](AttachmentData). ptr: NonNull>, /// Marker to tell the compiler that we should @@ -302,13 +301,13 @@ pub struct RawAttachmentMut<'a> { /// The following safety invariants are guaranteed to be upheld as long as /// this struct exists: /// - /// 1. The pointer must have been created from a `Box>` - /// for some `A` using `Box::into_raw`. - /// 2. The pointer will point to the same `AttachmentData` for the entire + /// 1. The pointer must have been created from a [`Box>`] + /// for some `A` using [`Box::into_raw`]. + /// 2. The pointer will point to the same [`AttachmentData`](AttachmentData) for the entire /// lifetime of this object. /// 3. This pointer represents exclusive mutable access to the - /// `AttachmentData` for the lifetime `'a` with the same semantics as a - /// `&'a mut AttachmentData`. + /// [`AttachmentData`] for the lifetime `'a` with the same semantics as a + /// [`&'a mut AttachmentData`](AttachmentData). ptr: NonNull>, /// Marker to tell the compiler that we should diff --git a/rootcause-internals/src/attachment/vtable.rs b/rootcause-internals/src/attachment/vtable.rs index ce9ecc1..6cea0be 100644 --- a/rootcause-internals/src/attachment/vtable.rs +++ b/rootcause-internals/src/attachment/vtable.rs @@ -52,12 +52,12 @@ pub(crate) struct AttachmentVtable { /// Drops the [`Box>`] instance pointed to by this /// pointer. drop: unsafe fn(NonNull>), - /// Formats the attachment using the `display` method on the handler. + /// Formats the attachment using the [`AttachmentHandler::display`] method. display: unsafe fn(RawAttachmentRef<'_>, &mut core::fmt::Formatter<'_>) -> core::fmt::Result, - /// Formats the attachment using the `debug` method on the handler. + /// Formats the attachment using the [`AttachmentHandler::debug`] method on the handler. debug: unsafe fn(RawAttachmentRef<'_>, &mut core::fmt::Formatter<'_>) -> core::fmt::Result, /// Get the formatting style preferred by the attachment when formatted as - /// part of a report. + /// part of a report, according to [`AttachmentHandler::preferred_formatting_style`]. preferred_formatting_style: unsafe fn(RawAttachmentRef<'_>, FormattingFunction) -> AttachmentFormattingStyle, } @@ -100,7 +100,7 @@ impl AttachmentVtable { (self.handler_type_id)() } - /// Drops the `Box>` instance pointed to by this pointer. + /// Drops the [`Box>`] instance pointed to by this pointer. /// /// # Safety /// diff --git a/rootcause-internals/src/handlers.rs b/rootcause-internals/src/handlers.rs index f169ca2..513b7db 100644 --- a/rootcause-internals/src/handlers.rs +++ b/rootcause-internals/src/handlers.rs @@ -15,14 +15,19 @@ /// # 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 +/// library provides built-in handlers ([`Error`], [`Display`], [`Debug`], [`Any`]) that /// cover most use cases. /// +/// [`Error`]: https://docs.rs/rootcause/latest/rootcause/handlers/struct.Error.html +/// [`Debug`]: https://docs.rs/rootcause/latest/rootcause/handlers/struct.Debug.html +/// [`Display`]: https://docs.rs/rootcause/latest/rootcause/handlers/struct.Display.html +/// [`Any`]: https://docs.rs/rootcause/latest/rootcause/handlers/struct.Any.html +/// /// 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 `Display` +/// [`std::error::Error`] +/// - Special display formatting that differs from the type's [`Display`](core::fmt::Display) /// implementation /// - Dynamic formatting based on the context value /// @@ -85,14 +90,16 @@ pub trait ContextHandler: 'static { /// /// # Returns /// - /// - `Some(&dyn Error)` if this context has an underlying error source - /// - `None` if this context is a leaf in the error chain + /// - [`Some(&dyn Error)`](core::error::Error::source) if this context has an underlying error source + /// - [`None`] if this context is a leaf in the error chain /// /// # Examples /// - /// For types implementing `std::error::Error`, delegate to their `source` + /// For types implementing [`std::error::Error`](core::error::Error), delegate to their [`source`] /// method: /// + /// [`source`]: core::error::Error::source + /// /// ``` /// use std::error::Error; /// @@ -176,9 +183,8 @@ pub trait ContextHandler: 'static { /// /// This method allows the handler to control: /// - **Formatting**: Whether to use display or debug formatting - /// - **Source-chasing**: Whether to follow the chain of of - /// [`Error::source()`](core::error::Error::source) if - /// [`ContextHandler::source`] returns `Some`, and also how deep to chase. + /// - **Source-chasing**: Whether to follow the chain of of [`Error::source()`](core::error::Error::source) if [`ContextHandler::source`] returns [`Some`], and + /// also how deep to chase. /// /// The default implementation returns the same formatting as the report, /// with no source chasing. @@ -414,11 +420,9 @@ pub trait AttachmentHandler: 'static { /// /// - `function`: Whether to use [`Display`](core::fmt::Display) or /// [`Debug`](core::fmt::Debug) formatting -/// - `follow_source`: Whether to follow the -/// [`Error::source`](core::error::Error::source)-chain when -/// [`ContextHandler::source`] returns `Some`. -/// - `follow_source_depth`: How deep to follow the chain, `None` means no -/// limit. +/// - `follow_source`: Whether to follow the [`Error::source`](core::error::Error::source)-chain +/// when [`ContextHandler::source`] returns [`Some`]. +/// - `follow_source_depth`: How deep to follow the chain, `None` means no limit. /// /// # Default /// @@ -449,7 +453,7 @@ pub struct ContextFormattingStyle { /// formatting pub follow_source: bool, /// The maximum depth to follow the [`core::error::Error`] source chain when - /// formatting. Setting to `None` means unlimited depth. + /// formatting. Setting to [`None`] means unlimited depth. pub follow_source_depth: Option, } @@ -514,8 +518,13 @@ pub struct AttachmentFormattingStyle { /// /// # Variants /// -/// - **`Display`** (default): Use the `display` method -/// - **`Debug`**: Use the `debug` method +/// - **[`Display`]** (default): Use the [`ContextHandler::display`] +/// or [`AttachmentHandler::display`] method +/// - **[`Debug`]**: Use the [`ContextHandler::debug`] +/// or [`AttachmentHandler::debug`] method +/// +/// [`Debug`]: FormattingFunction::Debug +/// [`Display`]: FormattingFunction::Display /// /// # Examples /// @@ -530,10 +539,12 @@ pub struct AttachmentFormattingStyle { /// ``` #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] pub enum FormattingFunction { - /// Prefer display formatting via the `display` method. + /// Prefer display formatting via the + /// [`ContextHandler::display`]/[`AttachmentHandler::display`] method. #[default] Display, - /// Prefer debug formatting via the `debug` method. + /// Prefer debug formatting via the + /// [`ContextHandler::debug`]/[`AttachmentHandler::debug`] method. Debug, } diff --git a/rootcause-internals/src/report/data.rs b/rootcause-internals/src/report/data.rs index 9ba34ac..a5ec9cb 100644 --- a/rootcause-internals/src/report/data.rs +++ b/rootcause-internals/src/report/data.rs @@ -46,7 +46,7 @@ pub(crate) struct ReportData { /// The following safety invariants are guaranteed to be upheld as long as /// this struct exists: /// - /// 1. The vtable must always point to a `ReportVtable` created for the + /// 1. The vtable must always point to a [`ReportVtable`] created for the /// actual context type `C` stored below. This is true even when accessed /// via type-erased pointers. vtable: &'static ReportVtable, @@ -220,7 +220,7 @@ impl<'a> RawReportMut<'a> { /// The caller must ensure: /// /// 1. In case there are other references to the same report and they make - /// assumptions about the report children being `Send+Sync`, then those + /// assumptions about the report children being [`Send`] and [`Sync`], then those /// assumptions must be upheld when modifying the children. #[inline] pub unsafe fn into_children_mut(self) -> &'a mut Vec { @@ -245,7 +245,7 @@ impl<'a> RawReportMut<'a> { unsafe { &mut *children_ptr } } - /// Deconstructs the `RawReportMut` and returns a mutable reference to the + /// Deconstructs the [`RawReportMut`] and returns a mutable reference to the /// attachments vector. /// /// # Safety @@ -253,7 +253,7 @@ impl<'a> RawReportMut<'a> { /// The caller must ensure: /// /// 1. In case there are other references to the same report and they make - /// assumptions about the report attachments being `Send+Sync`, then + /// assumptions about the report attachments being [`Send`] and [`Sync`], then /// those assumptions must be upheld when modifying the attachments. #[inline] pub unsafe fn into_attachments_mut(self) -> &'a mut Vec { diff --git a/rootcause-internals/src/report/raw.rs b/rootcause-internals/src/report/raw.rs index 5808408..57d6fb5 100644 --- a/rootcause-internals/src/report/raw.rs +++ b/rootcause-internals/src/report/raw.rs @@ -61,12 +61,14 @@ pub struct RawReport { /// this struct exists: /// /// 1. The pointer must have been created from a - /// `triomphe::Arc>` for some `C` using - /// `triomphe::Arc::into_raw`. - /// 2. The pointer retains full provenance over the `Arc` for the entire + /// [`triomphe::Arc>`] for some `C` using + /// [`triomphe::Arc::into_raw`]. + /// 2. The pointer retains full provenance over the [`Arc`] for the entire /// lifetime of this object (i.e., it was not derived from a `&T`) - /// 3. The pointer will point to the same `ReportData` for the entire + /// 3. The pointer will point to the same [`ReportData`] for the entire /// lifetime of this object. + /// + /// [`Arc`]: triomphe::Arc ptr: NonNull>, } @@ -194,12 +196,14 @@ pub struct RawReportRef<'a> { /// this struct exists: /// /// 1. The pointer must have been created from a - /// `triomphe::Arc>` for some `C` using - /// `triomphe::Arc::into_raw`. - /// 2. The pointer retains full provenance over the `Arc` for the entire + /// [`triomphe::Arc>`] for some `C` using + /// [`triomphe::Arc::into_raw`]. + /// 2. The pointer retains full provenance over the [`Arc`] for the entire /// lifetime of this object (i.e., it was not derived from a `&T`) - /// 3. The pointer will point to the same `ReportData` for the entire + /// 3. The pointer will point to the same [`ReportData`] for the entire /// lifetime of this object. + /// + /// [`Arc`]: triomphe::Arc ptr: NonNull>, /// Marker to tell the compiler that we should @@ -384,16 +388,16 @@ pub struct RawReportMut<'a> { /// this struct exists: /// /// 1. The pointer must have been created from a - /// `triomphe::Arc>` for some `C` using - /// `triomphe::Arc::into_raw`. - /// 2. The pointer will point to the same `ReportData` for the entire + /// [`triomphe::Arc>`] for some `C` using + /// [`triomphe::Arc::into_raw`]. + /// 2. The pointer will point to the same [`ReportData`] for the entire /// lifetime of this object. /// 3. This pointer is valid for exclusive mutable access to the - /// `ReportData` with the same semantics as a `&'a mut ReportData`. + /// [`ReportData`] with the same semantics as a [`&'a mut ReportData`](ReportData). ptr: NonNull>, /// Marker to tell the compiler that we should - /// behave the same as a `&'a mut ReportData` + /// behave the same as a [`&'a mut ReportData`](ReportData) _marker: core::marker::PhantomData<&'a mut ReportData>, } diff --git a/rootcause-internals/src/report/vtable.rs b/rootcause-internals/src/report/vtable.rs index 5d08233..cc65c3b 100644 --- a/rootcause-internals/src/report/vtable.rs +++ b/rootcause-internals/src/report/vtable.rs @@ -44,7 +44,7 @@ use crate::{ /// `debug`, and `preferred_context_formatting_style` all point to the /// functions defined below /// * The concrete pointers are all instantiated with the same context type `C` -/// and handler type `H` that were used to create this `ReportVtable`. +/// and handler type `H` that were used to create this [`ReportVtable`]. pub(crate) struct ReportVtable { /// Gets the [`TypeId`] of the context type that was used to create this /// [`ReportVtable`]. @@ -58,17 +58,17 @@ pub(crate) struct ReportVtable { /// Method to drop the [`triomphe::Arc>`] instance pointed to /// by this pointer. drop: unsafe fn(NonNull>), - /// Clones the `triomphe::Arc>` pointed to by this pointer. + /// Clones the [`triomphe::Arc>`] pointed to by this pointer. clone_arc: unsafe fn(NonNull>) -> RawReport, /// Gets the strong count of the [`triomphe::Arc>`] pointed to /// by this pointer. strong_count: unsafe fn(RawReportRef<'_>) -> usize, - /// Returns a reference to the source of the error using the `source` method - /// on the handler. + /// Returns a reference to the source of the error using the + /// [`ContextHandler::source`] method. source: unsafe fn(RawReportRef<'_>) -> Option<&(dyn core::error::Error + 'static)>, - /// Formats the report using the `display` method on the handler. + /// Formats the report using the [`ContextHandler::display`] method. display: unsafe fn(RawReportRef<'_>, &mut core::fmt::Formatter<'_>) -> core::fmt::Result, - /// Formats the report using the `debug` method on the handler. + /// Formats the report using the [`ContextHandler::debug] method. debug: unsafe fn(RawReportRef<'_>, &mut core::fmt::Formatter<'_>) -> core::fmt::Result, /// Get the formatting style preferred by the context when formatted as part /// of a report. @@ -117,7 +117,7 @@ impl ReportVtable { (self.handler_type_id)() } - /// Drops the `triomphe::Arc>` instance pointed to by this + /// Drops the [`triomphe::Arc>`] instance pointed to by this /// pointer. /// /// # Safety @@ -155,13 +155,16 @@ impl ReportVtable { /// /// 1. The pointer comes from a [`triomphe::Arc>`] turned into /// a pointer via [`triomphe::Arc::into_raw`] - /// 2. The pointer has full provenance over the `Arc` (i.e., it was not + /// 2. The pointer has full provenance over the [`Arc`] (i.e., it was not /// derived from a `&T` reference) /// 3. This [`ReportVtable`] must be a vtable for the context type stored in /// the [`ReportData`]. /// 4. All other references to this report are compatible with shared - /// ownership. Specifically none of them assume that the strong_count is - /// `1`. + /// ownership. Specifically none of them assume that the [`strong_count`] is + /// 1. + /// + /// [`Arc`]: triomphe::Arc + /// [`strong_count`]: triomphe::Arc::strong_count #[inline] pub(super) unsafe fn clone_arc(&self, ptr: NonNull>) -> RawReport { // SAFETY: We know that `self.clone_arc` points to the function `clone_arc::` @@ -256,7 +259,7 @@ impl ReportVtable { } } - /// Formats the given `RawReportRef` using the [`H::debug`] function + /// Formats the given [`RawReportRef`] using the [`H::debug`] function /// used when creating this [`ReportVtable`]. /// /// [`H::debug`]: ContextHandler::debug @@ -350,12 +353,14 @@ pub(super) unsafe fn drop(ptr: NonNull>) { /// /// 1. The pointer comes from a [`triomphe::Arc>`] turned into a /// pointer via [`triomphe::Arc::into_raw`] -/// 2. The pointer has full provenance over the `Arc` (i.e., it was not derived +/// 2. The pointer has full provenance over the [`Arc`] (i.e., it was not derived /// from a `&T` reference) /// 3. The context type `C` matches the actual context type stored in the /// [`ReportData`] /// 4. All other references to this report are compatible with shared ownership. /// Specifically none of them assume that the strong_count is `1`. +/// +/// [`Arc`]: triomphe::Arc unsafe fn clone_arc(ptr: NonNull>) -> RawReport { let ptr: *const ReportData = ptr.cast::>().as_ptr(); diff --git a/rootcause-internals/src/util.rs b/rootcause-internals/src/util.rs index 3cf213f..14b64a0 100644 --- a/rootcause-internals/src/util.rs +++ b/rootcause-internals/src/util.rs @@ -3,9 +3,13 @@ /// Marker type used when type-erasing reports or attachments. /// /// This zero-sized type serves as a placeholder in generic type parameters -/// when the actual concrete type has been erased. For example, -/// `AttachmentData` represents an attachment whose concrete type -/// is unknown at the current scope. +/// when the actual concrete type has been erased. [`ReportData`] +/// represents a report whose concrete type +/// is unknown at the current scope, and [`AttachmentData`] same for +/// attachments. +/// +/// [`ReportData`]: crate::report::data::ReportData +/// [`AttachmentData`]: crate::attachment::data::AttachmentData /// /// Using a distinct marker type (rather than `()`) makes the intent clearer /// in type signatures and error messages. diff --git a/rootcause-tracing/src/lib.rs b/rootcause-tracing/src/lib.rs index d7d4cca..15f8776 100644 --- a/rootcause-tracing/src/lib.rs +++ b/rootcause-tracing/src/lib.rs @@ -285,7 +285,7 @@ pub struct SpanCollector { /// Whether to capture spans for all reports or only leaf reports (those /// without children). /// - /// When `true`, all reports get span attachments. When `false`, only leaf + /// When [`true`](bool), all reports get span attachments. When [`false`](bool), only leaf /// reports do. pub capture_span_for_reports_with_children: bool, } @@ -383,7 +383,7 @@ impl ReportCreationHook for SpanCollector { /// Extension trait for attaching tracing spans to reports. /// /// This trait provides methods to easily attach the current tracing span -/// to a report or to the error contained within a `Result`. +/// to a report or to the error contained within a [`Result`]. /// /// # Examples /// @@ -399,7 +399,7 @@ impl ReportCreationHook for SpanCollector { /// } /// ``` /// -/// Attach tracing span to a `Result`: +/// Attach tracing span to a [`Result`]: /// /// ``` /// use rootcause::{Report, report}; diff --git a/src/compat/anyhow1.rs b/src/compat/anyhow1.rs index 0b632ff..48a35a7 100644 --- a/src/compat/anyhow1.rs +++ b/src/compat/anyhow1.rs @@ -145,9 +145,9 @@ use crate::{Report, compat::ReportAsError, markers}; /// /// # Implementation Details /// -/// - **Display**: Uses [`anyhow::Error`]'s `Display` implementation -/// - **Debug**: Uses [`anyhow::Error`]'s `Debug` implementation -/// - **Source**: Uses [`anyhow::Error`]'s `source` method to traverse the error +/// - **Display**: Uses [`anyhow::Error`]'s [`std::fmt::Display`](core::fmt::Display) implementation +/// - **Debug**: Uses [`anyhow::Error`]'s [`std::fmt::Debug`](core::fmt::Debug)implementation +/// - **Source**: Uses [`anyhow::Error`]'s [`source`](core::error::Error::source) method to traverse the error /// chain /// - **Formatting style**: Matches the report's formatting function (Display or /// Debug) @@ -214,7 +214,7 @@ impl IntoRootcause for anyhow::Result { /// A trait for converting rootcause [`Report`]s into [`anyhow::Error`]. /// -/// This trait provides the `.into_anyhow()` method for converting rootcause +/// This trait provides the [`.into_anyhow()`](IntoAnyhow::into_anyhow) method for converting rootcause /// reports into anyhow errors. It's implemented for both [`Report`] and /// [`Result`], making it easy to call anyhow-based APIs from /// rootcause code. @@ -252,9 +252,9 @@ impl IntoRootcause for anyhow::Result { /// println!("{}", anyhow_err); /// ``` /// -/// ## Using `From` Instead +/// ## Using [`From`] Instead /// -/// You can also use the `From` trait for explicit conversions: +/// You can also use the [`From`] trait for explicit conversions: /// /// ``` /// use rootcause::{compat::anyhow1::IntoAnyhow, prelude::*}; diff --git a/src/compat/boxed_error.rs b/src/compat/boxed_error.rs index 00206ca..719613b 100644 --- a/src/compat/boxed_error.rs +++ b/src/compat/boxed_error.rs @@ -127,16 +127,16 @@ use crate::{ /// A custom handler for boxed error trait objects that delegates to the /// underlying error's formatting. /// -/// This handler ensures that boxed errors (`Box` and `Box`) display identically whether they're used directly or +/// This handler ensures that boxed errors ([`Box`] and +/// ([`Box`]) display identically whether they're used directly or /// wrapped in a rootcause [`Report`]. You typically don't need to use this /// handler directly - it's used automatically by the [`IntoRootcause`] trait. /// /// # Implementation Details /// -/// - **Display**: Uses the boxed error's `Display` implementation -/// - **Debug**: Uses the boxed error's `Debug` implementation -/// - **Source**: Uses the boxed error's `source` method to traverse the error +/// - **Display**: Uses the boxed error's [`Display`](core::fmt::Display) implementation +/// - **Debug**: Uses the boxed error's [`Debug`](core::fmt::Debug) implementation +/// - **Source**: Uses the boxed error's [`source`](core::error::Error::source) method to traverse the error /// chain /// - **Formatting style**: Matches the report's formatting function (Display or /// Debug) @@ -217,10 +217,10 @@ impl ContextHandler> for BoxedErrorHandler { /// A trait for converting rootcause [`Report`]s into boxed error trait objects. /// -/// This trait provides the `.into_boxed_error()` method for converting +/// This trait provides the [`.into_boxed_error()`](IntoBoxedError::into_boxed_error) method for converting /// rootcause reports into standard Rust error trait objects. It's implemented /// for both [`Report`] and [`Result`], making it easy to integrate -/// with APIs that expect `Box`. +/// with APIs that expect [`Box`]. /// /// The specific type of boxed error depends on the thread safety marker: /// - [`SendSync`] reports convert to `Box` @@ -259,9 +259,9 @@ impl ContextHandler> for BoxedErrorHandler { /// println!("{}", boxed_err); /// ``` /// -/// ## Using `From` Instead +/// ## Using [`From`] Instead /// -/// You can also use the `From` trait for explicit conversions: +/// You can also use the [`From`] trait for explicit conversions: /// /// ``` /// use std::error::Error; diff --git a/src/compat/error_stack05.rs b/src/compat/error_stack05.rs index 193c6c4..76e52d7 100644 --- a/src/compat/error_stack05.rs +++ b/src/compat/error_stack05.rs @@ -156,9 +156,9 @@ use crate::{ /// /// # Implementation Details /// -/// - **Display**: Uses [`error_stack::Report`]'s `Display` implementation -/// - **Debug**: Uses [`error_stack::Report`]'s `Debug` implementation -/// - **Source**: Uses the current context's `source` method to traverse the +/// - **Display**: Uses [`error_stack::Report`]'s [`Display`](core::fmt::Display) implementation +/// - **Debug**: Uses [`error_stack::Report`]'s [`Debug`](core::fmt::Debug) implementation +/// - **Source**: Uses the current context's [`source`](core::error::Error::source) method to traverse the /// error chain /// - **Formatting style**: Matches the report's formatting function (Display or /// Debug) @@ -227,7 +227,7 @@ where /// A trait for converting rootcause [`Report`]s into [`error_stack::Report`]. /// -/// This trait provides the `.into_error_stack()` method for converting +/// This trait provides the [`.into_error_stack()`](IntoErrorStack::into_error_stack) method for converting /// rootcause reports into error-stack reports. It's implemented for both /// [`Report`] and [`Result`], making it easy to call /// error-stack-based APIs from rootcause code. @@ -267,9 +267,9 @@ where /// println!("{}", es_report); /// ``` /// -/// ## Using `From` Instead +/// ## Using [`From`] Instead /// -/// You can also use the `From` trait for explicit conversions: +/// You can also use the [`From`] trait for explicit conversions: /// /// ``` /// # use error_stack05 as error_stack; diff --git a/src/compat/error_stack06.rs b/src/compat/error_stack06.rs index 14c1908..97bdb0c 100644 --- a/src/compat/error_stack06.rs +++ b/src/compat/error_stack06.rs @@ -149,9 +149,9 @@ use crate::{ /// /// # Implementation Details /// -/// - **Display**: Uses [`error_stack::Report`]'s `Display` implementation -/// - **Debug**: Uses [`error_stack::Report`]'s `Debug` implementation -/// - **Source**: Uses the current context's `source` method to traverse the +/// - **Display**: Uses [`error_stack::Report`]'s [`Display`](core::fmt::Display) implementation +/// - **Debug**: Uses [`error_stack::Report`]'s [`Debug`](core::fmt::Debug) implementation +/// - **Source**: Uses the current context's [`source`](core::error::Error::source) method to traverse the /// error chain /// - **Formatting style**: Matches the report's formatting function (Display or /// Debug) @@ -219,7 +219,7 @@ where /// A trait for converting rootcause [`Report`]s into [`error_stack::Report`]. /// -/// This trait provides the `.into_error_stack()` method for converting +/// This trait provides the [`.into_error_stack()`](IntoErrorStack::into_error_stack) method for converting /// rootcause reports into error-stack reports. It's implemented for both /// [`Report`] and [`Result`], making it easy to call /// error-stack-based APIs from rootcause code. @@ -257,9 +257,9 @@ where /// println!("{}", es_report); /// ``` /// -/// ## Using `From` Instead +/// ## Using [`From`] Instead /// -/// You can also use the `From` trait for explicit conversions: +/// You can also use the [`From`] trait for explicit conversions: /// /// ``` /// use rootcause::prelude::*; diff --git a/src/compat/eyre06.rs b/src/compat/eyre06.rs index f9862dd..2920fbf 100644 --- a/src/compat/eyre06.rs +++ b/src/compat/eyre06.rs @@ -145,9 +145,9 @@ use crate::{Report, compat::ReportAsError, markers}; /// /// # Implementation Details /// -/// - **Display**: Uses [`eyre::Report`]'s `Display` implementation -/// - **Debug**: Uses [`eyre::Report`]'s `Debug` implementation -/// - **Source**: Uses [`eyre::Report`]'s `source` method to traverse the error +/// - **Display**: Uses [`eyre::Report`]'s [`Display`](core::fmt::Display) implementation +/// - **Debug**: Uses [`eyre::Report`]'s [`Debug`](core::fmt::Debug) implementation +/// - **Source**: Uses [`eyre::Report`]'s [`source`](core::error::Error::source) method to traverse the error /// chain /// - **Formatting style**: Matches the report's formatting function (Display or /// Debug) @@ -214,7 +214,7 @@ impl IntoRootcause for eyre::Result { /// A trait for converting rootcause [`Report`]s into [`eyre::Report`]. /// -/// This trait provides the `.into_eyre()` method for converting rootcause +/// This trait provides the [`.into_eyre()`](IntoEyre::into_eyre) method for converting rootcause /// reports into eyre reports. It's implemented for both [`Report`] and /// [`Result`], making it easy to call eyre-based APIs from /// rootcause code. @@ -252,9 +252,9 @@ impl IntoRootcause for eyre::Result { /// println!("{}", eyre_err); /// ``` /// -/// ## Using `From` Instead +/// ## Using [`From`] Instead /// -/// You can also use the `From` trait for explicit conversions: +/// You can also use the [`From`] trait for explicit conversions: /// /// ``` /// use rootcause::prelude::*; diff --git a/src/compat/mod.rs b/src/compat/mod.rs index 054b05a..a95285a 100644 --- a/src/compat/mod.rs +++ b/src/compat/mod.rs @@ -39,7 +39,7 @@ //! support flexible integration patterns //! - **Information preservation**: Maintain error context and formatting across //! conversions where possible -//! - **Ergonomic APIs**: Use familiar Rust patterns like `From`/`Into` traits +//! - **Ergonomic APIs**: Use familiar Rust patterns like [`From`]/[`Into`] traits //! and extension traits with descriptive method names //! //! # Example @@ -80,8 +80,8 @@ use crate::{ /// handling libraries into rootcause reports. It's designed to be implemented /// by compatibility modules for different error handling libraries. /// -/// The trait provides the `.into_rootcause()` method, which can convert both -/// individual error values and `Result` types. This makes it easy to integrate +/// The trait provides the [`.into_rootcause()`](IntoRootcause::into_rootcause) method, which can convert both +/// individual error values and [`Result`] types. This makes it easy to integrate /// external error types with rootcause's error handling. /// /// # When to Use @@ -137,15 +137,15 @@ use crate::{ pub trait IntoRootcause { /// The type produced by the conversion. /// - /// For error types, this is typically [`Report`]. For `Result` types, this - /// is typically `Result`. + /// For error types, this is typically [`Report`]. For [`Result`] types, this + /// is typically [`Result`]. type Output; /// Converts this value into a rootcause type. /// /// The specific behavior depends on the type being converted: /// - For error types: wraps the error in a [`Report`] - /// - For `Result` types: converts the error variant while preserving the + /// - For [`Result`] types: converts the error variant while preserving the /// success value /// /// # Examples diff --git a/src/hooks/attachment_formatter.rs b/src/hooks/attachment_formatter.rs index 428fccc..8a8ca4a 100644 --- a/src/hooks/attachment_formatter.rs +++ b/src/hooks/attachment_formatter.rs @@ -187,8 +187,8 @@ use crate::{ pub(crate) struct HookMap { /// # Safety Invariant /// - /// The hook stored under `TypeId::of::()` is guaranteed to be an - /// instance of the type `Hook`. + /// The hook stored under [`TypeId::of::()`](core::any::TypeId::of) is guaranteed to be an + /// instance of the type [`Hook`]. map: HashMap, rustc_hash::FxBuildHasher>, } @@ -202,7 +202,7 @@ impl HookMap { /// Retrieves the formatter hook for the specified attachment /// type. /// - /// The returned hook is guaranteed to be an instance of type `Hook`, + /// The returned hook is guaranteed to be an instance of type [`Hook`], /// where `TypeId::of::() == type_id`. fn get(&self, type_id: TypeId) -> Option<&dyn StoredHook> { Some(&**self.map.get(&type_id)?) @@ -310,7 +310,7 @@ trait StoredHook: 'static + Send + Sync + core::fmt::Debug { /// The caller must ensure: /// /// 1. The type `A` stored in the attachment matches the `A` from type - /// `Hook` this is implemented for. + /// [`Hook`] this is implemented for. unsafe fn display( &self, attachment: ReportAttachmentRef<'_, Dynamic>, @@ -325,7 +325,7 @@ trait StoredHook: 'static + Send + Sync + core::fmt::Debug { /// The caller must ensure: /// /// 1. The type `A` stored in the attachment matches the `A` from type - /// `Hook` this is implemented for. + /// [`Hook`] this is implemented for. unsafe fn debug( &self, attachment: ReportAttachmentRef<'_, Dynamic>, diff --git a/src/hooks/builtin_hooks/location.rs b/src/hooks/builtin_hooks/location.rs index dd3d521..ee88348 100644 --- a/src/hooks/builtin_hooks/location.rs +++ b/src/hooks/builtin_hooks/location.rs @@ -34,7 +34,7 @@ pub struct Location { impl Location { /// Capture the caller's source code location. /// - /// This function uses Rust's built-in `core::panic::Location::caller()` to + /// This function uses Rust's built-in [`core::panic::Location::caller()`] to /// obtain the file and line number of the code that invoked it. /// /// # Examples diff --git a/src/hooks/context_formatter.rs b/src/hooks/context_formatter.rs index 65c10cd..6686598 100644 --- a/src/hooks/context_formatter.rs +++ b/src/hooks/context_formatter.rs @@ -129,8 +129,8 @@ use crate::{ pub(crate) struct HookMap { /// # Safety Invariant /// - /// The hook stored under `TypeId::of::()` is guaranteed to be an - /// instance of the type `Hook`. + /// The hook stored under [`TypeId::of::()`](core::any::TypeId::of) is guaranteed to be an + /// instance of the type [`Hook`]. map: HashMap, rustc_hash::FxBuildHasher>, } @@ -144,7 +144,7 @@ impl HookMap { /// Retrieves the formatter hook for the specified context /// type. /// - /// The returned hook is guaranteed to be an instance of type `Hook`, + /// The returned hook is guaranteed to be an instance of type [`Hook`], /// where `TypeId::of::() == type_id`. fn get(&self, type_id: TypeId) -> Option<&dyn StoredHook> { Some(&**self.map.get(&type_id)?) @@ -203,8 +203,8 @@ trait StoredHook: 'static + Send + Sync + core::fmt::Debug { /// /// The caller must ensure: /// - /// 1. The type `C` stored in the context matches the `C` from type `Hook` this is implemented for. + /// 1. The type `C` stored in the context matches the `C` from type + /// [`Hook`] this is implemented for. unsafe fn display( &self, report: ReportRef<'_, Dynamic, Uncloneable, Local>, @@ -217,8 +217,7 @@ trait StoredHook: 'static + Send + Sync + core::fmt::Debug { /// /// The caller must ensure: /// - /// 1. The type `C` stored in the context matches the `C` from type `Hook` this is implemented for. + /// 1. The type `C` stored in the context matches the `C` from type [`Hook`] this is implemented for. unsafe fn debug( &self, report: ReportRef<'_, Dynamic, Uncloneable, Local>, diff --git a/src/hooks/mod.rs b/src/hooks/mod.rs index e3e664a..12a3cc6 100644 --- a/src/hooks/mod.rs +++ b/src/hooks/mod.rs @@ -233,7 +233,7 @@ impl core::fmt::Display for HooksAlreadyInstalledError { impl core::error::Error for HooksAlreadyInstalledError {} impl Hooks { - /// Creates a new `Hooks` builder with location tracking. + /// Creates a new [`Hooks`] builder with location tracking. /// /// This is equivalent to using rootcause without installing any hooks - you /// get automatic location tracking. Use this as the base when you want to @@ -264,7 +264,7 @@ impl Hooks { })) } - /// Creates a new `Hooks` builder without location tracking. + /// Creates a new [`Hooks`] builder without location tracking. /// /// By default, rootcause automatically tracks source locations where errors /// occur. Use this method when you don't want that automatic tracking. @@ -581,7 +581,7 @@ impl Hooks { /// A handle to hooks that have been leaked into static memory. /// -/// You get a `HooksHandle` when calling [`Hooks::replace()`], which returns +/// You get a [`HooksHandle`] when calling [`Hooks::replace()`], which returns /// the previously installed hooks. The hooks remain in memory for the lifetime /// of the program unless you call the unsafe [`reclaim()`](Self::reclaim) /// method. @@ -596,7 +596,7 @@ impl Hooks { /// /// # Memory Leak Warning /// -/// Dropping a `HooksHandle` **will leak memory**. This is by design - the hooks +/// Dropping a [`HooksHandle`] **will leak memory**. This is by design - the hooks /// might still be referenced by other threads, so we can't safely deallocate /// them. In most applications this is fine since you typically install hooks /// once at startup. If you're replacing hooks frequently in tests or hot-reload @@ -644,17 +644,17 @@ impl Hooks { pub struct HooksHandle { /// # Safety /// - /// 1. This pointer points to a valid HookData that has been created by - /// calling `Box::into_raw` on a `Box`. + /// 1. This pointer points to a valid [`HookData`] that has been created by + /// calling [`Box::into_raw`] on a [`Box`]. /// 2. This struct has exclusive ownership of the pointer. No other - /// `HooksHandle` instances exist pointing to the same data. + /// [`HooksHandle`] instances exist pointing to the same data. /// 3. There might exist shared references to the HookData created by - /// `use_hooks`. These references are always temporary (scoped to the - /// `use_hooks` call) and read-only. Deallocation through `reclaim()` is + /// [`use_hooks`]. These references are always temporary (scoped to the + /// [`use_hooks`] call) and read-only. Deallocation through [`reclaim()`](Self::reclaim) is /// only safe when the caller can guarantee no such references exist or /// will be created in the future. /// 4. No mutation or deallocation of the pointed-to data will occur until - /// `reclaim()` is called. + /// [`reclaim()`](Self::reclaim) is called. hook_data: NonNull, } @@ -720,16 +720,16 @@ impl HooksHandle { /// # Safety /// /// 1. The caller must guarantee that, if this pointer came from being - /// installed globally, then all calls to `use_hooks` that might have + /// installed globally, then all calls to [`use_hooks`] that might have /// used this pointer have completed, and that no future calls to - /// `use_hooks` will use this pointer. + /// [`use_hooks`] will use this pointer. pub unsafe fn reclaim(self) -> Hooks { // SAFETY: // - We know that the pointer is valid and was obtained from `Box::into_raw` // because of the struct invariant. // - We know that we have exclusive ownership of the pointer because of the // struct invariant. - // - The caller has guaranteed that all calls to `use_hooks` that might have + // - The caller has guaranteed that all calls to use_hooks that might have // used this pointer have completed. Since this is the only way to access the // pointer, we can safely convert it back into a Box here. let boxed = unsafe { @@ -749,15 +749,15 @@ struct GlobalHooks { /// # Safety /// /// 1. This pointer will either be null, or point to a valid HookData that - /// has been created using `Box::into_raw`. + /// has been created using [`Box::into_raw`]. /// 2. If the pointer is non-null, then it is owned by this struct. - /// 3. All writing to the `AtomicPtr` is done using release semantics. - /// 4. All reading from the `AtomicPtr` is done using acquire semantics when + /// 3. All writing to the [`AtomicPtr`] is done using release semantics. + /// 4. All reading from the [`AtomicPtr`] is done using acquire semantics when /// the pointer will be dereferenced and with relaxed semantics /// otherwise. /// 5. If the pointer is replaced, then the previous pointer might still be /// referenced by this or other threads in the process of executing - /// `use_hooks`, so it must not be deallocated or mutated until it is + /// [`use_hooks`], so it must not be deallocated or mutated until it is /// certain that all such function calls have completed. ptr: AtomicPtr, } @@ -773,8 +773,8 @@ impl GlobalHooks { /// /// # Safety /// - /// 1. The `new` pointer is valid and points to a `Box` that has - /// been turned into a raw pointer using `Box::into_raw`. + /// 1. The `new` pointer is valid and points to a [`Box`] that has + /// been turned into a raw pointer using [`Box::into_raw`]. /// 2. On success the function claims ownership of the `new` pointer, and it /// cannot be used by the caller anymore. /// 3. On failure, the `new` pointer remains owned by the caller, and no @@ -798,14 +798,14 @@ impl GlobalHooks { /// /// # Safety /// - /// 1. The `new` pointer is valid and points to a `Box` that has - /// been turned into a raw pointer using `Box::into_raw`. + /// 1. The `new` pointer is valid and points to a [`Box`](HookData) that has + /// been turned into a raw pointer using [`Box::into_raw`]. /// 2. The function claims ownership of the `new` pointer. - /// 3. If the function returns `Some(ptr)`, then ownership of that pointer + /// 3. If the function returns [`Some(ptr)`], then ownership of that pointer /// is transferred to the caller. The returned pointer is similarly - /// guaranteed to have been created using `Box::into_raw`. + /// guaranteed to have been created using [`Box::into_raw`]. /// 4. The returned pointer might still be referenced by this or other - /// threads in the process of executing `use_hooks`, so it must not be + /// threads in the process of executing [`use_hooks`], so it must not be /// deallocated or mutated until it is certain that all such function /// calls have completed. unsafe fn replace(&self, new: NonNull) -> Option> { @@ -819,10 +819,10 @@ impl GlobalHooks { static HOOKS: GlobalHooks = GlobalHooks::new(); -/// A trait for calling hook functions with optional `HookData`. +/// A trait for calling hook functions with optional [`HookData`] /// -/// This is functionally similar to `FnOnce(Option<&HookData>) -> R`, but -/// adds a `#[track_caller]` to allow `report_creation` hooks to track the +/// This is functionally similar to [`FnOnce(Option<&HookData>) -> R`](FnOnce), but +/// adds a `#[track_caller]` to allow [`report_creation`](crate::hooks::report_creation) hooks to track the /// caller location. pub(crate) trait HookCallback { #[track_caller] diff --git a/src/into_report.rs b/src/into_report.rs index c3789f1..2f78330 100644 --- a/src/into_report.rs +++ b/src/into_report.rs @@ -18,8 +18,8 @@ use crate::{markers, prelude::Report, report_collection::ReportCollection}; /// # Automatic Implementations /// /// This trait is automatically implemented for: -/// - All types implementing `std::error::Error` (converts to new `Report`) -/// - Existing `Report` instances (performs identity or marker conversion) +/// - All types implementing [`core::error::Error`] (converts to new [`Report`]) +/// - Existing [`Report`] instances (performs identity or marker conversion) /// /// # Thread Safety /// @@ -27,17 +27,17 @@ use crate::{markers, prelude::Report, report_collection::ReportCollection}; /// - [`markers::SendSync`]: Report can be sent across threads /// - [`markers::Local`]: Report is restricted to the current thread /// -/// When converting from `SendSync` to `Local`, the conversion always succeeds. -/// Converting from `Local` to `SendSync` is only available if the context type -/// is `Send + Sync`. +/// When converting from [`SendSync`] to [`Local`], the conversion always succeeds. +/// Converting from [`Local`] to [`SendSync`] is only available if the context type +/// is [`Send`] and [`Sync`] /// /// # Typical Usage /// /// Most applications won't need to call this trait directly. Instead, consider: /// - Using [`report!`](crate::report!) to create reports from errors or strings /// - Using [`ResultExt`](crate::result_ext::ResultExt) methods to add context -/// to `Result` types -/// - Using the `From` trait for generic type conversions +/// to [`Result`] types +/// - Using the [`From`] trait for generic type conversions /// /// # Examples /// diff --git a/src/markers.rs b/src/markers.rs index f0c7936..32c28e3 100644 --- a/src/markers.rs +++ b/src/markers.rs @@ -362,31 +362,37 @@ pub struct Cloneable; /// Marker type for non-cloneable report references. /// -/// This marker is used exclusively with [`ReportRef`](crate::ReportRef) (not [`Report`](crate::Report)). It -/// indicates that the reference does not provide the -/// [`clone_arc`](crate::ReportRef::clone_arc) method to obtain an owned report. +/// This marker is used exclusively with +/// [`ReportRef`](crate::ReportRef) (not [`Report`]. +/// It indicates that the reference does not provide the +/// [`clone_arc`] method to obtain an owned report. /// -/// Note that `ReportRef` itself is always `Copy` and `Clone` - you can always -/// copy the reference itself. The `Uncloneable` marker only prevents cloning -/// the underlying `Arc` to get an owned `Report`. +/// Note that [`ReportRef`] itself is always [`Copy`] and [`Clone`] - you can always +/// copy the reference itself. The [`Uncloneable`] marker only prevents cloning +/// the underlying [`Arc`] to get an owned [`Report`]. /// /// # Common Uses /// -/// `Uncloneable` references typically arise in two situations: +/// [`Uncloneable`] references typically arise in two situations: /// -/// 1. **Taking a reference to a `Mutable` report**: When you call -/// [`as_ref`](crate::Report::as_ref) on a `Report`, you get a -/// `ReportRef` because the underlying report has unique +/// 1. **Taking a reference to a [`Mutable`] report**: When you call +/// [`as_ref`] on a [`Report`](crate::Report), you get a +/// [`ReportRef`](crate::ReportRef) because the underlying report has unique /// ownership. /// -/// 2. **Explicitly restricting cloneability**: You can convert a `ReportRef` to `ReportRef` when you want to pass a -/// reference that explicitly cannot use `clone_arc`, ensuring the recipient +/// 2. **Explicitly restricting cloneability**: You can convert a +/// [`ReportRef`](crate::ReportRef) to +/// [`ReportRef`](crate::ReportRef) when you want to pass a +/// reference that explicitly cannot use [`clone_arc`], ensuring the recipient /// can only inspect the report without obtaining ownership. This can be /// useful in APIs that need to accept both cloneable and uncloneable /// references. /// +/// [`as_ref`]: crate::Report::as_ref +/// [`clone_arc`]: crate::ReportRef::clone_arc +/// [`ReportRef`]: crate::ReportRef +/// [`Arc`]: triomphe::Arc +/// [`Report`]: crate::Report /// /// # Examples /// diff --git a/src/report/mut_.rs b/src/report/mut_.rs index f54ff5d..bd8e6bc 100644 --- a/src/report/mut_.rs +++ b/src/report/mut_.rs @@ -30,7 +30,7 @@ mod limit_field_access { /// /// # Key Characteristics /// - /// - **Not `Copy` or `Clone`**: Ensures exclusive mutable access + /// - **Not [`Copy`] or [`Clone`]**: Ensures exclusive mutable access /// - **Lifetime-bound**: Tied to the lifetime of the underlying report /// - **Two type parameters**: Has context type `C` and thread safety marker /// `T` (no ownership marker since mutable references are always uniquely @@ -86,18 +86,18 @@ mod limit_field_access { /// /// The following safety invariants are guaranteed to be upheld as long /// as this struct exists and must be continue to be upheld as - /// long as the inner `RawReportMut` exists: + /// long as the inner [`RawReportMut`] exists: /// - /// 1. `C` must either be a type bounded by `Sized`, or `Dynamic`. - /// 2. `T` must either be `SendSync` or `Local`. - /// 3. If `C` is a `Sized` type: The context embedded in the report must + /// 1. `C` must either be a type bounded by [`Sized`], or [`Dynamic`]. + /// 2. `T` must either be [`SendSync`] or [`Local`](crate::markers::Local). + /// 3. If `C` is a [`Sized`] type: The context embedded in the report must /// be of type `C` - /// 4. The strong count of the underlying `triomphe::Arc` is exactly 1. + /// 4. The strong count of the underlying [`triomphe::Arc`] is exactly 1. /// 5. All references to any sub-reports of this report are compatible /// with shared ownership. Specifically there are no references with - /// an assumption that the strong_count is `1`. + /// an assumption that the [`strong_count`](triomphe::Arc::strong_count) is 1. /// 7. If `T = SendSync`: All contexts and attachments in the report and - /// all sub-reports must be `Send+Sync` + /// all sub-reports must be [`Send`] and [`Sync`] /// 8. If `T = Local`: No other references to this report are allowed to /// have `T = SendSync` raw: RawReportMut<'a>, @@ -112,14 +112,14 @@ mod limit_field_access { /// /// The caller must ensure: /// - /// 1. `C` must either be a type bounded by `Sized`, or `Dynamic`. - /// 2. `T` must either be `SendSync` or `Local`. - /// 3. If `C` is a `Sized` type: The context embedded in the report must + /// 1. `C` must either be a type bounded by [`Sized`], or [`Dynamic`]. + /// 2. `T` must either be [`SendSync`] or [`Local`](crate::markers::Local). + /// 3. If `C` is a [`Sized`] type: The context embedded in the report must /// be of type `C` - /// 4. The strong count of the underlying `triomphe::Arc` is exactly 1. + /// 4. The strong count of the underlying [`triomphe::Arc`] is exactly 1. /// 5. All references to any sub-reports of this report are compatible /// with shared ownership. Specifically there are no references with - /// an assumption that the strong_count is `1`. + /// an assumption that the [`strong_count`](triomphe::Arc::strong_count) is 1. /// 6. If `T = SendSync`: All contexts and attachments in the report and /// all sub-reports must be `Send+Sync` /// 7. If `T = Local`: No other references to this report are allowed to @@ -167,7 +167,7 @@ mod limit_field_access { /// The caller must ensure: /// /// 1. If `T = SendSync`, no objects are added to the report through - /// this `RawReportMut` that are not `Send+Sync` + /// this [`RawReportMut`] that are not [`Send`] and [`Sync`] #[must_use] pub(crate) unsafe fn into_raw_mut(self) -> RawReportMut<'a> { // SAFETY: We need to uphold the safety invariants of the raw field: @@ -194,7 +194,7 @@ mod limit_field_access { /// The caller must ensure: /// /// 1. If `T = SendSync`, no objects are added to the report through - /// this `RawReportMut` that are not `Send+Sync` + /// this [`RawReportMut`] that are not `Send+Sync` #[must_use] pub(crate) unsafe fn as_raw_mut<'b>(&'b mut self) -> RawReportMut<'b> { // SAFETY: We need to uphold the safety invariants of the raw field: @@ -848,7 +848,8 @@ impl<'a, C: ?Sized, T> ReportMut<'a, C, T> { /// - Testing different formatters /// - Using different formatters in different parts of your application /// - /// Unlike the default `Display` and `Debug` implementations which use the + /// Unlike the default [`.format_current_context()`](Self::format_current_context)'s + /// [`Display`](core::fmt::Display) and [`Debug`](core::fmt::Debug) implementations which use the /// globally registered hook, this method uses the hook you provide /// directly. /// @@ -951,8 +952,8 @@ impl<'a, C: ?Sized, T> ReportMut<'a, C, T> { impl<'a, T> ReportMut<'a, Dynamic, T> { /// Attempts to downcast the current context to a specific type. /// - /// Returns `Some(&C)` if the current context is of type `C`, otherwise - /// returns `None`. + /// Returns [`Some(&C)`] if the current context is of type `C`, otherwise + /// returns [`None`]. /// /// # Examples /// ``` @@ -974,8 +975,8 @@ impl<'a, T> ReportMut<'a, Dynamic, T> { /// 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`. + /// Returns [`Some(&mut C)`] if the current context is of type `C`, otherwise + /// returns [`None`]. /// /// # Examples /// ``` @@ -1075,8 +1076,8 @@ impl<'a, T> ReportMut<'a, Dynamic, T> { /// Attempts to downcast the entire report to a specific context type. /// - /// Returns `Ok(ReportMut)` if the current context is of type `C`, - /// otherwise returns `Err(self)` with the original report. + /// Returns [`Ok(ReportMut)`](ReportMut) if the current context is of type `C`, + /// otherwise returns [`Err(self)`](Result::Err) with the original report. /// /// # Examples /// ``` diff --git a/src/report/owned.rs b/src/report/owned.rs index 7ee3264..3f36ab1 100644 --- a/src/report/owned.rs +++ b/src/report/owned.rs @@ -85,22 +85,22 @@ mod limit_field_access { /// The following safety invariants are guaranteed to be upheld as long /// as this struct exists: /// - /// 1. `C` must either be a type bounded by `Sized`, or `Dynamic`. - /// 2. `O` must either be `Mutable` or `Cloneable`. - /// 3. `T` must either be `SendSync` or `Local`. - /// 4. If `C` is a `Sized` type: The context embedded in the report must + /// 1. `C` must either be a type bounded by [`Sized`], or [`Dynamic`]. + /// 2. `O` must either be [`Mutable`] or [`Cloneable`]. + /// 3. `T` must either be [`SendSync`] or [`Local`]. + /// 4. If `C` is a [`Sized`] type: The context embedded in the report must /// be of type `C` /// 5. If `O = Mutable`: This is the unique owner of the report. More /// specifically this means that the strong count of the underlying - /// `triomphe::Arc` is exactly 1. + /// [`triomphe::Arc`] is exactly 1. /// 6. If `O = Cloneable`: All other references to this report are /// compatible with shared ownership. Specifically there are no - /// references with an assumption that the strong_count is `1`. + /// references with an assumption that the [`strong_count`](triomphe::Arc::strong_count) is `1`. /// 7. All references to any sub-reports of this report are compatible /// with shared ownership. Specifically there are no references with /// an assumption that the strong_count is `1`. /// 8. If `T = SendSync`: All contexts and attachments in the report and - /// all sub-reports must be `Send+Sync`. + /// all sub-reports must be [`Send`] and [`Sync`]. raw: RawReport, _context: PhantomData, _ownership: PhantomData, @@ -242,8 +242,8 @@ impl Report { /// # use rootcause::{prelude::*, markers::{SendSync, Mutable, Local}}; /// # #[derive(Debug)] /// # struct MyError; - /// # impl core::error::Error for MyError {} - /// # impl core::fmt::Display for MyError { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { unimplemented!() }} + /// # impl std::error::Error for MyError {} + /// # impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { unimplemented!() }} /// let report_sendsync: Report = Report::new(MyError); /// let report_local: Report = Report::new(MyError); /// ``` @@ -269,8 +269,8 @@ impl Report { /// # use rootcause::{prelude::*, markers::{SendSync, Local}}; /// # #[derive(Debug)] /// # struct MyError; - /// # impl core::error::Error for MyError {} - /// # impl core::fmt::Display for MyError { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { unimplemented!() }} + /// # impl std::error::Error for MyError {} + /// # impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { unimplemented!() }} /// let report_sendsync: Report = Report::new_custom::(MyError); /// let report_local: Report = Report::new_custom::(MyError); /// ``` @@ -1248,7 +1248,7 @@ impl Report { /// ``` /// # use rootcause::{prelude::*, preformatted::PreformattedContext, ReportRef, markers::{Uncloneable, Mutable, SendSync, Local}}; /// # #[derive(Default)] - /// # struct NonSendSyncError(core::cell::Cell<()>); + /// # struct NonSendSyncError(std::cell::Cell<()>); /// # let non_send_sync_error = NonSendSyncError::default(); /// let mut report: Report = report!(non_send_sync_error); /// let preformatted: Report = report.preformat(); @@ -1265,7 +1265,7 @@ impl Report { /// # Examples /// ``` /// # use rootcause::{prelude::*, markers::Dynamic}; - /// # use core::any::TypeId; + /// # use std::any::TypeId; /// # struct MyError; /// let report: Report = report!(MyError); /// let type_id = report.current_context_type_id(); @@ -1285,16 +1285,16 @@ impl Report { /// # Examples /// ``` /// # use rootcause::{prelude::*, markers::Dynamic}; - /// # use core::any::TypeId; + /// # use std::any::TypeId; /// # struct MyError; /// # let report = report!(MyError).into_cloneable(); /// let report: Report = report!(MyError); /// let type_name = report.current_context_type_name(); - /// assert_eq!(type_name, core::any::type_name::()); + /// assert_eq!(type_name, std::any::type_name::()); /// /// let report: Report = report.into_dynamic(); /// let type_name = report.current_context_type_name(); - /// assert_eq!(type_name, core::any::type_name::()); + /// assert_eq!(type_name, std::any::type_name::()); /// ``` #[must_use] pub fn current_context_type_name(&self) -> &'static str { @@ -1309,8 +1309,8 @@ impl Report { /// # Examples /// ``` /// # use rootcause::{prelude::*, markers::SendSync}; - /// # use core::any::TypeId; - /// let report = Report::new_sendsync_custom::("error message"); + /// # use std::any::TypeId; + /// let report : Report<&'static str> = Report::new_custom::("error message"); /// let handler_type = report.current_context_handler_type_id(); /// assert_eq!(handler_type, TypeId::of::()); /// ``` @@ -1326,9 +1326,9 @@ impl Report { /// # Examples /// ``` /// # use rootcause::prelude::*; - /// # use core::any::TypeId; + /// # use std::any::TypeId; /// let report: Report = report!("error message"); - /// let source: Option<&dyn core::error::Error> = report.current_context_error_source(); + /// let source: Option<&dyn std::error::Error> = report.current_context_error_source(); /// assert!(source.is_none()); // The context does not implement Error, so no source /// /// #[derive(Debug, thiserror::Error)] @@ -1538,7 +1538,7 @@ impl Report { /// # Examples /// ``` /// # use rootcause::prelude::*; - /// # use core::any::TypeId; + /// # use std::any::TypeId; /// # struct MyError; /// let report: Report = report!(MyError); /// let dyn_report: Report = report.into_dynamic(); @@ -1604,7 +1604,7 @@ impl Report { /// # Examples /// ``` /// # use rootcause::prelude::*; - /// # use core::any::TypeId; + /// # use std::any::TypeId; /// # struct MyError; /// let report: Report = report!(MyError); /// let dyn_report: Report = report.into_dynamic(); @@ -1650,8 +1650,8 @@ impl Report { /// # use rootcause::prelude::*; /// # #[derive(Debug)] /// # struct MyError; - /// # impl core::error::Error for MyError {} - /// # impl core::fmt::Display for MyError { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { unimplemented!() }} + /// # impl std::error::Error for MyError {} + /// # impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { unimplemented!() }} /// let report = Report::new_sendsync(MyError); /// ``` #[track_caller] @@ -1700,8 +1700,8 @@ impl Report { /// # use rootcause::prelude::*; /// # #[derive(Debug)] /// # struct MyError; - /// # impl core::error::Error for MyError {} - /// # impl core::fmt::Display for MyError { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { unimplemented!() }} + /// # impl std::error::Error for MyError {} + /// # impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { unimplemented!() }} /// let report = Report::new_local(MyError); /// ``` #[track_caller] @@ -1735,13 +1735,13 @@ impl Report { } } -// SAFETY: The `SendSync` marker indicates that all objects in the report are -// `Send`+`Sync`. Therefore it is safe to implement `Send`+`Sync` for the report +// SAFETY: The SendSync marker indicates that all objects in the report are +// Send + Sync. Therefore it is safe to implement Send + Sync for the report // itself. unsafe impl Send for Report {} -// SAFETY: The `SendSync` marker indicates that all objects in the report are -// `Send`+`Sync`. Therefore it is safe to implement `Send`+`Sync` for the report +// SAFETY: The SendSync marker indicates that all objects in the report are +// Send + Sync. Therefore it is safe to implement Send + Sync for the report // itself. unsafe impl Sync for Report {} diff --git a/src/report_attachment/mut_.rs b/src/report_attachment/mut_.rs index 9f5cd70..2cb966f 100644 --- a/src/report_attachment/mut_.rs +++ b/src/report_attachment/mut_.rs @@ -255,6 +255,23 @@ impl<'a, A: ?Sized> ReportAttachmentMut<'a, A> { /// Reborrows the [`ReportAttachmentMut`] to return a new /// [`ReportAttachmentMut`] with a shorter lifetime. + /// + /// # Examples + /// + /// ``` + /// # use rootcause::handlers::*; + /// # use rootcause::report_attachment::*; + /// let mut atch = ReportAttachment::new_sendsync_custom::(40i32); + /// { + /// let mut atch_mut_1 = atch.as_mut(); + /// { + /// let mut atch_mut_2 = atch_mut_1.as_mut(); + /// *atch_mut_2.inner_mut() += 1; + /// } + /// *atch_mut_1.inner_mut() += 1; + /// } + /// assert_eq!(atch.inner(), &42i32); + /// ``` #[must_use] pub fn as_mut(&mut self) -> ReportAttachmentMut<'_, A> { let raw = self.as_raw_mut();