async-middleware

Crates.ioasync-middleware
lib.rsasync-middleware
version1.0.0
sourcesrc
created_at2022-07-21 05:10:17.277271
updated_at2022-07-21 05:26:22.518369
descriptionSimple async monad(ish) middleware in Rust using tuples and async trait transforms
homepagehttps://github.com/nyxtom/async-middleware
repositoryhttps://github.com/nyxtom/async-middleware
max_upload_size
id629463
size21,067
Thomas Holloway (nyxtom)

documentation

README

async-middleware

latest version documentation license

Provides a way to pipe a number of async middleware functions together that is type safe between each of the input -> output. This allows you to combine A -> B -> C similar to a monad but not quite as formal. Although, you could in theory use this as a monad library but it isn't really setup to handle identity, maps, unwraps, fors (a more formal and idiomatic approach https://medium.com/swlh/monad-interface-rust-edition-bd6486b93607) would be better but there are some things missing like async closures that would make this easier. Things like wrapping an existing async function is very difficult due to the lack of async closures in rust. In any case, this provides a simple middleware chaining.

Examples

// import * as this provides all the trait implementations by default
use async_middleware::*;

async fn producer() -> i32 {
    3
}

async fn multipler(i: i32) -> i32 {
    i * 32
}

async fn stringer(i: i32) -> String {
    i.to_string()
}

async fn logger(s: String) {
    println!("{}", s);
}

async fn log_nums(i: i32) {
    println!("{}", i);
}

#[test]
fn test_piper_tuple() {
    pipe((producer, log_nums));
    pipe((producer, stringer, logger));
    pipe((producer, multipler, stringer, logger));
    pipe((multipler, multipler, multipler));
    pipe((multipler, multipler, stringer));

    // alternative syntax
    (producer, log_nums).pipe();
    (producer, stringer, logger).pipe();
    (producer, multipler, stringer, logger).pipe();
    (multipler, multipler, multipler).pipe();
    (multipler, multipler, stringer).pipe();

    // pipe different pipes
    let m = (producer, multipler).pipe();
    let m = (m, multipler).pipe();
    let m = pipe((m, stringer));

    assert_eq!(String::from("3072"), m.call(()).await);
}

#[async_std::test]
async fn test_piper_tuple_inputs() {
    let m = (multipler, multipler, stringer).pipe();
    assert_eq!(String::from("1024"), m.call(1).await);
    assert_eq!(String::from("2048"), m.call(2).await);
    assert_eq!(String::from("3072"), m.call(3).await);
}

#[test]
fn test_convert_transform() {
    convert(multipler, stringer);
    convert(multipler, multipler);
}

#[test]
fn test_source_transform() {
    convert(producer, multipler);
}

#[test]
fn test_source_sink() {
    convert(producer, log_nums);
}

#[test]
fn test_transform() {
    convert(convert(producer, multipler), stringer);
}

#[test]
fn test_transform_source_transform_sink() {
    convert(convert(convert(producer, multipler), stringer), logger);
}
Commit count: 13

cargo fmt