AtTraceable

Trait AtTraceable 

Source
pub trait AtTraceable: Sized {
Show 21 methods // Required methods fn trace_mut(&mut self) -> &mut AtTrace; fn trace(&self) -> Option<&AtTrace>; fn fmt_message(&self, f: &mut Formatter<'_>) -> Result; // Provided methods fn at(self) -> Self { ... } fn at_str(self, msg: &'static str) -> Self { ... } fn at_string(self, f: impl FnOnce() -> String) -> Self { ... } fn at_data<T: Display + Send + Sync + 'static>( self, f: impl FnOnce() -> T, ) -> Self { ... } fn at_debug<T: Debug + Send + Sync + 'static>( self, f: impl FnOnce() -> T, ) -> Self { ... } fn at_error<E: Error + Send + Sync + 'static>(self, err: E) -> Self { ... } fn at_crate(self, info: &'static AtCrateInfo) -> Self { ... } fn at_fn<F: Fn()>(self, _marker: F) -> Self { ... } fn at_named(self, name: &'static str) -> Self { ... } fn at_pop(&mut self) -> Option<AtFrameOwned> { ... } fn at_push(&mut self, segment: AtFrameOwned) { ... } fn at_first_pop(&mut self) -> Option<AtFrameOwned> { ... } fn at_first_insert(&mut self, segment: AtFrameOwned) { ... } fn map_traceable<E2, F>(self, f: F) -> E2 where F: FnOnce(Self) -> E2, E2: AtTraceable { ... } fn into_at<E2, F>(self, f: F) -> At<E2> where F: FnOnce(Self) -> E2 { ... } fn full_trace(&self) -> impl Display + '_ { ... } fn last_error_trace(&self) -> impl Display + '_ { ... } fn last_error(&self) -> impl Display + '_ { ... }
}
Expand description

Trait for types that embed an AtTrace directly.

Implement this trait to get all the .at_*() methods on your custom error types. Three methods are required:

§Example: Inline trace

use whereat::{AtTrace, AtTraceable};
use std::fmt;

struct MyError {
    kind: &'static str,
    trace: AtTrace,
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace { &mut self.trace }
    fn trace(&self) -> Option<&AtTrace> { Some(&self.trace) }
    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.kind)
    }
}

impl MyError {
    #[track_caller]
    fn new(kind: &'static str) -> Self {
        Self { kind, trace: AtTrace::capture() }
    }
}

// Now you can chain .at_*() methods
let err = MyError::new("not_found").at_str("looking up user");

§Example: Boxed trace (smaller error type)

use whereat::{AtTrace, AtTraceable};
use std::fmt;

struct MyError {
    kind: &'static str,
    trace: Box<AtTrace>,  // 8 bytes instead of sizeof(AtTrace)
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace { &mut self.trace }
    fn trace(&self) -> Option<&AtTrace> { Some(&self.trace) }
    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.kind)
    }
}

impl MyError {
    #[track_caller]
    fn new(kind: &'static str) -> Self {
        Self { kind, trace: Box::new(AtTrace::capture()) }
    }
}

§Example: Optional boxed trace (lazy allocation)

use whereat::{AtTrace, AtTraceable};
use std::fmt;

struct MyError {
    kind: &'static str,
    trace: Option<Box<AtTrace>>,  // None until first .at_*() call
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace {
        self.trace.get_or_insert_with(|| Box::new(AtTrace::new()))
    }
    fn trace(&self) -> Option<&AtTrace> { self.trace.as_deref() }
    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.kind)
    }
}

impl MyError {
    fn new(kind: &'static str) -> Self {  // No #[track_caller] needed
        Self { kind, trace: None }
    }
}

// Trace allocated lazily on first .at_*() call
let err = MyError::new("not_found").at_str("context");

§Why use this over At<E>?

Use AtTraceable when you want:

  • Full control over your error type’s layout
  • Custom storage strategy (inline, boxed, or optional)
  • To define your own error constructors

Use At<E> when you want:

  • Minimal changes to existing code
  • To wrap errors from external crates
  • The simplest possible setup

Required Methods§

Source

fn trace_mut(&mut self) -> &mut AtTrace

Get a mutable reference to the embedded trace.

Source

fn trace(&self) -> Option<&AtTrace>

Get an immutable reference to the trace, if allocated.

Returns None if no trace has been allocated yet (for lazy storage patterns). For inline storage, this always returns Some.

Source

fn fmt_message(&self, f: &mut Formatter<'_>) -> Result

Format just the error message (without trace).

This is used by the trace formatters to show the error message separately from the trace. Typically delegates to your error kind’s Display.

§Example
use whereat::{AtTrace, AtTraceable};
use std::fmt;

#[derive(Debug)]
enum ErrorKind {
    NotFound,
    InvalidInput(String),
}

struct MyError {
    kind: ErrorKind,
    trace: AtTrace,
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace { &mut self.trace }
    fn trace(&self) -> Option<&AtTrace> { Some(&self.trace) }

    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self.kind {
            ErrorKind::NotFound => write!(f, "not found"),
            ErrorKind::InvalidInput(s) => write!(f, "invalid input: {}", s),
        }
    }
}

