intrepid-core 0.2.0

Manage complex async business logic with ease
Documentation
mod active_action;

use crate::ActionService;

pub use active_action::ActiveAction;

/// The `Active` type state represents an action which is ready to be invoked as a service.
#[derive(Clone)]
pub struct Active(pub ActionService);

impl From<ActionService> for Active {
    fn from(service: ActionService) -> Self {
        Self(service)
    }
}

#[tokio::test]
async fn as_a_stateless_action() -> Result<(), tower::BoxError> {
    use crate::Handler;

    let action = || async {};
    let result = action.invoke((), ()).await?;

    assert_eq!(result, ().into());

    Ok(())
}

#[tokio::test]
async fn suspending_and_resuming_statelessly() -> Result<(), tower::BoxError> {
    use crate::Handler;
    use tower::Service;

    let action = || async {};
    let result = action.active(()).call(()).await?;

    assert_eq!(result, ().into());

    Ok(())
}

#[tokio::test]
async fn as_a_stateful_service() -> Result<(), tower::BoxError> {
    use crate::{Handler, State};
    use tower::Service;

    #[derive(Clone)]
    struct ArbitraryState;

    impl From<ArbitraryState> for crate::Frame {
        fn from(_: ArbitraryState) -> Self {
            "ArbitraryState".to_owned().into()
        }
    }

    let action = |State(state): State<ArbitraryState>| async { state };
    let result = action.active(ArbitraryState).call(()).await?;

    assert_eq!(result, "ArbitraryState".to_string().into());

    Ok(())
}