logerr 0.1.0

Seamless error type logging
Documentation
# logerr

Seamless error type logging.


## What does it do?

`logerr` aims to make logging errors as part of a `std::result::Result` easy
and obstruction-free. It provides a trait, `LoggableError`, that is implemented
on a rich variety of common `Result` variants. All the traits functions share
the special property that they **pass through the `Result` type unmodified**.

This way, regular error handling is not obstructed in any way, and logging can
happen while you're "on the go" handling errors.


## How to use it

Once you have a `Result` with a supported error type, you just do:

```rust
use anyhow::{anyhow, Context};
use logerr::LoggableError;  // Must include to get access to trait functions

fn main() {
    Err(anyhow!("an error occured"))
        .context("this is just a demo")
        .to_stderr()                     // <-- Magic!
        .unwrap()
}
```

There are various feature flags that control the behavior of logging. By
default, `LoggableError` uses a generic implementation over all error types
implementing `Debug` and uses a debug print statement (`{:#?}`) to perform the
logging.

If you want to make use of more advanced features, or add special
implementations for your own error types (including custom logging), refer to
the feature flags below.


## Feature flags

### Feature compatibility matrix

Below you see a matrix representation of the features that can safely be
combined with each other. An `X` means that the features can be combined.

|             | log | anyhow | generic | std\_errors |
| ----------: | :-: | :----: | :-----: | :---------: |
| log         |     | X      | X       | X           |
| anyhow      | X   |        |         | X           |
| generic     | X   |        |         |             |
| std\_errors | X   | X      |         |             |


### Choosing which features to use

> **I only want to log errors!**

In this case the default features (`log`, `generic`) are very likely sufficient
for you

> **I want to bring my own error formatting, completely!**

This is currently only possible for error types that you or your code owns (Due
to the orphan rule). In this case, forego all default features and implement
the `LoggableError` trait yourself. You can have a look at the source code if
you need inspiration.

> **I want any formatting for `std` errors and add my own errors, too!**

Use the `std_errors` feature flag and implement the `LoggableError` trait for
all other error types you need.

> **I'm using anyhow for all my error handling!**

Use the `anyhow` feature flag, and you're good to go.


### `log`

Pulls in [the log crate][310] and adds a default implementation for `to_log`
that prints the error to `log::error!`.


### `anyhow`

Pulls in [the anyhow crate][320] and adds an implementation specifically for
`anyhow::Result` (i.e. `Result<_, anyhow::Error`) that prints the whole error
chain like this:

```
ERROR: an error occured
because: something bad happened
because: file doesn't exist
```

The root error is the last one printed.

- Your application must use the `anyhow::Result` type for this to work
- **This is mutually exclusive with the following features:**
    - `generic`


### `generic`

Adds a generic implementation of the `LoggableError` trait for all error types
that implement the `Debug` trait.

- **This is mutually exclusive with the following features:**
    - `anyhow`
    - `std_errors`


### `std_errors`

Adds implementations of the `LoggableError` trait to all error types from the
`std` library.


[310]: https://crates.io/crates/log
[320]: https://crates.io/crates/anyhow