Crate murmur

source ·
Expand description

murmur

GitHub Crates.io Documentation GitHub Actions License

This library provides a simple and flexible way to format colored messages with optional NerdFonts or Unicode icons.

Table of Contents

  1. Usage
  2. IconKind Variants
  3. Whisper Methods
  4. Handling Errors with Default Methods
  5. Custom Error Handling

Usage

There is only a Whisper struct and an IconKind enum.

use murmur::{Whisper, IconKind};

IconKind Variants

The IconKind enum variants map to a specific Unicode or NerdFont icon, each icon has a default color. Casing conforms to Rust API Guidelines.

  • NfFaTimes
  • NfFaCheck
  • NfFaInfoCircle
  • NfFaRefresh
  • NfFaWarning
  • NfFaBug
  • UnicodeCrossMark
  • UnicodeCheckMark
  • UnicodeInformationSource
  • UnicodeGear
  • UnicodeWarningSign
  • UnicodeBug

For a full list of the currently supported icons, see the IconKind enum.

use murmur::{Whisper, IconKind};
use owo_colors::OwoColorize;

Whisper::new()
    .icon(IconKind::NfFaCheck)
    .message("message")
    .message("message".red())
    .whisper()
    .unwrap();

You must have NerdFonts installed to use the `Nf` variants.

Whisper methods:

The Whisper struct provides the following methods:

  • new(): Creates a new Whisper instance
  • .icon(): Adds an icon to the Whisper instance
  • .message(): Adds a message to the Whisper instance
  • .messages(): Adds multiple messages to the Whisper instance
  • .whisper(): Builds the Whisper instance and prints the messages

Here are some examples of how to use the Whisper struct.

new

use murmur::{Whisper, IconKind};

Whisper::new()
    .icon(IconKind::NfFaCheck)
    .message("message")
    .whisper()
    .ok();

icon

use murmur::{Whisper, IconKind};

Whisper::new().icon(IconKind::UnicodeCheckMark).whisper().ok();

message

use murmur::Whisper;
use std::io::{Error, ErrorKind};

fn main() -> Result<(), Error> {
    Whisper::new()
        .message("1 message")
        .message("2 message")
        .message("3 message")
        .whisper()
        .map_err(|err| Error::new(ErrorKind::Other, err))?;
    Ok(())
}

Output:

1 message without icon
2 message without icon indents by 2 spaces all messages after the first
3 message

messages

use murmur::Whisper;

Whisper::new()
    .messages(["1 message without icon", "2 message", "3 message"])
    .whisper()
    .ok();

Whisper::new()
    .messages(vec!["1 message without icon", "2 message", "3 message"])
    .whisper()
    .ok();

Handling Errors with Default Methods

The whisper method returns -> Result<(), WhisperError>

use murmur::{Whisper, IconKind, WhisperError};
use std::io::{Error, ErrorKind};



fn whisper_new() -> Result<(), WhisperError> {
    let whisper = Whisper::new()
        .icon(IconKind::NfFaBug)
        .message("The `whisper` method returns  `-> Result<(), WhisperError>`")
        .whisper()?;
    Ok(())
}

fn whisper_unwrap() {
    Whisper::new()
        .icon(IconKind::NfFaInfoCircle)
        .message("unwrap")
        .message("Returns the contained Ok value, consuming the self value,\
         function may panic, its use is generally discouraged")
        .whisper()
        .unwrap();
}


fn whisper_unwrap_or_else() {
    Whisper::new()
        .icon(IconKind::NfFaBug)
        .message("unwrap_or_else")
        .message("Unwrapping a `Whisper` instance or panicking with a custom message.")
        .whisper()
        .unwrap_or_else(|err| panic!("Failed to print message: {}", err));
}

fn whisper_expect() {
    Whisper::new()
        .icon(IconKind::NfFaWarning)
        .message("expect")
        .message(
            "Returns the contained Ok value, consuming the self value.\
             Because this function may panic, its use is generally discouraged.\
             Instead, prefer to use pattern matching and handle the Err case explicitly,\
             or call unwrap_or, unwrap_or_else, or unwrap_or_default.",
        )
        .whisper()
        .expect("Failed to print message");
}

