1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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(())
}