1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use std::{sync::RwLock, unimplemented};
use stepflow_base::ObjectStoreFiltered;
use stepflow_data::{StateDataFiltered, var::{Var, VarId}};
use super::{ActionResult, Action, ActionId, Step};
use crate::ActionError;
pub struct CallbackAction<F> {
id: ActionId,
cb: RwLock<F>,
}
impl<F> std::fmt::Debug for CallbackAction<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "CallbackAction({})", self.id)
}
}
impl<F> CallbackAction<F>
where F: FnMut(&Step, Option<&str>, &StateDataFiltered, &ObjectStoreFiltered<Box<dyn Var + Send + Sync>, VarId>) -> Result<ActionResult, ActionError> + Send + Sync
{
pub fn new(id: ActionId, cb: F) -> Self {
CallbackAction {
id,
cb: RwLock::new(cb),
}
}
}
impl<F> Action for CallbackAction<F>
where F: FnMut(&Step, Option<&str>, &StateDataFiltered, &ObjectStoreFiltered<Box<dyn Var + Send + Sync>, VarId>) -> Result<ActionResult, ActionError> + Send + Sync
{
fn id(&self) -> &ActionId {
&self.id
}
fn boxed(self) -> Box<dyn Action + Sync + Send> {
unimplemented!();
}
fn start(&mut self, step: &Step, step_name: Option<&str>, step_data: &StateDataFiltered, vars: &ObjectStoreFiltered<Box<dyn Var + Send + Sync>, VarId>)
-> Result<ActionResult, ActionError> {
let mut cb = self.cb.try_write().map_err(|_e| ActionError::Other)?;
cb(step, step_name, step_data, vars)
}
}
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use stepflow_base::ObjectStoreFiltered;
use stepflow_data::StateDataFiltered;
use stepflow_test_util::test_id;
use crate::{ Action, ActionId, ActionResult};
use super::CallbackAction;
use super::super::test_action_setup;
#[test]
fn basic_callback() {
let mut count = 0;
{
let mut exec = CallbackAction::new(test_id!(ActionId),
|_, _, _, _| {
count += 1;
Ok(ActionResult::CannotFulfill)
});
let (step, state_data, var_store, _var_id, _val) = test_action_setup();
let vars = ObjectStoreFiltered::new(&var_store, HashSet::new());
let step_data_filtered = StateDataFiltered::new(&state_data, HashSet::new());
let start_action1 = exec.start(&step, None, &step_data_filtered, &vars);
assert_eq!(start_action1, Ok(ActionResult::CannotFulfill));
let start_action2 = exec.start(&step, None, &step_data_filtered, &vars);
assert_eq!(start_action2, Ok(ActionResult::CannotFulfill));
let start_action3 = exec.start(&step, None, &step_data_filtered, &vars);
assert_eq!(start_action3, Ok(ActionResult::CannotFulfill));
}
assert_eq!(count, 3);
}
}