Rust CLI utility library. Error handling, status reporting, and exit codes.

Overview

narrate

This library provides CLI application error and status reporting utilities. The coloured output formatting aims to be similar to Cargo. Error type is a wrapper around Anyhow.

Crates.io msrv 1.61 tests docs license

Features

  • User facing status messages and error reporting
  • Wrap any error with additional context
  • Optional help messages for errors
  • Set of standard CLI errors with exit codes conforming to sysexits.h
  • Convenience Result type
  • Drop in replacement for Anyhow

How to use

  • Use narrate::Result<T> as a return type of any fallible function.

    Within the function, use ? to propagate any error that implements the std::error::Error trait. Same as anyhow::Result<T>.

    use narrate::Result;
    
    fn get_user() -> Result<User> {
        let json = std::fs::read_to_string("user.json")?;
        let user: User = serde_json::from_str(&json)?;
        Ok(user)
    }
  • Wrap an error with more context by importing the narrate::ErrorWrap trait. Similar to anyhow::Context, this can give your users more information as to why an error happened.

    use narrate::{CliError, ErrorWrap, Result};
    
    fn run() -> Result<()> {
        ...
        // wrap with contextual information
        data.acquire().wrap("unable to acquire data")?;
    
        // wrap with another error
        config.load().wrap(CliError::Config)?;
    
        // wrap with lazily evaulated string or error
        config.load().wrap_with(|| format!("cannot load {}", path))?;
    
        // wrap with help information
        create_dir()
          .wrap("project directory already exists")
          .add_help("Try using cargo init")?;
        ...
    }
    error: project directory already exists
    cause: Is a directory (os error 20)
    
    Try using cargo init
  • Use the narrate::ExitCode trait to get the sysexits.h conforming exit code from a narrate::Error. By default this is just 70 (software error) but it can be easily implemented for any type.

  • narrate::CliError collection of typical command line errors. Use them to add context to deeper application errors. Use their exit_code to conform to sysexits.h.

    use narrate::{CliError, ErrorWrap, ExitCode, Result};
    
    fn main() {
        let res = run();
    
        if let Err(ref err) = res {
            std::process::exit(err.exit_code());
        }
    }
    
    fn run() -> Result<()> {
        will_error().wrap(CliError::OsErr)?
        Ok(())
    }
  • Report errors to the command line with either report::err or report::err_full for the complete error chain.

    use narrate::{CliError, Error, report};
    
    fn main() {
        let res = run();
    
        if let Err(ref err) = res {
            report::err_full(&err);
            std::process::exit(err.exit_code());
        }
    }
    
    fn run() -> Result<()> {
        ...
        let config: Config = serde_json::from_str(&json)
            .wrap("bad config file `/app/config.toml`")
            .wrap(CliError::Config)
            .add_help("see https://docs.example.rs/config for more help")?;
        ...
    }

    report::err_full output

  • Report application status to the command line with report::status. Modeled on the output from Cargo.

    use colored::Color;
    use narrate::report;
    
    fn main() {
        report::status("Created", "new project `spacetime`", Color::Green);
    }

    report::status output

Contributing

Thank you very much for considering to contribute to this project!

We welcome any form of contribution:

  • New issues (feature requests, bug reports, questions, ideas, ...)
  • Pull requests (documentation improvements, code improvements, new features, ...)

Note: Before you take the time to open a pull request, please open an issue first.

See CONTRIBUTING.md for details.

License

narrate is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT for details.

You might also like...
A super simple but lightweight logging library that tries to capture the most important (status) information.

Hackerlog A super simple but lightweight logging library that tries to capture the most important (status) information. The following is supported: Lo

All famous C programming Codes in Rust

All top 100 codes from basic to advance which is taught in C programming language in rust Programming language.

Easy, Simple, Clean. Making status bars reliable and up-to-date.

Simple Status Easy, Simple, Clean. Making status bars reliable and up-to-date. Installation Compiling simple_status yourself doesn't require much. Ins

An eye that keeps track of your Roblox status and shares it with others
An eye that keeps track of your Roblox status and shares it with others

Roblox presence for Discord with only one native standalone executable that relies on zero external dependencies, and doesn't need to be installed.

Core lightning (CLN) plugin to watch channel health, gossip health and ping amboss for online status

vitality Core lightning (CLN) plugin to watch channel health, gossip health and ping amboss for online status Installation Building Usage Telegram Opt

Generate basic VCard QR codes from the command line.
Generate basic VCard QR codes from the command line.

vcard-qr Generate basic VCard QR codes from your terminal. Stick them on your things so people can contact you if they get lost! This little program i

Schemars is a high-performance Python serialization library, leveraging Rust and PyO3 for efficient handling of complex objects

Schemars Introduction Schemars is a Python package, written in Rust and leveraging PyO3, designed for efficient and flexible serialization of Python c

Rust crate that allows you to display status & progress information in a terminal

status-line This crate allows you to display status & progress information in a terminal This crate handles the problem of displaying a small amount o

Are we lang yet? A simple website providing information about the status of Rust's language development ecosystem.

Are We Lang Yet This project answers the question "Is the Rust ecosystem ready to use for language development yet?". arewelangyet.com What is this? C

