Giter Club home page Giter Club logo

thistermination's Introduction

thistermination

thistermination is a library crate inspired by thiserror to add the std::process::Termination trait to error enums.

[dependencies]
thistermination = "1.0"

Compiler support: requires rustc 1.56+

Why Implement The Termination Trait?

A struct or enum that implements the std::process::Termination and std::fmt::Debug traits can be returned by the main function, allowing developers to print a message on program exit and set the exit code.

Usage

To add the std::process::Termination trait to an enum, you can use one of three possible derive macros:

  • #[derive(Termination)]: is intended to be used in combination with thiserror, this macro implements the traits std::process::Termination and std::fmt::Debug. The exit_code defaults to libc::EXIT_FAILURE, and the Debug message is the same as the Display message unless explicitly set using exit_code and msg.

    use thistermination::{Termination};
    use thiserror::Error;
    
    #[derive(Error, Termination)]
    pub enum RequestError {
        #[error("request failed {0:?}")]
        RequestFailed(#[from] reqwest::Error),
        #[termination(msg("exiting wrong api key"))]
        #[error("wrong api key")]
        WrongAPIKey,
        #[termination(exit_code(3))]
        #[error("failed with status {0}")]
        RequestStatusError(u16),
        #[termination(exit_code(4), msg("exiting failed to load image {error:?}"))]
        #[error("failed to load image {error:?}")]
        ImageLoadError{#[from] error: image::ImageError},
    }
    
    fn main() -> Result<(), RequestError> {
        Err(RequestError::WrongAPIKey)
    }
  • #[derive(TerminationFull)]: is intended to be used without thiserror, this macro implements the traits std::process::Termination, std::fmt::Debug, std::fmt::Display, and std::error::Error. The exit_code defaults to libc::EXIT_FAILURE, and msg is required and used for both Display and Debug.

    use thistermination::{TerminationFull};
    
    #[derive(TerminationFull)]
    pub enum RequestError {
        #[termination(exit_code(1), msg("request failed {0:?}"))]
        RequestFailed(#[from] reqwest::Error),
        #[termination(exit_code(2), msg("wrong api key"))]
        WrongAPIKey,
        #[termination(exit_code(3), msg("failed with status {0}"))]
        RequestStatusError(u16),
        #[termination(exit_code(4), msg("failed to load image {error:?}"))]
        ImageLoadError{#[from] error: image::ImageError},
    }
    
    fn main() -> Result<(), RequestError> {
        Err(RequestError::WrongAPIKey)
    }
  • #[derive(TerminationNoDebug)]: is the most basic variant, implementing only the std::process::Termination trait. If no exit_code is provided, it defaults to libc::EXIT_FAILURE. However, the std::fmt::Debug trait is necessary for the enum to be returned by the main function and must be implemented manually or using the Debug macro.

    use thistermination::{TerminationNoDebug};
    
    #[derive(TerminationNoDebug, Debug)]
    pub enum RequestError {
        #[termination(exit_code(1))]
        RequestFailed(reqwest::Error),
        WrongAPIKey,
        #[termination(exit_code(3))]
        RequestStatusError(u16),
        ImageLoadError{error: image::ImageError},
    }
    
    fn main() -> Result<(), RequestError> {
        Err(RequestError::WrongAPIKey)
    }

Details

  • thistermination does not appear in your public API; the macros simply implement the the various traits.

  • The macros can be derived for unit enums, enums with named fields, and enum tuples.

  • msg supports accessing the fields of the enum in a format string manner

    • #[termination(msg("{var}"))] ⟶ write!("{}", self.var)
    • #[termination(msg("{0}"))] ⟶ write!("{}", self.0)
    • #[termination(msg("{var:?}"))] ⟶ write!("{:?}", self.var)
    • #[termination(msg("{0:?}"))] ⟶ write!("{:?}", self.0)

    You can also specify additional format string arguments for msg

    #[derive(TerminationFull)]
    pub enum RequestError {
        #[termination(exit_code(4), msg("failed to load image {0:?}"))]
        ImageLoadError(#[from] image::ImageError),
    }
  • Using #[from] will generate a std::convert::From implementation for the specific variant. A variant with #[from] is not allowed to contain any additional fields and can only be used in combination with #[derive(TerminationFull)].

    #[derive(TerminationFull)]
    pub enum CLIError {
        #[termination(exit_code(4), msg("Invalid argument {0}, expected < {}", i16::MAX))]
        InvalidArgument(u16),
    }
  • You can also change the default values of exit_code and msg by adding the #[termination(...)] helper attribute to the enum itself.

    #[derive(Error, Termination)]
    #[termination(exit_code(3), msg("Fatal Error"))]
    pub enum RequestError {
        #[error("request failed {0:?}")]
        RequestFailed(#[from] reqwest::Error),
        #[error("wrong api key")]
        WrongAPIKey,
        #[error("failed with status {0}")]
        RequestStatusError(u16),
        #[termination(exit_code(4), msg("exiting failed to load image {error:?}"))]
        #[error("failed to load image {error:?}")]
        ImageLoadError{#[from] error: image::ImageError},
    }

Comparison To thiserror

#[derive(TerminationFull)] can be used instead of thiserror as it offers many of the basic features of thiserror. However, it lacks some features like #[source], #[backtrace], the ability to automatically detect a backtrace, and #[error(transparent)]. If any of these features are required, you can use thiserror in combination with #[derive(Termination)].

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.