stepflow_json/
data.rs

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();   // FUTURE: pre-alloc this
34    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}