precisej-printable-errno 0.2.2

Printable system call errors for nix
Documentation
# precisej-printable-errno

Printable system call errors for `nix`. **CURRENTLY IN DEVELOPMENT**

## What?
`precisej-printable-errno` is a simple library that adds the
possibility of attaching a printable error message to every [Errno].
It additionally lets you add an integer error code that can be used
to exit the application.

The library is intended to be used by lower-level applications that
intend to use `nix`'s Rust-friendly bindings to libc system functions.

**Note**: `precisej-printable-errno`'s authors have no relationship
with the `nix-rust` maintainers.

## Where?
Any system that `nix` supports should be supported by
`precisej-printable-errno`. To use this library, add
`precisej-printable-errno = "$LIB_VERSION"` (replacing `$LIB_VERSION`
with the latest version available in [crates.io](https://crates.io/)).

Projects currently using `precisej-printable-errno`:
* initd

If you are the author of another Rust project, are using the library,
and would like to be mentioned here, please contact me.

## Why?
When writing initd, I found that there wasn't a straightforward way
to bubble up an exit code, and resorted to having a main() function
call a function which would return an `i32`, and then call
[std::process::exit] with the resulting error code. This was
unergonomic and bypassed Rust's excellent Result handling. Therefore
I decided to create special Error structs containing an error message
and an exit code, and since I found it useful I decided to turn it
into a library crate.

I didn't find out how to do anything similar with other libraries
such as `anyhow`. If someone finds a better, equally lightweight
alternative please contact me.

### Why not Termination?
As of 2021-12-10, [std::process::Termination] is unstable and requires
the `termination_trait_lib` feature, which can only be activated in
nightly versions of Rust. Not all programs can make use of nightly (some,
such as `initd`, deny the use of unstable features in its codebase),
for which this crate exists.

Not all of this library's functionality can be replicated with
[std::process::Termination], so this library can be of use even for users
of nightly Rust, albeit somewhat awkwardly. Future versions of
`precisej-printable-errno` will optionally include an implementation of
[std::process::Termination] for [ExitError] as a non-default feature for
interested nightly users.

## How?
```rust
/* use ... */

const PROGRAM_NAME: &'static str = "example-program";

pub fn main() {
    if let Err(e) = start() {
        e.eprint_and_exit()
    }
}

pub fn start() -> Result<(), ExitError<&'static str>> {
    let init_file = open("/sbin/init", OFlag::O_RDONLY, Mode::empty())
        .printable(PROGRAM_NAME, "unable to open /sbin/init")
        .bail(1)?;

    let mut buf = [0; 1024];
    read(init_file, &mut buf)
        .printable(PROGRAM_NAME, "unable to read first KB of /sbin/init")
        .bail(2)?;

    drop(buf);

    open("/path/to/nonexistent/file", OFlag::O_RDONLY, Mode::empty())
        .printable(PROGRAM_NAME, "unable to open /path/to/nonexistent/file")
        .bail(3)?;

    // That last call should have caused the process to exit with
    // code 3 and the following error message:
    //
    // example-program: unable to open /path/to/nonexistent/file: No such file or directory

    Ok(())
}
```

License: MIT