1use std::collections::HashMap;
2use tinyjson::JsonValue;
3use stepflow::{Error, data::{BoolValue, TrueVar}, prelude::*};
4use stepflow::object::{ObjectStore, IdError};
5use stepflow::Session;
6use stepflow::data::{StateData, VarId, StringVar, EmailVar, BoolVar};
7use super::error::StepFlowParseError;
8use crate::json::jsonval_get_obj;
9
10
11pub fn parse_vars_json(session: &mut Session, vars_json: &HashMap<String, JsonValue>) -> Result<(), StepFlowParseError> {
12 for (name, vartype) in vars_json {
13 if let JsonValue::String(vartype) = vartype {
14 let varid = session.var_store_mut().reserve_id();
15 let var = match &vartype[..] {
16 "String" => StringVar::new(varid).boxed(),
17 "Email" => EmailVar::new(varid).boxed(),
18 "Bool" => BoolVar::new(varid).boxed(),
19 "True" => TrueVar::new(varid).boxed(),
20 _ => return Err(StepFlowParseError::UnexpectedValue(vartype.clone()))
21 };
22 session.var_store_mut().register_named(name.clone(), var)
23 .map_err(|e| stepflow::Error::VarId(e))?;
24
25 } else {
26 return Err(StepFlowParseError::WrongType { key: name.to_owned(), expected: "String".to_owned() })
27 }
28 }
29 Ok(())
30}
31
32pub fn statedata_from_jsonval_obj(jsonval_obj: &HashMap<String, JsonValue>, varstore: &ObjectStore<Box<dyn Var + Send + Sync>, VarId>) -> Result<StateData, StepFlowParseError> {
33 let mut statedata = StateData::new(); for (var_name,val_json) in jsonval_obj {
35 let var = varstore.get_by_name(&var_name[..]).ok_or_else(|| StepFlowParseError::UnexpectedValue(var_name.clone()))?;
36 let val = match val_json {
37 JsonValue::String(val_str) => {
38 var.value_from_str(&val_str[..]).map_err(|e| Error::InvalidValue(e))?
39 },
40 JsonValue::Boolean(val) => BoolValue::new(*val).boxed(),
41 _ => return Err(StepFlowParseError::WrongType { key: var_name.clone(), expected: "String or Boolean".to_owned()}),
42 };
43 statedata.insert(var, val).map_err(|e| Error::InvalidValue(e))?;
44 }
45 Ok(statedata)
46 }
47
48pub fn parse_statedata_json(json: &str, varstore: &ObjectStore<Box<dyn Var + Send + Sync>, VarId>) -> Result<StateData, StepFlowParseError> {
49 let parsed: JsonValue = json.parse()?;
50 let statedata_json = jsonval_get_obj(&parsed, "root")?;
51 let statedata = statedata_from_jsonval_obj(statedata_json, varstore)?;
52 Ok(statedata)
53}
54
55pub fn json_value_from_val(val: &Box<dyn Value>) -> JsonValue {
56 match val.get_baseval() {
57 stepflow::data::BaseValue::String(s) => JsonValue::String(s),
58 stepflow::data::BaseValue::Boolean(b) => JsonValue::Boolean(b),
59 stepflow::data::BaseValue::Float(f) => JsonValue::Number(f),
60 }
61}
62
63pub fn json_value_from_statedata(statedata: &StateData, varstore: &ObjectStore<Box<dyn Var + Send + Sync>, VarId>) -> Result<JsonValue, StepFlowParseError> {
64 let mut result = HashMap::new();
65 for (varid, val) in statedata.iter_val() {
66 let name = varstore.name_from_id(varid)
67 .ok_or_else(|| stepflow::Error::VarId(IdError::IdHasNoName(varid.clone())))?
68 .to_owned();
69 let val = json_value_from_val(val);
70 result.insert(name, val);
71 }
72 Ok(JsonValue::Object(result))
73}