# proxit — Unix-style error messages in Rust
`proxit` is a super simple Rust library that allows you to have consistent,
UNIX-style error messages with a little bit less boilerplate by implementing the
`Termination` trait for you.
## Why?
All UNIX commandline utilities have displayed their errors in more-or-less the
exact same way since the beginning of time:
<utility name>: <error message>
and sometimes:
Usage: <utility name> <utility arguments>
# or
usage: <utility name> <utility arguments>
For example:
$ grep -fakeflags
grep: akeflags: No such file or directory
$ mandoc
bash: mandoc: command not found
$ doas
usage: doas [-Lns] [-C config] [-u user] command [args]
So how did the genius Rust team decide to do it? Let’s check the code:
```rust
impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
fn report(self) -> ExitCode {
match self {
Ok(val) => val.report(),
Err(err) => {
io::attempt_print_to_stderr(format_args_nl!("Error: {err:?}"));
ExitCode::FAILURE
}
}
}
}
```
Wait… did I see that right?
```rust
… format_args_nl!("Error: {err:?}"));
```
Bruh.
## How Proxit Works
Using `proxit` is super simple:
```rust
use proxit::MainResult;
fn main() -> MainResult {
work().into();
}
fn work() -> Result<(), Error> { /* … */ }
```
A `MainResult` is just a wrapper around a `Result<T, E>` where `T` implements
`Termination`, and `E` implements `Display`. In practice, `T` will basically
always be `()` which does implement `Termination`.
When the `main` function returns, if the `Result` within the `MainResult` is an
`Ok` variant, then the `.report()` method of `T` is invoked. Otherwise, `E` is
printed out to standard error (this is why you need to implement `Display`)
prefixed by the string `"{argv0}: "` where `argv0` is the program name.
What if you want to print a usage string though? Well… because simpler and
simpler is **always** better, just call `eprintln!()` and `process::exit()`.
Printing the usage string yourself also gives you the flexibility to decide
between GNU- and FreeBSD-style usage strings (`"Usage: {s}"`) and OpenBSD-style
usage strings (`"usage: {s}"`).
```rust
use std::process;
use proxit::{self, MainResult, Usage};
fn main() -> MainResult {
work.into();
}
fn work() -> Result<(), Error> {
if usage_wrong() {
eprintln!("Usage: [-abc] required_arg");
process::exit(1);
}
}
```
## Additional Note
When a process using this library is spawned, the parent process calling `exec()`
could potentially not provide the program name in `argv[0]`. In this case, we
default to using the Rust style of `"Error: {s}"`.