boomerang_runtime/action/
mod.rs1use std::{
2 fmt::{Debug, Display},
3 sync::{Arc, Mutex},
4};
5
6use crate::{Duration, Tag};
7
8mod action_ref;
9mod store;
10
11pub use action_ref::*;
12use store::{ActionStore, BaseActionStore};
13
14#[cfg(not(feature = "serde"))]
15pub trait ActionData: std::fmt::Debug + Send + Sync + Clone + 'static {}
16
17#[cfg(not(feature = "serde"))]
18impl<T> ActionData for T where T: std::fmt::Debug + Send + Sync + Clone + 'static {}
19
20#[cfg(feature = "serde")]
21pub trait ActionData:
22 std::fmt::Debug
23 + Send
24 + Sync
25 + Clone
26 + serde::Serialize
27 + for<'de> serde::Deserialize<'de>
28 + 'static
29{
30}
31
32#[cfg(feature = "serde")]
33impl<T> ActionData for T where
34 T: std::fmt::Debug
35 + Send
36 + Sync
37 + Clone
38 + serde::Serialize
39 + for<'de> serde::Deserialize<'de>
40 + 'static
41{
42}
43
44tinymap::key_type! {
45 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46 pub ActionKey
47}
48
49#[derive(Debug)]
51pub struct LogicalAction {
52 pub name: String,
53 pub key: ActionKey,
54 pub min_delay: Duration,
55 pub store: Box<dyn BaseActionStore>,
56}
57
58impl LogicalAction {
59 pub fn new<T: ActionData>(name: &str, key: ActionKey, min_delay: Duration) -> Self {
60 let store = ActionStore::<T>::new();
61 Self {
62 name: name.into(),
63 key,
64 min_delay,
65 store: Box::new(store),
66 }
67 }
68}
69
70#[derive(Debug)]
71pub struct PhysicalAction {
72 pub name: String,
73 pub key: ActionKey,
74 pub min_delay: Duration,
75 pub store: Arc<Mutex<dyn BaseActionStore>>,
76}
77
78impl PhysicalAction {
79 pub fn new<T: ActionData>(name: &str, key: ActionKey, min_delay: Duration) -> Self {
80 let store = ActionStore::<T>::new();
81 let store: Arc<Mutex<dyn BaseActionStore>> = Arc::new(Mutex::new(store));
82 Self {
83 name: name.into(),
84 key,
85 min_delay,
86 store,
87 }
88 }
89
90 #[cfg(feature = "serde")]
92 pub fn new_builder(&self) -> Result<serde_arrow::ArrayBuilder, crate::RuntimeError> {
93 self.store.lock().expect("lock").new_builder()
94 }
95
96 #[cfg(feature = "serde")]
98 pub fn build_value_at(
99 &mut self,
100 builder: &mut serde_arrow::ArrayBuilder,
101 tag: Tag,
102 ) -> Result<(), crate::RuntimeError> {
103 self.store
104 .lock()
105 .expect("lock")
106 .build_value_at(builder, tag)
107 }
108}
109
110#[derive(Debug)]
111pub enum Action {
112 Startup,
114 Shutdown,
116 Logical(LogicalAction),
117 Physical(PhysicalAction),
118}
119
120impl Action {
121 pub fn as_valued(&self) -> Option<&LogicalAction> {
122 if let Self::Logical(v) = self {
123 Some(v)
124 } else {
125 None
126 }
127 }
128
129 pub fn as_valued_mut(&mut self) -> Option<&mut LogicalAction> {
130 if let Self::Logical(v) = self {
131 Some(v)
132 } else {
133 None
134 }
135 }
136
137 pub fn as_physical(&mut self) -> Option<&mut PhysicalAction> {
138 if let Self::Physical(v) = self {
139 Some(v)
140 } else {
141 None
142 }
143 }
144}
145
146impl Display for Action {
147 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
148 match self {
149 Action::Startup => f.write_fmt(format_args!("Action::Startup")),
150 Action::Shutdown => f.write_fmt(format_args!("Action::Shutdown")),
151 Action::Logical(LogicalAction { name, .. }) => {
152 f.write_fmt(format_args!("Action::Logical<{name}>"))
153 }
154 Action::Physical(PhysicalAction { name, .. }) => {
155 f.write_fmt(format_args!("Action::Physical<{name}>"))
156 }
157 }
158 }
159}
160
161impl AsRef<Action> for Action {
162 fn as_ref(&self) -> &Self {
163 self
164 }
165}
166
167impl AsMut<Action> for Action {
168 fn as_mut(&mut self) -> &mut Action {
169 self
170 }
171}