fn whisper_map_err() -> Result<(), Error> {
    Whisper::new()
        .icon(IconKind::NfFaTimes)
        .message("map_err")
        .message("Maps a Result<T, E> to Result<T, F> \
         by applying a function to a contained Err value, leaving an Ok value untouched.")
        .message("This function can be used to pass through a \
         successful result while handling an error.")
        .whisper()
        .map_err(|err| Error::new(ErrorKind::Other, err))?;
    Ok(())
}

fn whisper_map_err_2() -> Result<(), Error> {
    let err = "Hypothetical error message";
    Whisper::new()
        .icon(IconKind::NfFaTimes)
        .message(&format!("Error executing command: {}", err))
        .whisper()
        .map_err(|_| Error::new(ErrorKind::Other, "Whisper failed"))?;
    Ok(())
}
fn whisper_ok() {
    Whisper::new()
        .icon(IconKind::NfFaTimes)
        .message("ok")
        .message("Converts from Result<T, E> to Option<T>.")
        .message("consuming self, and discarding the error, if any.")
        .whisper()
        .ok();
}


fn whisper_box_dyn_error() -> Result<(), Box<dyn std::error::Error>> {
   Whisper::new()
       .icon(IconKind::NfFaTimes)
      .message("box_dyn_error")
      .message("This function returns a Result. If the operation is successful,\
       it returns Ok(()).")
      .message("If there is an error during the operation, it returns WhisperError.")
      .whisper()?;
   Ok(())
}
fn whisper_match() {
    let whisper = Whisper::new()
        .icon(IconKind::NfFaBug)
        .message("match");

    match whisper.whisper() {
        Ok(()) => println!("Message printed successfully"),
        Err(error) => eprintln!("Failed to print message: {error}",),
    }
}

fn whisper_if_let() {
    let whisper = Whisper::new()
        .icon(IconKind::NfFaBug)
        .message("if_let")
        .message("test_whisper_if_let");

    if let Err(error) = whisper.whisper() {
        eprintln!("Failed to print message: {error}",);
    }
}

fn whisper_execute_command_example(command: &str, args: &[&str]) -> Result<(), Error> {
    let output = std::process::Command::new(command)
        .args(args)
        .output()?;

    let whisper = |message: &str, icon: IconKind| {
        Whisper::new()
            .icon(icon)
            .message(message)
            .whisper()
            .ok();
    };

    if output.status.success() {
        let command = format!("{} {}", command, args.join(" "));
        whisper(&command, IconKind::NfFaRefresh);
    } else {
        whisper("Failed to execute command", IconKind::NfFaTimes);
    };

    Ok(())
}

Customizing Error Handling


use murmur::{Whisper, IconKind, WhisperError};

#[derive(Debug)]
enum CustomError {
    WhisperError(String),
}

impl From<WhisperError> for CustomError {
    fn from(error: WhisperError) -> Self {
        Self::WhisperError(format!("We can add more info to the error: {error}"))
    }
}

fn explicit_closure_for_error_conversion() -> Result<(), CustomError> {
    Whisper::new()
        .icon(IconKind::NfFaTimes)
        .message("Explicit closure to convert a `WhisperError` into a `CustomError`.")
        .whisper()
        .map_err(|err| CustomError::from(err))?;
    Ok(())
}

fn function_reference_for_error_conversion() -> Result<(), CustomError> {
    Whisper::new()
        .icon(IconKind::NfFaTimes)
        .message("Function reference to convert a `WhisperError` into a `CustomError`.")
        .whisper()
        .map_err(CustomError::from)?;
    Ok(())
}

Structs

  • Represents a collection of messages with an optional icon and message

Enums

  • IconKind is an enum representing different kinds of icons for formatting messages.
  • The WhisperError enum represents different kinds of errors that can occur while printing messages.