openauth-core 0.0.2

Core types and primitives for OpenAuth.
Documentation
use openauth_core::context::request_state::{
    define_request_state, has_request_state, run_with_request_state,
};
use openauth_core::error::OpenAuthError;

#[derive(Clone, Debug, PartialEq, Eq)]
struct Marker {
    id: &'static str,
}

#[tokio::test]
async fn run_with_request_state_exposes_state_inside_scope() {
    let result = run_with_request_state(async {
        assert!(has_request_state());
        "success"
    })
    .await;

    assert_eq!(result, "success");
}

#[tokio::test]
async fn has_request_state_returns_false_outside_scope() {
    assert!(!has_request_state());
}

#[tokio::test]
async fn request_state_is_isolated_between_concurrent_scopes() -> Result<(), OpenAuthError> {
    let state = define_request_state(|| Marker { id: "initial" });

    let first = run_with_request_state({
        let state = state.clone();
        async move {
            state.set(Marker { id: "first" })?;
            tokio::time::sleep(std::time::Duration::from_millis(10)).await;
            state.get()
        }
    });

    let second = run_with_request_state({
        let state = state.clone();
        async move {
            state.set(Marker { id: "second" })?;
            tokio::time::sleep(std::time::Duration::from_millis(5)).await;
            state.get()
        }
    });

    let (first, second) = tokio::join!(first, second);

    assert_eq!(first?, Marker { id: "first" });
    assert_eq!(second?, Marker { id: "second" });

    Ok(())
}

#[tokio::test]
async fn request_state_lazily_initializes_once_per_scope() -> Result<(), OpenAuthError> {
    let state = define_request_state(|| Marker { id: "initial" });

    run_with_request_state(async {
        assert_eq!(state.get()?, Marker { id: "initial" });
        state.set(Marker { id: "updated" })?;
        assert_eq!(state.get()?, Marker { id: "updated" });
        Ok(())
    })
    .await
}

#[tokio::test]
async fn request_state_returns_error_outside_scope() {
    let state = define_request_state(|| Marker { id: "initial" });

    assert_eq!(state.get(), Err(OpenAuthError::RequestStateMissing));
}