intrepid-core 0.2.0

Manage complex async business logic with ease
Documentation
use tower::{Layer, ServiceExt};

use crate::{layer::FullUriMatch, Actionable, ActiveAction, BoxedAction};

/// A route that maps a pattern to an action, and only calls that action if the pattern
/// matches the frame. Under the hood this is done with a URL pattern matcher and a
/// tower layer.
///
#[derive(Clone)]
pub struct Dispatchable<State> {
    pattern: String,
    action: BoxedAction<State>,
}

impl<State> Dispatchable<State> {
    /// Create a new action route with a given pattern and action. When the action route
    /// is turned into an actionable, it will layer the action with a URL pattern matcher.
    ///
    pub fn new(pattern: impl AsRef<str>, action: impl Actionable<State>) -> Self {
        Self {
            pattern: pattern.as_ref().into(),
            action: Box::new(action),
        }
    }
}

impl<State> Actionable<State> for Dispatchable<State>
where
    State: Clone + Send + 'static,
{
    fn into_actionable(self: Box<Self>, state: State) -> ActiveAction {
        let layer = FullUriMatch::layer(self.pattern.clone());
        let service = layer.layer(self.action.into_actionable(state));

        service.boxed_clone().into()
    }
}