nautilus_common/
component.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::fmt::Debug;
17
18use nautilus_model::identifiers::ComponentId;
19
20use crate::{
21    enums::{ComponentState, ComponentTrigger},
22    timer::TimeEvent,
23};
24
25/// Common trait for components.
26pub trait Component: Debug {
27    /// Returns the unique identifier for this component.
28    fn id(&self) -> ComponentId;
29
30    /// Returns the current state of the component.
31    fn state(&self) -> ComponentState;
32
33    /// Returns the component trigger.
34    fn trigger(&self) -> ComponentTrigger;
35
36    /// Returns whether the component is currently running.
37    fn is_running(&self) -> bool;
38
39    /// Returns whether the component is stopped.
40    fn is_stopped(&self) -> bool;
41
42    /// Returns whether the component has been disposed.
43    fn is_disposed(&self) -> bool;
44
45    /// Starts the component.
46    ///
47    /// # Errors
48    ///
49    /// Returns an error if the component fails to start.
50    fn start(&mut self) -> anyhow::Result<()>;
51
52    /// Stops the component.
53    ///
54    /// # Errors
55    ///
56    /// Returns an error if the component fails to stop.
57    fn stop(&mut self) -> anyhow::Result<()>;
58
59    /// Resets the component to its initial state.
60    ///
61    /// # Errors
62    ///
63    /// Returns an error if the component fails to reset.
64    fn reset(&mut self) -> anyhow::Result<()>;
65
66    /// Disposes of the component, releasing any resources.
67    ///
68    /// # Errors
69    ///
70    /// Returns an error if the component fails to dispose.
71    fn dispose(&mut self) -> anyhow::Result<()>;
72
73    /// Handles a timer event (TBD).
74    fn handle_event(&mut self, event: TimeEvent);
75}
76
77#[rustfmt::skip]
78impl ComponentState {
79    /// Transition the state machine with the component `trigger`.
80    ///
81    /// # Errors
82    ///
83    /// Returns an error if `trigger` is invalid for the current state.
84    pub fn transition(&mut self, trigger: &ComponentTrigger) -> anyhow::Result<Self> {
85        let new_state = match (&self, trigger) {
86            (Self::PreInitialized, ComponentTrigger::Initialize) => Self::Ready,
87            (Self::Ready, ComponentTrigger::Reset) => Self::Resetting,
88            (Self::Ready, ComponentTrigger::Start) => Self::Starting,
89            (Self::Ready, ComponentTrigger::Dispose) => Self::Disposing,
90            (Self::Resetting, ComponentTrigger::ResetCompleted) => Self::Ready,
91            (Self::Starting, ComponentTrigger::StartCompleted) => Self::Running,
92            (Self::Starting, ComponentTrigger::Stop) => Self::Stopping,
93            (Self::Starting, ComponentTrigger::Fault) => Self::Faulting,
94            (Self::Running, ComponentTrigger::Stop) => Self::Stopping,
95            (Self::Running, ComponentTrigger::Degrade) => Self::Degrading,
96            (Self::Running, ComponentTrigger::Fault) => Self::Faulting,
97            (Self::Resuming, ComponentTrigger::Stop) => Self::Stopping,
98            (Self::Resuming, ComponentTrigger::ResumeCompleted) => Self::Running,
99            (Self::Resuming, ComponentTrigger::Fault) => Self::Faulting,
100            (Self::Stopping, ComponentTrigger::StopCompleted) => Self::Stopped,
101            (Self::Stopping, ComponentTrigger::Fault) => Self::Faulting,
102            (Self::Stopped, ComponentTrigger::Reset) => Self::Resetting,
103            (Self::Stopped, ComponentTrigger::Resume) => Self::Resuming,
104            (Self::Stopped, ComponentTrigger::Dispose) => Self::Disposing,
105            (Self::Stopped, ComponentTrigger::Fault) => Self::Faulting,
106            (Self::Degrading, ComponentTrigger::DegradeCompleted) => Self::Degraded,
107            (Self::Degraded, ComponentTrigger::Resume) => Self::Resuming,
108            (Self::Degraded, ComponentTrigger::Stop) => Self::Stopping,
109            (Self::Degraded, ComponentTrigger::Fault) => Self::Faulting,
110            (Self::Disposing, ComponentTrigger::DisposeCompleted) => Self::Disposed,
111            (Self::Faulting, ComponentTrigger::FaultCompleted) => Self::Faulted,
112            _ => anyhow::bail!("Invalid state trigger {self} -> {trigger}"),
113        };
114        Ok(new_state)
115    }
116}