1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! ## Intro //! //! Key feature of the `error-rules` crate is chained error handling without pain. //! For example your application have nested modules: app -> garage -> car -> engine. //! But how to know where this error happens? //! Should be saved error context for each module. //! To do that could be use `.map_err()` before each `?` operator. But this way is too verbose. //! The `error-rules` macro will do that automaticaly. //! Idea is simple, each module has own error handler with configurable display text. //! It pass source error wrapped into own error handler with custom display text. //! So app will get error with text like: "Garage => Car => Engine => resource temporarily unavailable" //! //! ## Declaring error types //! //! Macro `error_rules!` implements `Error`, `Result` types and all necessary traits for `Error`. //! All arguments should be comma-separated. //! //! To prevent types shadowing all errors from standard library and other crates should be used //! with module name. For example: `io::Error`. //! //! ## Display format //! //! Error display text defines in tuple after `self =>` keyword. //! First tuple argument is a format string. Additional arguments: //! //! - `error` - chained error text //! - `context` - context for this error //! //! ``` //! use error_rules::*; //! //! error_rules! { //! self => ("app error => {}", error) //! } //! //! assert_eq!( //! Error::from("error message").to_string().as_str(), //! "app error => error message"); //! ``` //! //! ## Error types //! //! After display text you could define error types for conversions into `Error` chain. //! By the default implements conversion for: `&str`, `String` //! //! ``` //! use std::io; //! use error_rules::*; //! //! error_rules! { //! self => ("app error => {}", error), //! std::io::Error, //! } //! //! let io_error = io::Error::new(io::ErrorKind::Other, "io-error"); //! assert_eq!( //! Error::from(io_error).to_string().as_str(), //! "app error => io-error"); //! ``` //! //! ## Custom error types //! //! Custom errors is an additional error kind to use with `Error`. //! Defines like `struct` with display arguments after `=>` keyword. //! Could be defined without fields: //! //! ``` //! # use error_rules::*; //! error_rules! { //! self => ("app error => {}", error), //! CustomError => ("custom error"), //! } //! //! assert_eq!( //! Error::from(CustomError).to_string().as_str(), //! "app error => custom error"); //! ``` //! //! or with fields: //! //! ``` //! # use error_rules::*; //! error_rules! { //! self => ("app error => {}", error), //! CustomError(usize) => ("custom error value:{}", 0), //! } //! //! assert_eq!( //! Error::from(CustomError(100)).to_string().as_str(), //! "app error => custom error value:100"); //! ``` //! //! or with named fields: //! //! ``` //! # use error_rules::*; //! error_rules! { //! self => ("app error => {}", error), //! CustomError { //! value: usize, //! } => ("custom error value:{}", value), //! } //! //! assert_eq!( //! Error::from(CustomError { value: 100 }).to_string().as_str(), //! "app error => custom error value:100"); //! ``` //! //! ## Error context //! //! Error context let to append additional information into error description. //! For example will be useful to get know which file unavailable on `File::open()`. //! //! ``` //! # use error_rules::*; //! error_rules! { //! self => ("file reader ({}) => {}", context, error), //! std::io::Error, //! } //! //! let n = "not-found.txt"; //! let e = std::fs::File::open(n).context(n).unwrap_err(); //! assert_eq!( //! e.to_string().as_str(), //! "file reader (not-found.txt) => No such file or directory (os error 2)"); //! ``` #[macro_use] mod error_rules;