use hb_error::*;
struct ExampleError {
msg: String,
inner_errors: Vec<String>,
}
impl ExampleError {
pub fn new() -> ExampleError {
ExampleError {
msg: String::new(),
inner_errors: vec![],
}
}
}
impl hb_error::ErrorContext for ExampleError {
fn make_inner(mut self) -> Self {
self.inner_errors.push(self.msg);
self.msg = String::new();
self
}
fn msg<T: Into<String>>(mut self, msg: T) -> Self {
self.msg = msg.into();
self
}
}
impl std::fmt::Display for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f, "{}\n{}", self.msg, self.inner_errors.join("\n"))
}
}
impl std::fmt::Debug for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f, "{}\n{}", self.msg, self.inner_errors.join("\n"))
}
}
impl From<std::io::Error> for ExampleError {
fn from(_: std::io::Error) -> ExampleError {
ExampleError {
msg: "encountered an IO Error".to_string(),
inner_errors: vec![],
}
}
}
fn io_error() -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::AlreadyExists,
"Example IO Error.",
))
}
fn example_error() -> Result<(), ExampleError> {
Err(ExampleError::new().msg("Generated ExampleError."))
}
#[context("addition context - basic example")]
fn basic_exampleerror() -> Result<(), ExampleError> {
example_error()
}
#[context("addition context - basic example")]
fn basic2_exampleerror() -> Result<(), ExampleError> {
example_error()?;
Ok(())
}
#[context("addition context - basic example")]
fn basic3_exampleerror() -> Result<(), ExampleError> {
return example_error();
}
#[convert_error]
fn basic4_exampleerror() -> Result<(), ExampleError> {
return io_error();
}
#[context("addition context - basic example")]
fn basic5_exampleerror() -> Result<(), ExampleError> {
return io_error();
}
#[context("add parameters '{p}' - basic example")]
fn basic6_exampleerror(p: &str) -> Result<(), ExampleError> {
return io_error();
}
#[context_doc]
fn basic7_exampleerror(p: &str) -> Result<(), ExampleError> {
return io_error();
}
#[hberror("{self.val}{self.msg}{self.inner_msgs.join(\"\n...due to...\")}")]
struct AnotherExampleError {
#[Default(10)]
val: i32,
#[Source]
IOError: std::io::Error,
}
#[context("hberror generated example from io error")]
fn more_exampleerror() -> Result<(), AnotherExampleError> {
return io_error();
}
#[context("adding a second layer of context")]
fn more_exampleerror2() -> Result<(), AnotherExampleError> {
return more_exampleerror();
}
#[context("with some generic parameter")]
fn more_exampleerror3<T: From<std::io::Error> + hb_error::ErrorContext>() -> Result<(), T> {
return io_error();
}
fn main() {
println!(
"Basic Example 1: Adding context to a fall through error\n{}\n",
basic_exampleerror().err().unwrap()
);
println!(
"Basic Example 2: Adding context to a try expression (? operator)\n{}\n",
basic2_exampleerror().err().unwrap()
);
println!(
"Basic Example 3: Adding context to a returned error\n{}\n",
basic3_exampleerror().err().unwrap()
);
println!(
"Basic Example 4: Converting an io::Error into a ExampleError\n{}\n",
basic4_exampleerror().err().unwrap()
);
println!(
"Basic Example 5: Adding converting and adding context with an io:Error\n{}\n",
basic5_exampleerror().err().unwrap()
);
println!(
"Basic Example 6: adding a specific context message with a parameter\n{}\n",
basic6_exampleerror("val").err().unwrap()
);
println!(
"Basic Example 7: adding a specific context message from a doc comment\n{}\n",
basic7_exampleerror("val").err().unwrap()
);
println!(
"Another Example 1: Trying out the macro to fill in the contents of an error type\n{}\n",
more_exampleerror().err().unwrap()
);
println!(
"Another Example 2: Adding a layer of context on top\n{}\n",
more_exampleerror2().err().unwrap()
);
println!(
"Another Example 3: working with generics\n{}\n",
more_exampleerror3::<AnotherExampleError>().err().unwrap()
);
}