quick-error 1.2.3

A macro which makes error types pleasant to write.
Documentation
A macro which makes errors easy to write Minimum type is like this: ```rust #[macro_use] extern crate quick_error; # fn main() {} quick_error! { #[derive(Debug)] pub enum SomeError { Variant1 {} } } ``` Both ``pub`` and non-public types may be declared, and all meta attributes (such as ``#[derive(Debug)]``) are forwarded as is. The `Debug` must be implemented (but you may do that yourself if you like). The documentation comments ``/// something`` (as well as other meta attrbiutes) on variants are allowed. # Allowed Syntax You may add arbitrary parameters to any struct variant: ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { /// IO Error Io(err: std::io::Error) {} /// Utf8 Error Utf8(err: std::str::Utf8Error) {} } } ``` Note unlike in normal Enum declarations you declare names of fields (which are omitted from type). How they can be used is outlined below. Now you might have noticed trailing braces `{}`. They are used to define implementations. By default: * `Error::cause()` returns None (even if type wraps some value) * `Display` outputs debug representation * No `From` implementations are defined ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { Io(err: std::io::Error) { display("{}", err) } Utf8(err: std::str::Utf8Error) { display("utf8 error") } } } ``` To change `cause` method to return some error, add `cause(value)`, for example: ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { Io(err: std::io::Error) { cause(err) } Utf8(err: std::str::Utf8Error) { display("utf8 error") } Other(err: Box) { cause(&**err) } } } ``` Note you don't need to wrap value in `Some`, its implicit. In case you want `None` returned just omit the `cause`. You can't return `None` conditionally. To change how each clause is `Display`ed add `display(pattern,..args)`, for example: ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { Io(err: std::io::Error) { display("I/O error: {}", err) } Utf8(err: std::str::Utf8Error) { display("Utf8 error, valid up to {}", err.valid_up_to()) } } } ``` If you need a reference to the error when `Display`ing, you can instead use `display(x) -> (pattern, ..args)`, where `x` sets the name of the reference. ```rust # #[macro_use] extern crate quick_error; # fn main() {} # use std::error::Error; // put methods like `source()` of this trait into scope quick_error! { #[derive(Debug)] pub enum SomeError { Io(err: std::io::Error) { display(x) -> ("I/O: {}", err) } Utf8(err: std::str::Utf8Error) { display(self_) -> ("UTF-8 error. Valid up to {}", err.valid_up_to()) } } } ``` To convert to the type from any other, use one of the three forms of `from` clause. For example, to convert simple wrapper use bare `from()`: ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { Io(err: std::io::Error) { from() } } } ``` This implements ``From``. To convert to singleton enumeration type (discarding the value), use the `from(type)` form: ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { FormatError { from(std::fmt::Error) } } } ``` And the most powerful form is `from(var: type) -> (arguments...)`. It might be used to convert to type with multiple arguments or for arbitrary value conversions: ```rust # #[macro_use] extern crate quick_error; # fn main() {} # quick_error! { #[derive(Debug)] pub enum SomeError { FailedOperation(s: &'static str, errno: i32) { from(errno: i32) -> ("os error", errno) from(e: std::io::Error) -> ("io error", e.raw_os_error().unwrap()) } /// Converts from both kinds of utf8 errors Utf8(err: std::str::Utf8Error) { from() from(err: std::string::FromUtf8Error) -> (err.utf8_error()) } } } ``` # Context Since quick-error 1.1 we also have a `context` declaration, which is similar to (the longest form of) `from`, but allows adding some context to the error. We need a longer example to demonstrate this: ```rust # #[macro_use] extern crate quick_error; # use std::io; # use std::fs::File; # use std::path::{Path, PathBuf}; # use quick_error::ResultExt; quick_error! { #[derive(Debug)] pub enum Error { File(filename: PathBuf, err: io::Error) { context(path: &'a Path, err: io::Error) -> (path.to_path_buf(), err) } } } fn openfile(path: &Path) -> Result<(), Error> { try!(File::open(path).context(path)); // If we didn't have context, the line above would be written as; // // try!(File::open(path) // .map_err(|err| Error::File(path.to_path_buf(), err))); Ok(()) } # fn main() { # openfile(Path::new("/etc/somefile")).ok(); # } ``` Each `context(a: A, b: B)` clause implements `From> for Error`. Which means multiple `context` clauses are a subject to the normal coherence rules. Unfortunately, we can't provide full support of generics for the context, but you may either use a lifetime `'a` for references or `AsRef` (the latter means `A: AsRef`, and `Type` must be concrete). It's also occasionally useful to use a tuple as a type of the first argument. You also need to `use quick_error::ResultExt` extension trait to get working `.context()` method. More info on context in [this article](http://bit.ly/1PsuxDt). All forms of `from`, `display`, `cause`, and `context` clauses can be combined and put in arbitrary order. Only `from` and `context` can be used multiple times in single variant of enumeration. Docstrings are also okay. Empty braces can be omitted as of quick_error 0.1.3. # Private Enums Since quick-error 1.2.0 we have a way to make a private enum that is wrapped by public structure: ```rust #[macro_use] extern crate quick_error; # fn main() {} quick_error! { #[derive(Debug)] pub enum PubError wraps ErrorEnum { Variant1 {} } } ``` This generates data structures like this ```rust pub struct PubError(ErrorEnum); enum ErrorEnum { Variant1, } ``` Which in turn allows you to export just `PubError` in your crate and keep actual enumeration private to the crate. This is useful to keep backwards compatibility for error types. Currently there is no shorcuts to define error constructors for the inner type, but we consider adding some in future versions. It's possible to declare internal enum as public too.