intrepid-core 0.1.6

Manage complex async business logic with ease
Documentation
use tower::Service;

use crate::{BoxedAction, Frame, FrameFuture, Handler};

/// An action that can be invoked as a service.
#[derive(Clone)]
pub struct Endpoint<State>(BoxedAction<State>);

impl<State> Endpoint<State> {
    /// Create a new endpoint.
    pub fn new<Args>(action: impl Handler<Args, State> + Send + Sync + 'static) -> Self
    where
        State: Clone + Send + Sync + 'static,
        Args: Clone + Send + Sync + 'static,
    {
        let actionable = action.as_into_actionable();

        Self(actionable)
    }

    /// Convert this endpoint into the inner action, discarding the endpoint wrapper.
    pub fn into_inner(self) -> BoxedAction<State> {
        self.0
    }
}

impl<Args, State> Handler<Args, State> for Endpoint<State>
where
    State: Clone + Send + 'static,
    Args: Clone + Send + 'static,
{
    type Future = FrameFuture;

    fn invoke(&self, frame: impl Into<Frame>, state: State) -> Self::Future {
        let frame = frame.into();
        let mut actionable = self.0.clone().into_actionable(state);

        actionable.call(frame.clone())
    }
}