Trait HatchExt

Source
pub trait HatchExt<T>
where Self: Sized,
{ // Required methods fn context(self, msg: impl Into<String>) -> Result<T>; fn with_suggestion(self, s: impl Into<String>) -> Result<T>; fn with_shell(self, p: impl Any + Send + Sync + 'static) -> Result<T>; fn with_priority(self, priority: u8) -> Result<T>; fn ctx(self, msg: impl Into<String>) -> Result<T>; fn help(self, s: impl Into<String>) -> Result<T>; fn meta(self, k: impl Into<String>, v: impl Into<String>) -> Result<T>; }
Expand description

Extension trait for Result to easily attach Yoshi context, suggestions, and metadata.

This trait provides convenience methods for Result types, allowing developers to seamlessly add YoContext, suggestions, and metadata to errors as they propagate through the application. This simplifies error handling chains and ensures rich diagnostic information is preserved.

§Type Parameters

  • T - The Ok type of the Result.

§Examples

use yoshi_std::{Yoshi, YoshiKind, HatchExt};

fn process_data(input: &str) -> Result<usize, Yoshi> {
    if input.is_empty() {
        return Err(Yoshi::new(YoshiKind::Validation {
            field: "input".into(),
            message: "Input cannot be empty".into(),
            expected: Some("non-empty string".into()),
            actual: Some("empty string".into()),
        }))
        .context("Failed to validate data")
        .with_suggestion("Provide non-empty input");
    }

    // Simulate an I/O operation that might fail
    let result: std::result::Result<usize, io::Error> = Err(io::Error::new(ErrorKind::Other, "disk full"));

    result
        .map_err(Yoshi::from) // Convert io::Error to Yoshi
        .context("Failed to write processed data to disk")
        .map_err(|e| e.with_metadata("file_size", "10MB").with_priority(200))
}

let result = process_data("");
assert!(result.is_err());
let error = result.unwrap_err();
println!("Error: {}", error);
assert!(error.to_string().contains("Input cannot be empty"));

let result2 = process_data("some_data");
if let Err(e) = result2 {
    println!("Error: {}", e);
    assert!(e.to_string().contains("Failed to write processed data to disk"));
    assert_eq!(e.primary_context().unwrap().metadata.get("file_size".into()).map(|s| s.as_ref()), Some("10MB"));
    assert_eq!(e.primary_context().unwrap().priority, 200);
}

Required Methods§

Source

fn context(self, msg: impl Into<String>) -> Result<T>

Adds a context message to the error.

If self is Ok, it is returned unchanged. If self is Err, its error is converted to a Yoshi error if it isn’t already, and a new YoContext with the provided message is added to it.

This method preserves the current source code location (file, line, column).

§Arguments
  • msg - The context message.
§Returns

A Result<T, Yoshi> with the added context on error.

§Examples
use yoshi_std::{Yoshi, HatchExt};

fn read_file(path: &str) -> Result<String, Yoshi> {
    std::fs::read_to_string(path)
        .map_err(Yoshi::from)
        .context(format!("Failed to read file: {}", path))
}

let result = read_file("non_existent_file.txt");
if let Err(e) = result {
    println!("Error: {}", e);
    assert!(e.to_string().contains("Failed to read file: non_existent_file.txt"));
}
§Errors

Returns a Yoshi error with added context if the result is an error.

Source

fn with_suggestion(self, s: impl Into<String>) -> Result<T>

Adds a suggestion to the error’s primary context.

If self is Ok, it is returned unchanged. If self is Err, its error is converted to a Yoshi error if it isn’t already, and a new suggestion is added to its primary YoContext.

§Arguments
  • s - The suggestion message.
§Returns

A Result<T, Yoshi> with the added suggestion on error.

§Examples
use yoshi_std::{Yoshi, HatchExt};

fn connect_db() -> Result<(), Yoshi> {
    // Simulate a connection error
    Err(io::Error::new(ErrorKind::ConnectionRefused, "db connection refused"))
        .map_err(Yoshi::from)
        .with_suggestion("Ensure the database server is running.")
}
let result = connect_db();
if let Err(e) = result {
    println!("Error: {}", e);
    assert!(e.suggestion().as_deref() == Some("Ensure the database server is running."));
}
§Errors

Returns a Yoshi error with added suggestion if the result is an error.

Source

fn with_shell(self, p: impl Any + Send + Sync + 'static) -> Result<T>

Attaches a typed shell to the error’s primary context.

If self is Ok, it is returned unchanged. If self is Err, its error is converted to a Yoshi error if it isn’t already, and a new typed shell is added to its primary YoContext.

§Arguments
  • p - The shell to attach. Must be Any + Send + Sync + 'static.
§Returns

A Result<T, Yoshi> with the added shell on error. /// # Examples

use yoshi_std::{Yoshi, YoshiKind, HatchExt};

#[derive(Debug, PartialEq)]
struct RequestInfo {
    request_id: String,
    user_agent: String,
}

fn process_request(id: &str, ua: &str) -> Result<(), Yoshi> {
    // Simulate an internal error
    Err(Yoshi::new(YoshiKind::Internal {
        message: "Processing failed".into(),
        source: None,
        component: None,
    }))
    .with_shell(RequestInfo { request_id: id.into(), user_agent: ua.into() })
}

let result = process_request("req123", "Mozilla/5.0");
if let Err(e) = result {
    println!("Error: {}", e);
    let info = e.shell::<RequestInfo>();
    assert!(info.is_some());
    assert_eq!(info.unwrap().request_id, "req123");
}
§Errors

Returns a Yoshi error with added shell if the result is an error.

Source

fn with_priority(self, priority: u8) -> Result<T>

Sets the priority for the error’s primary context.

If self is Ok, it is returned unchanged. If self is Err, its error is converted to a Yoshi error if it isn’t already, and the priority of its primary YoContext is updated.

§Arguments
  • priority - The priority level (0-255).
§Returns

A Result<T, Yoshi> with the updated priority on error.

§Examples
use yoshi_std::{Yoshi, YoshiKind, HatchExt};

fn perform_critical_op() -> Result<(), Yoshi> {
    // Simulate a critical error
    Err(Yoshi::new(YoshiKind::Internal {
        message: "Critical operation failed".into(),
        source: None,
        component: None,
    }))
    .with_priority(250) // Mark as very high priority
}
let result = perform_critical_op();
if let Err(e) = result {
    println!("Error: {}", e);
    assert_eq!(e.primary_context().unwrap().priority, 250);
}
§Errors

Returns a Yoshi error with updated priority if the result is an error.

Source

fn ctx(self, msg: impl Into<String>) -> Result<T>

Short alias for context.

§Errors

Returns a Yoshi error with added context if the result is an error.

Source

fn help(self, s: impl Into<String>) -> Result<T>

Short alias for with_suggestion.

§Errors

Returns a Yoshi error with added suggestion if the result is an error.

Source

fn meta(self, k: impl Into<String>, v: impl Into<String>) -> Result<T>

Adds metadata to the error’s primary context.

This is a convenience method that delegates to Yoshi::with_metadata.

§Arguments
  • k - The metadata key.
  • v - The metadata value.
§Returns

A Result<T, Yoshi> with the added metadata on error.

§Examples
use yoshi_std::{Yoshi, YoshiKind, HatchExt, Arc};

fn fetch_user_data() -> Result<String, Yoshi> {
    // Simulate an error during user data fetch
    Err(Yoshi::new(YoshiKind::NotFound {
        resource_type: "User".into(),
        identifier: "unknown_user".into(),
        search_locations: None,
    }))
    .meta("user_id", "12345")
    .meta("trace_id", "abcde-12345")
}

let result = fetch_user_data();
if let Err(e) = result {
    println!("Error: {}", e);
    let metadata = e.primary_context().unwrap().metadata.clone();
    assert_eq!(metadata.get(&Arc::from("user_id")).map(|s| s.as_ref()), Some("12345"));
}
§Errors

Returns a Yoshi error with added metadata if the result is an error.

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.

Implementations on Foreign Types§

Source§

impl<T, E> HatchExt<T> for Result<T, E>
where E: Into<Yoshi> + Send + Sync + 'static,

Source§

fn with_priority(self, priority: u8) -> Result<T>

Sets the priority for the error’s primary context.

Source§

fn context(self, msg: impl Into<String>) -> Result<T>

Source§

fn with_suggestion(self, s: impl Into<String>) -> Result<T>

Source§

fn with_shell(self, p: impl Any + Send + Sync + 'static) -> Result<T>

Source§

fn ctx(self, msg: impl Into<String>) -> Result<T>

Source§

fn help(self, s: impl Into<String>) -> Result<T>

Source§

fn meta(self, k: impl Into<String>, v: impl Into<String>) -> Result<T>

Implementors§