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- TheOktype of theResult.
§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§
Sourcefn context(self, msg: impl Into<String>) -> Result<T>
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.
Sourcefn with_suggestion(self, s: impl Into<String>) -> Result<T>
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.
Sourcefn with_shell(self, p: impl Any + Send + Sync + 'static) -> Result<T>
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 beAny + 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.
Sourcefn with_priority(self, priority: u8) -> Result<T>
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.
Sourcefn ctx(self, msg: impl Into<String>) -> Result<T>
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.
Sourcefn help(self, s: impl Into<String>) -> Result<T>
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.
Sourcefn meta(self, k: impl Into<String>, v: impl Into<String>) -> Result<T>
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>
impl<T, E> HatchExt<T> for Result<T, E>
Source§fn with_priority(self, priority: u8) -> Result<T>
fn with_priority(self, priority: u8) -> Result<T>
Sets the priority for the error’s primary context.