Provided Methods§

Source

fn at(self) -> Self

Add the caller’s location to the trace.

Source

fn at_str(self, msg: &'static str) -> Self

Add a static string context to the last location (or create one if empty).

Source

fn at_string(self, f: impl FnOnce() -> String) -> Self

Add a lazily-computed string context to the last location (or create one if empty).

Source

fn at_data<T: Display + Send + Sync + 'static>( self, f: impl FnOnce() -> T, ) -> Self

Add lazily-computed typed context (Display) to the last location (or create one if empty).

Source

fn at_debug<T: Debug + Send + Sync + 'static>( self, f: impl FnOnce() -> T, ) -> Self

Add lazily-computed typed context (Debug) to the last location (or create one if empty).

Source

fn at_error<E: Error + Send + Sync + 'static>(self, err: E) -> Self

Add an error as context to the last location (or create one if empty).

Use this to attach a source error that implements core::error::Error.

Source

fn at_crate(self, info: &'static AtCrateInfo) -> Self

Add a crate boundary marker to the last location (or create one if empty).

Uses inline storage if no crate_info is set yet; only allocates a context entry when crossing to a different crate.

Source

fn at_fn<F: Fn()>(self, _marker: F) -> Self

Add a location frame with the caller’s function name as context.

Captures both file:line:col AND the function name at zero runtime cost. Pass an empty closure || {} - its type includes the parent function name.

§Example
use whereat::{AtTrace, AtTraceable};

struct MyError {
    trace: AtTrace,
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace { &mut self.trace }
    fn trace(&self) -> Option<&AtTrace> { Some(&self.trace) }
    fn fmt_message(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "my error")
    }
}

impl MyError {
    #[track_caller]
    fn new() -> Self {
        Self { trace: AtTrace::capture() }
    }
}

fn do_something() -> Result<(), MyError> {
    Err(MyError::new().at_fn(|| {}))  // Captures file:line + "do_something"
}
Source

fn at_named(self, name: &'static str) -> Self

Add a location frame with an explicit name as context.

Like at_fn but with an explicit label instead of auto-detecting the function name.

Source

fn at_pop(&mut self) -> Option<AtFrameOwned>

Pop the most recent location and its contexts from the trace.

Source

fn at_push(&mut self, segment: AtFrameOwned)

Push a segment (location + contexts) to the end of the trace.

Source

fn at_first_pop(&mut self) -> Option<AtFrameOwned>

Pop the oldest location and its contexts from the trace.

Source

fn at_first_insert(&mut self, segment: AtFrameOwned)

Insert a segment (location + contexts) at the beginning of the trace.

Source

fn map_traceable<E2, F>(self, f: F) -> E2
where F: FnOnce(Self) -> E2, E2: AtTraceable,

Convert to another AtTraceable type, transferring the trace.

The trace is moved from self to the new error.

Source

fn into_at<E2, F>(self, f: F) -> At<E2>
where F: FnOnce(Self) -> E2,

Convert to At<E2>, transferring the trace.

Source

fn full_trace(&self) -> impl Display + '_

Format with full trace (message + all frames with contexts).

Returns a formatter that displays:

  • The error message (via fmt_message)
  • All trace frames with locations
  • All context strings attached to each frame
  • Nested error chains for error contexts
§Example
use whereat::{AtTrace, AtTraceable};
use std::fmt;

struct MyError {
    msg: &'static str,
    trace: AtTrace,
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace { &mut self.trace }
    fn trace(&self) -> Option<&AtTrace> { Some(&self.trace) }
    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.msg)
    }
}

impl MyError {
    #[track_caller]
    fn new(msg: &'static str) -> Self {
        Self { msg, trace: AtTrace::capture() }
    }
}

let err = MyError::new("something failed").at_str("while loading");
println!("{}", err.full_trace());
// Output:
// something failed
//     at src/main.rs:10:15
//         while loading
Source

fn last_error_trace(&self) -> impl Display + '_

Format with trace locations only (message + locations, no context strings).

Returns a formatter that displays:

  • The error message (via fmt_message)
  • All trace frame locations
  • NO context strings (for compact output)
§Example
use whereat::{AtTrace, AtTraceable};
use std::fmt;

struct MyError {
    msg: &'static str,
    trace: AtTrace,
}

impl AtTraceable for MyError {
    fn trace_mut(&mut self) -> &mut AtTrace { &mut self.trace }
    fn trace(&self) -> Option<&AtTrace> { Some(&self.trace) }
    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.msg)
    }
}

impl MyError {
    #[track_caller]
    fn new(msg: &'static str) -> Self {
        Self { msg, trace: AtTrace::capture() }
    }
}

let err = MyError::new("something failed").at_str("while loading");
println!("{}", err.last_error_trace());
// Output:
// something failed
//     at src/main.rs:10:15
// (note: "while loading" context is omitted)
Source

fn last_error(&self) -> impl Display + '_

Format just the error message (no trace).

Returns a formatter that only displays the error message via fmt_message. Use this when you want to show the error without any trace information.

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.

Implementors§