ppoppo-sdk-core 0.2.0

Internal shared primitives for the Ppoppo SDK family (pas-external, pas-plims, pcs-external) — verifier port, audit trait, session liveness port, OIDC discovery, perimeter Bearer-auth Layer kit, identity types. Not a stable public API; do not depend on this crate directly. Consume the SDK crates that re-export from it (e.g. `pas-external`).
Documentation
//! [`MemoryAuthProvider`] — in-memory [`super::AuthProvider`] for
//! boundary tests. Test-support adapter; gated behind
//! `cfg(any(test, feature = "test-support"))`.

use std::sync::Arc;

use async_trait::async_trait;

use super::error::VerifyError;
use super::port::AuthProvider;

/// In-memory [`AuthProvider`] for boundary tests.
///
/// Configured with a closure mapping bearer-string → outcome, so each
/// test can pin the validator's verdict. Mirrors the
/// [`crate::MemoryBearerVerifier`] pattern: SDK ships the in-process
/// test seam so consumer integration tests don't redefine a
/// `MockValidator` struct in every file.
///
/// Gated behind `cfg(any(test, feature = "test-support"))` — zero
/// runtime cost when disabled.
pub struct MemoryAuthProvider<S> {
    outcome: Arc<dyn Fn(&str) -> Result<S, VerifyError> + Send + Sync>,
}

impl<S> MemoryAuthProvider<S>
where
    S: Clone + Send + Sync + 'static,
{
    /// Build with a verdict closure. The closure runs on every
    /// `verify_token` call; tests can capture state (e.g. an
    /// `AtomicUsize` call counter) by `move`-capturing into a
    /// `Fn` body.
    pub fn new<F>(outcome: F) -> Self
    where
        F: Fn(&str) -> Result<S, VerifyError> + Send + Sync + 'static,
    {
        Self {
            outcome: Arc::new(outcome),
        }
    }
}

#[async_trait]
impl<S> AuthProvider<S> for MemoryAuthProvider<S>
where
    S: Clone + Send + Sync + 'static,
{
    async fn verify_token(&self, bearer: &str) -> Result<S, VerifyError> {
        (self.outcome)(bearer)
    }
}