intrepid-core 0.3.0

Manage complex async business logic with ease
Documentation
mod direct_batch;
mod dispatch_batch;
mod dispatchable;
mod first_match;
mod open;
mod routed;
mod stateful;
mod stateless;

use direct_batch::Batch;
use dispatch_batch::DispatchBatch;
use first_match::FirstMatch;
use routed::Routed;

pub use open::*;
pub use stateful::*;
pub use stateless::*;

use crate::{ActionContext, Handler};

#[derive(Clone)]
/// A system is a collection of actions that can be invoked as services.
pub enum System<Status, State> {
    /// An unordered system that invokes all actions.
    Batch(Batch<Status, State>),
    /// A system that routes frames to actions fully matching patterns.
    DispatchBatch(DispatchBatch<Status, State>),
    /// A system that routes frames to matching patterns.
    Routed(Routed<Status, State>),
    /// A system that invokes the first action that matches a frame.
    FirstMatch(FirstMatch<Status, State>),
}

impl<Status, State> System<Status, State>
where
    State: Clone + Send + Sync + 'static,
{
    /// Add a frame handler to the system. This is a no-op for systems that do not support
    /// wildcard routing or only support specific patterns.
    pub fn on_frame<ActionHandler, Args>(self, action: ActionHandler) -> Self
    where
        ActionHandler: Handler<Args, State> + Clone + Send + Sync + 'static,
        Args: Clone + Send + Sync + 'static,
    {
        match self {
            Self::Batch(system) => Self::Batch(system.on_frame(action)),
            Self::FirstMatch(system) => Self::FirstMatch(system.on_frame(action)),
            _ => self,
        }
    }

    /// Add a uri bound or path bound handler to the system.
    ///
    /// - Dispatch systems will match the pattern exactly.
    /// - Routed systems will match the pattern as a path fragment.
    pub fn on<ActionHandler, Args>(self, pattern: impl AsRef<str>, action: ActionHandler) -> Self
    where
        ActionHandler: Handler<Args, State> + Clone + Send + Sync + 'static,
        Args: Clone + Send + Sync + 'static,
    {
        match self {
            Self::DispatchBatch(system) => Self::DispatchBatch(system.on(pattern, action)),
            Self::Routed(system) => Self::Routed(system.on(pattern, action)),
            _ => self,
        }
    }

    /// Get the routes for this system, if any.
    pub fn routes(&self) -> Option<Vec<String>> {
        match self {
            Self::Routed(system) => Some(system.routes()),
            _ => None,
        }
    }

    /// Get the action context for this system.
    pub fn action_context(&self) -> ActionContext<State> {
        match self {
            Self::Batch(system) => system.action_context(),
            Self::DispatchBatch(system) => system.action_context(),
            Self::Routed(system) => system.action_context(),
            Self::FirstMatch(system) => system.action_context(),
        }
    }
}