Skip to content

tibrom/async-result-ext

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

async-result-ext

Async extensions for Rust’s [Result<T, E>].
This crate provides asynchronous counterparts of the standard Result methods (map, and_then, map_err, inspect), allowing you to use async closures seamlessly.


✨ Motivation

The standard library’s Result methods (map, and_then, etc.) only work with synchronous closures.
When writing async code, you often need to .await inside these transformations. This crate fills that gap.

Instead of:

let res: Result<i32, &str> = Ok(5);

let mapped = match res {
    Ok(v) => Ok(async { v * 2 }.await),
    Err(e) => Err(e),
};

You can just write:

use async_result_ext::AsyncResultExt;

let res: Result<i32, &str> = Ok(5);
let mapped = res.async_map(|v| async move { v * 2 }).await;

assert_eq!(mapped, Ok(10));

📦 Installation

Add this to your Cargo.toml:

[dependencies]
async-result-ext = "0.1.0"

🚀 Usage

use async_result_ext::AsyncResultExt;

#[tokio::main]
async fn main() {
    let r: Result<i32, &str> = Ok(2);

    // async_map: transform Ok values asynchronously
    let doubled = r.async_map(|v| async move { v * 2 }).await;
    assert_eq!(doubled, Ok(4));

    // async_and_then: chain async computations returning Result
    let chained = doubled.async_and_then(|v| async move { Ok(v + 3) }).await;
    assert_eq!(chained, Ok(7));

    // async_map_or: provide a default for Err cases
    let res = Err::<i32, &str>("fail");
    let fallback = res.async_map_or(100, |v| async move { v * 10 }).await;
    assert_eq!(fallback, 100);

    // async_map_err: transform errors asynchronously
    let err: Result<i32, &str> = Err("oops");
    let mapped_err = err.async_map_err(|e| async move { e.len() }).await;
    assert_eq!(mapped_err, Err(4));

    // async_inspect & async_inspect_err: peek into values without changing them
    let ok: Result<i32, &str> = Ok(42);
    ok.async_inspect(|v| async move {
        println!("Got value: {v}");
    }).await;

    let err: Result<i32, &str> = Err("fail");
    err.async_inspect_err(|e| async move {
        eprintln!("Error: {e}");
    }).await;

    // async_is_ok_and: check condition asynchronously on Ok values
    let r: Result<i32, &str> = Ok(10);
    let is_even = r.async_is_ok_and(|v| async move { v % 2 == 0 }).await;
    assert!(is_even);

    // async_is_err_and: check condition asynchronously on Err values
    let r: Result<i32, &str> = Err("boom!");
    let too_long = r.async_is_err_and(|e| async move { e.len() > 3 }).await;
    assert!(too_long);
}

📖 Provided Methods

  • async_map – async version of [Result::map]
  • async_and_then – async version of [Result::and_then]
  • async_map_or – async version of [Result::map_or]
  • async_map_or_else – async version of [Result::map_or_else]
  • async_map_err – async version of [Result::map_err]
  • async_inspect – async version of [Result::inspect]
  • async_inspect_err – async version of [Result::inspect_err]
  • async_is_ok_and - async version of [Result::is_ok_and]
  • async_is_err_and - async version of [Result::is_err_and]

⚡ Features

  • Minimal and lightweight
  • No dependencies (except your async runtime, e.g. Tokio or async-std)
  • Familiar API – mirrors the standard library’s Result methods

🔧 License

MIT License. See LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages