raskell 0.1.1

Haskell-style functional programming for Rust
Documentation
use raskell::prelude::*;

#[derive(Debug, PartialEq)]
enum ApiError {
    Store,
    Inactive,
    NoNickname,
}

#[derive(Debug, PartialEq)]
struct StoreError;

impl From<StoreError> for ApiError {
    fn from(_: StoreError) -> Self {
        ApiError::Store
    }
}

#[derive(Debug)]
struct User {
    name: String,
    active: bool,
}

async fn load_user(id: u32) -> Result<User, StoreError> {
    if id == 0 {
        return Err(StoreError);
    }

    Ok(User {
        name: "Meetzli".into(),
        active: true,
    })
}

async fn load_nickname(user: &User) -> Result<Option<String>, ApiError> {
    Ok(Some(user.name.to_lowercase()))
}

/// The block is an ordinary future, so it can be returned, awaited or spawned.
#[allow(clippy::manual_async_fn, reason = "the hdo! async block is the future")]
fn greet(id: u32) -> impl Future<Output = Result<String, ApiError>> {
    hdo!(async {
        // `<-?` converts `StoreError` into `ApiError` through `From`.
        user <-? load_user(id).await;

        guard user.active throw ApiError::Inactive;

        Some(nickname) <- load_nickname(&user).await throw ApiError::NoNickname;

        pure format!("hello, {}!", nickname.to_uppercase())
    })
}

fn main() {
    println!("{:?}", pollster::block_on(greet(1)));
    println!("{:?}", pollster::block_on(greet(0)));
}