Skip to main content

Crate exit_safely

Crate exit_safely 

Source
Expand description

exit_safely provides a simple and highly transparent option to derive(Termination) from your own enum with a very simple API which still provides you full control over exit codes and what to (safely) output to stderr.

Minimal magic, maximum flexibilty, zero boilerplate.

§Why?

std::process::exit warns: “Note that because this function never returns, and that it terminates the process, no destructors on the current stack or any other thread’s stack will be run. If a clean shutdown is needed it is recommended to … simply return a type implementing Termination … from the main function and avoid this function altogether”

§Example usage:

use exit_safely::Termination;
use std::process::Termination as _Termination;

#[derive(Termination)]
#[repr(u8)]
enum Exit<T: _Termination> {
    Ok(T) = 0,
    Error(String) = 1,
    InvocationError(String) = 2,
}

For use in main() you will probably also want to derive Debug and Try (via try_v2):

#![feature(never_type)]
#![feature(try_trait_v2)]
#![feature(try_trait_v2_residual)]
use exit_safely::Termination;
use try_v2::*;

#[derive(Debug, Termination, Try, Try_ConvertResult)]
#[must_use]
#[repr(u8)]
enum Exit<T: std::process::Termination> {
    Ok(T) = 0,
    Error(String) = 1,
    InvocationError(String) = 2,
}

fn main() -> Exit<()> {
    // Use either `?` or return `Exit::...` to exit early from your code ...
    Exit::Ok(())
}

See the integration tests or readme for a full example

🔬 Stability

This crate makes use of the following experimental features:

Since Termination works best for types which also implement the experimental Try, we hope this is acceptable to you.

The authors consider all of the above features to be reliable and already well advanced in the stabilisation process. Nevertheless, we run automated tests every month to ensure no fundamental changes affect this crate.

Derive Macros§

Termination
Derives Termination.