Crate luhtwin

Crate luhtwin 

Source
Expand description

githubcrates-iodocs-rs

§luhtwin - Horrible Error Handling for Rust

luhtwin provides a ergonomic error handling system that emphasizes context accumulation, structured diagnostics, and flexible formatting. Built around the AnyError type, it allows you to wrap any error with rich metadata and progressively add context as errors bubble up through your application.

§Core Ideas

  • AnyError — The main error container that wraps any Error type with context chains
  • LuhTwin<T> — Type alias for Result<T, AnyError>, the primary result type
  • ErrorContext — Structured metadata including messages, file/line info, docs, and severity
  • Wrap — Wrapping existing Results into LuhTwin.
  • Twin — Transforming existing Results into LuhTwin.
  • Encase — Encase existing LuhTwins in another layer of context.

§Getting Started

Add luhtwin to your Cargo.toml:

[dependencies]
luhtwin = "0.1.4"

§Quick Example

use luhtwin::{LuhTwin, Twin, Wrap, Encase, at};
use std::fs;
use std::io;

fn read_config_file(path: &str) -> LuhTwin<String> {
    fs::read_to_string(path)
        .wrap(|| format!("failed to read config from {}", path))
}

fn parse_config(content: String) -> LuhTwin<Config> {
    serde_json::from_str(&content)
        .twin()
        .encase(|| "failed to parse config as JSON")
}

fn load_config() -> LuhTwin<Config> {
    let content = read_config_file("config.json")?;
    parse_config(content)
        .encase(|| "config loading failed")
}

fn main() -> LuhTwin<()> {
    let config = load_config()?;
    println!("Config loaded successfully!");
    Ok(())
}

§Error Output

When an error occurs, luhtwin provides detailed, layered context:

LUHTWIN_FULL=1 to see full errors <3
  1: failed to read config from config.json: No such file or directory
  2: failed to parse config as JSON
  3: config loading failed
source: No such file or directory (os error 2)
backtrace:
disabled backtrace

With LUHTWIN_FULL=1, you get the full context including file/line info:

  1: failed to read config from config.json: No such file or directory
      - file: "src/main.rs"
      - line: 8

  2: failed to parse config as JSON
      - file: "src/main.rs"
      - line: 14

  3: config loading failed
      - file: "src/main.rs"
      - line: 19

§Common Patterns

§Converting foreign errors with .twin()

use std::fs::File;

fn open_file() -> LuhTwin<File> {
    File::open("data.txt").twin()
}

§Wrapping errors with context using .wrap()

fn read_user_data(id: u32) -> LuhTwin<UserData> {
    read_from_db(id).wrap(|| format!("failed to load user {}", id))
}

§Adding layers with .encase()

fn initialize() -> LuhTwin<()> {
    load_config()
        .encase(|| "initialization failed")?;
    connect_db()
        .encase(|| "initialization failed")?;
    Ok(())
}

§Using the at! macro for rich context

fn validate_input(input: &str) -> LuhTwin<()> {
    if input.is_empty() {
        return Err(at!("input validation failed")
            .attach("input", input)
            .attach("expected", "non-empty string")
            .into());
    }
    Ok(())
}

§Environment Variables

  • LUHTWIN_FULL=1 - Show full error details with all attached arguments
  • RUST_BACKTRACE=1 - Enable backtrace capture (standard Rust behavior)

Macros§

at
Creates an ErrorContext with automatic file and line information.
bail
Early return with an error, similar to anyhow::bail!.
ensure
Assert a condition and bail with an error if it’s false.

Structs§

AnyError
AnyError
Arg
Arg
ErrorContext
ErrorContext

Traits§

Context
Context
Encase
Encase
ErrorArg
ErrorArg
Twin
Twin
Wrap
Wrap

Type Aliases§

BigTwin
BigTwin
ErrorSource
Just a base trait ease of refactoring <3
LuhTwin
LuhTwin