intrepid_core/
system.rs

1mod direct_batch;
2mod dispatch_batch;
3mod dispatchable;
4mod first_match;
5mod open;
6mod routed;
7mod stateful;
8mod stateless;
9
10use direct_batch::Batch;
11use dispatch_batch::DispatchBatch;
12use first_match::FirstMatch;
13use routed::Routed;
14
15pub use open::*;
16pub use stateful::*;
17pub use stateless::*;
18
19use crate::{ActionContext, Handler};
20
21#[derive(Clone)]
22/// A system is a collection of actions that can be invoked as services.
23pub enum System<Status, State> {
24    /// An unordered system that invokes all actions.
25    Batch(Batch<Status, State>),
26    /// A system that routes frames to actions fully matching patterns.
27    DispatchBatch(DispatchBatch<Status, State>),
28    /// A system that routes frames to matching patterns.
29    Routed(Routed<Status, State>),
30    /// A system that invokes the first action that matches a frame.
31    FirstMatch(FirstMatch<Status, State>),
32}
33
34impl<Status, State> System<Status, State>
35where
36    State: Clone + Send + Sync + 'static,
37{
38    /// Add a frame handler to the system. This is a no-op for systems that do not support
39    /// wildcard routing or only support specific patterns.
40    pub fn on_frame<ActionHandler, Args>(self, action: ActionHandler) -> Self
41    where
42        ActionHandler: Handler<Args, State> + Clone + Send + Sync + 'static,
43        Args: Clone + Send + Sync + 'static,
44    {
45        match self {
46            Self::Batch(system) => Self::Batch(system.on_frame(action)),
47            Self::FirstMatch(system) => Self::FirstMatch(system.on_frame(action)),
48            _ => self,
49        }
50    }
51
52    /// Add a uri bound or path bound handler to the system.
53    ///
54    /// - Dispatch systems will match the pattern exactly.
55    /// - Routed systems will match the pattern as a path fragment.
56    pub fn on<ActionHandler, Args>(self, pattern: impl AsRef<str>, action: ActionHandler) -> Self
57    where
58        ActionHandler: Handler<Args, State> + Clone + Send + Sync + 'static,
59        Args: Clone + Send + Sync + 'static,
60    {
61        match self {
62            Self::DispatchBatch(system) => Self::DispatchBatch(system.on(pattern, action)),
63            Self::Routed(system) => Self::Routed(system.on(pattern, action)),
64            _ => self,
65        }
66    }
67
68    /// Get the routes for this system, if any.
69    pub fn routes(&self) -> Option<Vec<String>> {
70        match self {
71            Self::Routed(system) => Some(system.routes()),
72            _ => None,
73        }
74    }
75
76    /// Get the action context for this system.
77    pub fn action_context(&self) -> ActionContext<State> {
78        match self {
79            Self::Batch(system) => system.action_context(),
80            Self::DispatchBatch(system) => system.action_context(),
81            Self::Routed(system) => system.action_context(),
82            Self::FirstMatch(system) => system.action_context(),
83        }
84    }
85}