Skip to main content

AnErr

Struct AnErr 

Source
pub struct AnErr<K, const DEPTH: usize = 3, const REASON_LEN: usize = 29>
where K: Copy + Clone + Debug + PartialEq + Eq,
{ pub reasons: [Option<AsciiStr<REASON_LEN>>; DEPTH], pub locations: [Option<&'static Location<'static>>; DEPTH], pub kinds: [Option<K>; DEPTH], pub len: u8, }
Expand description

A compact, Copy, zero-allocation error type that records a parallel stack of error kinds, source locations, and per-level human-readable reasons.

AnErr stores up to DEPTH levels of error context. Each level contains:

  • an error kind of type K,
  • the source location where the level was created,
  • an optional reason specific to that level (AsciiStr<REASON_LEN>).

The kind enum provides the general error category while the per-level reason carries concrete details (e.g. a bad value, file path, token, etc.).

The type implements Copy and performs no heap allocation. Default memory footprint is small and fully controllable via the generic parameters.

§Type Parameters

  • K: Error kind type. Must implement Copy + Clone + Debug + PartialEq + Eq.
  • DEPTH: Maximum number of context levels (default 3). Additional context beyond this limit is silently discarded.
  • REASON_LEN: Maximum length of each individual reason in bytes (default 29). Longer reasons are silently truncated.

§Construction

use an_error::{AnErr, an_err};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MyKind {
    Parse,
    Io,
    Validation,
}

pub type MyError = AnErr<MyKind, 4, 64>;

fn parse() -> Result<(), MyError> {
    Err(an_err!(MyKind::Parse, "unexpected token at byte {}", 42))
}

fn load(path: &str) -> Result<(), MyError> {
    let inner = parse()
        .map_err(|e| an_err!(MyKind::Io, "while loading config from {}", path => e))?;
    Ok(())
}

All constructors and the context method capture the call site via #[track_caller].

§Display

The Display implementation produces output of the following form:

--
• Trace (2 levels):
   1. Io    @ src/io.rs:42:10    while loading config from /etc/foo
   2. Parse @ src/parser.rs:17:5  unexpected token at byte 42

Each trace level shows its own reason (if present) immediately after the location.

§Invariants

Maintained by all constructors and context:

  • len is always in 1..=DEPTH.
  • For every i in 0..len, kinds[i] and locations[i] are Some.
  • reasons[i] is Some only if a non-empty reason was supplied for that level.

Fields§

§reasons: [Option<AsciiStr<REASON_LEN>>; DEPTH]

Per-level reasons. Only the first len entries are valid. None means no reason (or an empty reason) was provided for that level.

§locations: [Option<&'static Location<'static>>; DEPTH]

Parallel stack of source locations. Only the first len entries are valid.

§kinds: [Option<K>; DEPTH]

Parallel stack of error kinds (one per call-stack level). Only the first len entries are valid.

§len: u8

Current depth of the error trace (1 = original error).

Implementations§

Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq,

Source

pub fn new(kind: K) -> Self

Creates a new error with the given kind and no reason.

Source

pub fn with_reason(kind: K, reason: AsciiStr<REASON_LEN>) -> Self

Creates a new error with the given kind and reason.

If the reason is empty, it is stored as None.

Source

pub fn with_fmt(kind: K, args: Arguments<'_>) -> Self

Creates a new error with the given kind and a formatted reason.

The formatted string is truncated if it exceeds REASON_LEN bytes.

Source

pub fn depth(&self) -> u8

Returns the current depth of the error trace.

Source

pub fn kind(&self) -> Option<K>

Returns the most recent error kind (the top of the trace).

Source

pub fn context(&mut self, kind: K, new_reason: AsciiStr<REASON_LEN>)

Appends a new context level and optional reason to this error.

If new_reason is empty, no reason is stored for the new level. If the maximum depth is already reached, the call is a no-op.

Source

pub fn context_fmt(&mut self, kind: K, args: Arguments<'_>)

Appends a new context level with a formatted reason.

Used internally by the an_err! macro. The formatted string is truncated if it exceeds REASON_LEN bytes.

Source

pub fn trace(&self) -> TraceIter<'_, K, DEPTH, REASON_LEN>

Returns an iterator over the error trace, from most recent context down to the original error.

Each item is (kind, location, reason). The iterator borrows self with zero copying.

Trait Implementations§

Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Clone for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq + Clone,

Source§

fn clone(&self) -> AnErr<K, DEPTH, REASON_LEN>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Debug for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq,

Source§

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

Debug prints the same clean, human-readable trace as Display. This makes unwrap(), dbg!(), and panic messages readable instead of dumping giant byte arrays.

Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Display for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq,

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Error for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq,

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> From<K> for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq,

Source§

fn from(kind: K) -> Self

Converts a kind into a new AnErr with no reason.

Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> PartialEq for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq + PartialEq,

Source§

fn eq(&self, other: &AnErr<K, DEPTH, REASON_LEN>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Copy for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq + Copy,

Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Eq for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq + Eq,

Source§

impl<K, const DEPTH: usize, const REASON_LEN: usize> StructuralPartialEq for AnErr<K, DEPTH, REASON_LEN>
where K: Copy + Clone + Debug + PartialEq + Eq,

Auto Trait Implementations§

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Freeze for AnErr<K, DEPTH, REASON_LEN>
where K: Freeze,

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> RefUnwindSafe for AnErr<K, DEPTH, REASON_LEN>
where K: RefUnwindSafe,

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Send for AnErr<K, DEPTH, REASON_LEN>
where K: Send,

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Sync for AnErr<K, DEPTH, REASON_LEN>
where K: Sync,

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> Unpin for AnErr<K, DEPTH, REASON_LEN>
where K: Unpin,

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> UnsafeUnpin for AnErr<K, DEPTH, REASON_LEN>
where K: UnsafeUnpin,

§

impl<K, const DEPTH: usize, const REASON_LEN: usize> UnwindSafe for AnErr<K, DEPTH, REASON_LEN>
where K: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<!> for T

Source§

fn from(t: !) -> T

Converts to this type from the input type.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.