actrpc-orchestrator 0.1.0

Configuration and orchestration utilities for ActRPC.
Documentation
use crate::action::{ActionHandler, ActionHandlerFuture, TypedActionHandler};
use actrpc_core::{
    action::{ActionKind, ActionSpec, RequestedActionRecord, ResolvedActionRecord},
    interception::InterceptionRequest,
};
use std::marker::PhantomData;

pub struct RegisteredActionHandler<A, H>
where
    A: ActionSpec,
    A::Params: Send + 'static,
    A::Result: Send + 'static,
    H: TypedActionHandler<A>,
{
    inner: H,
    _marker: PhantomData<A>,
}

impl<A, H> RegisteredActionHandler<A, H>
where
    A: ActionSpec,
    A::Params: Send + 'static,
    A::Result: Send + 'static,
    H: TypedActionHandler<A>,
{
    pub fn new(inner: H) -> Self {
        Self {
            inner,
            _marker: PhantomData,
        }
    }
}

impl<A, H> ActionHandler for RegisteredActionHandler<A, H>
where
    A: ActionSpec + Send + Sync + 'static,
    A::Params: Send + 'static,
    A::Result: Send + 'static,
    H: TypedActionHandler<A> + Send + Sync + 'static,
{
    fn kind(&self) -> ActionKind {
        A::action_kind()
    }

    fn handle<'a>(
        &'a self,
        request: &'a InterceptionRequest,
        action: RequestedActionRecord,
    ) -> ActionHandlerFuture<'a>
    where
        Self: 'a,
    {
        Box::pin(async move {
            let typed_action = action.try_into()?;
            let resolved = self.inner.handle_typed(request, typed_action).await?;
            let record: ResolvedActionRecord =
                resolved.try_into().map_err(map_serde_serialize_err)?;

            Ok(record)
        })
    }
}

fn map_serde_serialize_err(error: serde_json::Error) -> actrpc_core::error::CodecError {
    actrpc_core::error::CodecError::Serialize(error.to_string())
}