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
88
89
90
91
92
93
94
95
96
97
use std::collections::HashMap;
use serde::{Deserialize};
use stepflow::prelude::*;
use stepflow::object::IdError;
use stepflow::{Session, SessionId, Error};
use super::{VarSerde, StepSerde, ActionSerde, SerdeError};
const NAME_GLOBAL_ACTION: &str = "$all";
const NAME_ROOT_STEP: &str = "$root";
#[derive(Debug, Deserialize)]
#[serde(rename = "Session")]
pub struct SessionSerde {
vars: Option<HashMap<String, VarSerde>>,
steps: HashMap<String, StepSerde>,
actions: HashMap<String, ActionSerde>,
}
impl SessionSerde {
pub fn into_session<T>(self, session_id: SessionId, allow_implicit_var: bool) -> Result<Session, SerdeError<T>> {
let mut session = Session::with_capacity(
session_id,
if let Some(vars) = &self.vars { vars.len() } else { 0 },
self.steps.len(),
self.actions.len()
);
if let Some(vars) = self.vars {
for (var_name, var_serde) in vars {
session.var_store_mut().insert_new_named(var_name, |var_id| {
Ok(var_serde.to_var(var_id))
})?;
}
}
if allow_implicit_var {
for (_step_name, step_serde) in &self.steps {
step_serde.ensure_all_vars(&mut session)?;
}
}
let mut stepid_to_substep_names = HashMap::with_capacity(self.steps.len());
for (step_name, step_serde) in self.steps {
let var_store = session.var_store();
let input_var_ids = step_serde.input_var_ids(var_store)?;
let output_var_ids = step_serde.output_var_ids(var_store)?;
session.step_store_mut().insert_new_named(step_name, |step_id| {
let (step, substep_names) = step_serde.to_step(step_id, input_var_ids, output_var_ids)?;
stepid_to_substep_names.insert(step.id().clone(), substep_names);
Ok(step)
})?;
}
for (step_id, substep_names) in stepid_to_substep_names {
if let Some(substep_names) = substep_names {
StepSerde::add_substeps(step_id, substep_names, session.step_store_mut())?;
}
}
let root_step_id = session.step_store()
.id_from_name(NAME_ROOT_STEP)
.ok_or_else(|| Error::StepId(IdError::NoSuchName(NAME_ROOT_STEP.to_owned())))?.clone();
session.push_root_substep(root_step_id);
for (step_name, action_serde) in self.actions {
let action_id = session.action_store().reserve_id()?;
let action = action_serde.to_action(action_id, session.var_store())?;
session.action_store().register_named::<String>(step_name.clone(), action)?;
if step_name.eq(NAME_GLOBAL_ACTION) {
session.set_action_for_step(action_id, None)?;
} else {
let step_id = session.step_store().id_from_name(&step_name[..]).ok_or_else(|| Error::StepId(IdError::NoSuchName(step_name)))?.clone();
session.set_action_for_step(action_id, Some(&step_id))?;
}
}
Ok(session)
}
}