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.

Source

pub fn to_wire_bytes<const PATH_LEN: usize>( &self, kind_to_u16: impl Fn(K) -> u16, buf: &mut [u8], ) -> Result<usize, ()>

Serialize this error into a fixed-size byte buffer for transmission.

The caller must provide a buffer that is at least Self::WIRE_SIZE::<PATH_LEN>() bytes long. Returns the number of bytes actually written (always the same for a given PATH_LEN).

Recommended usage:

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]   // or #[repr(u16)] for >256 variants
pub enum MyKind { ... }

let mut buf = [0u8; AnErr::<MyKind, 3, 29>::wire_size::<80>()];
let written = my_error.to_wire_bytes::<80>(|k| k as u16, &mut buf);
let packet = &buf[..written];
Source

pub const fn wire_size<const PATH_LEN: usize>() -> usize

Compile-time size of the wire representation for a given PATH_LEN.

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> AsErrorSource for T
where T: Error + 'static,

Source§

fn as_error_source(&self) -> &(dyn Error + 'static)

For maximum effectiveness, this needs to be called as a method to benefit from Rust’s automatic dereferencing of method receivers.
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<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
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.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more