Comments
  • Move anyhow integration behind a feature flag

    Move anyhow integration behind a feature flag

    BREAKING CHANGE

    Hide Error::downcast and Error::from_anyhow behind an "anyhow" feature flag. These are currently the only public APIs using anyhow types. Moreover only publicly re-export anyhow crate behind the feature flag.

    This allows the default API to keep the implementation separate from the user and the "anyhow" feature-set to allow conversion between the two types.

    enhancement 
    opened by sonro 2
  • Custom types implementing ExitCode are being ignored

    Custom types implementing ExitCode are being ignored

    Problem

    Current ExitCode behaviour does not produce custom exit codes. Unless the underlying error is an Error or CliError, any calls to ExitCode::exit_code() will just produce the default 70.

    Proposed Solution

    Replace the ExitCode trait with assigning exitcodes to an Error.

    bug 
    opened by sonro 0
  • Separate wrapping from adding help messages

    Separate wrapping from adding help messages

    BREAKING CHANGE

    Simplify ErrorWrap API to sometthing more akin to:

    possible_error()
        .wrap(|| "error message")
        .set_help("help message")?;
    
    enhancement 
    opened by sonro 0
  • Report status macros

    Report status macros

    Format report messages to standard colors.

    • success!: green
    • info!: blue
    • warning!: orange

    4 varients:

    varient | output | note ---|---|--- success!("hello") | "success: hello" | | info!("{}", msg) | "info: msg string" | | warning!("title", "hello") | "title: hello" | 'title' would be orange success!("title", "{}", msg") | "title: msg string" | 'title' would be green

    enhancement 
    opened by sonro 0
Releases(v0.4.0)
  • v0.4.0(Nov 24, 2022)

    Added

    • Features for conditional compilation of separate utilities. See #12.
    • All features enabled by default [report, error, cli-error, anyhow]. See #12.
    • cicheck shell script for quickly checking if repo will pass CI checks.
    • anyhow error reporting.

    Changed

    • [BREAKING] Seal ExitCode trait. It was only useful with CliError anyway. Now the API reflects this.
    • [BREAKING] Mark CliError as non_exhaustive to allow for more variants in the future.
    • Error Debug formatting is now similar to report::err_full. Now the library is more similar anyhow in the way Result can be used.

    Documentation

    • Fixed Minimum Support Rust Version formatting in Cargo.toml.
    • Add more examples.

    API docs

    • Add crate root.
    • Add report module.

    ErrorWrap rustdoc

    • Fixed wrong method names.
    • Added more lazy evaluation information.
    • Updated example to be more complete.
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Oct 19, 2022)

    Added

    • add_help and add_help_with methods for Error.
    • CliError common trait implementations.

    Changed

    • Deprecate set_help and set_help_owned methods for Error type.
    • [BREAKING] Display implementation simplified for Error.
    • [BREAKING] report::err module now only prints relevant help.
    • [BREAKING] Error::downcast method no longer returns an anyhow::Result.

    Testing

    Add Integration Tests

    • Report module.
    • Error.
    • Chain.
    • ExitCode.
    • CliError.
    • Further wrap tests.

    Documentation

    • Add minimum supported rust version: 1.61
    Source code(tar.gz)
    Source code(zip)
Owner
Christopher Morton
Christopher Morton
This library provides a convenient derive macro for the standard library's std::error::Error trait.

derive(Error) This library provides a convenient derive macro for the standard library's std::error::Error trait. [dependencies] therror = "1.0" Compi

Sebastian Thiel 5 Oct 23, 2023
Bam Error Stats Tool (best): analysis of error types in aligned reads.

best Bam Error Stats Tool (best): analysis of error types in aligned reads. best is used to assess the quality of reads after aligning them to a refer

Google 54 Jan 3, 2023
Application microframework with command-line option parsing, configuration, error handling, logging, and shell interactions

Abscissa is a microframework for building Rust applications (either CLI tools or network/web services), aiming to provide a large number of features w

iqlusion 524 Dec 26, 2022
ergonomic and precise error handling built atop type-level set arithmetic

terrors - the Rust error handling library Handling errors means taking a set of possible error types, removing the ones that are locally addressible,

Komora 190 Jul 27, 2024
Sysexits-rs (sysexits) is a library that provides the system exit code constants

sysexits-rs sysexits-rs (sysexits) is a library that provides the system exit code constants as defined by <sysexits.h>. This library implements the T

Shun Sakai 7 Dec 15, 2022
A command line progress reporting library for Rust

indicatif Documentation A Rust library for indicating progress in command line applications to users. This currently primarily provides progress bars

Armin Ronacher 3.2k Dec 30, 2022
A Reporting library for for Ara Programming Language 📃

Ara Reporting A Reporting library for Ara Programming Language ?? Internally, Ara reporting uses the codespan-reporting library to build a report of t

Ara Programming Language 4 Jan 7, 2023
A simple CLI I made while practicing rust to easily make QR codes with just one command, all in your terminal.

Welcome to rust-qrcode-cli ?? A CLI I made while practicing rust to easily make QR codes with just one command, all in your terminal. Install git clon

Dhravya Shah 2 Mar 2, 2022
A run-codes cli front end with some extra features

run-cli Run-cli A run-codes cli front end with some extra features Report Bug · Request Feature Table of Contents About The Project Built With Getting

Matheus Vieira 13 Nov 16, 2022
Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and at compile-time.

rgb2ansi256 rgb2ansi256 is a small Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and const fn. Th

Linda_pp 7 Nov 17, 2022