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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use crate::PicoValue; use serde::Serialize; use serde_json::json; use std::collections::HashMap; #[derive(Debug, Clone, Serialize)] pub enum StateValue { Boolean(bool), Number(isize), String(String), } type Namespace = String; pub type VariablesMap = HashMap<String, PicoValue>; type NamespaceVariableMap = HashMap<Namespace, VariablesMap>; #[derive(Serialize, Debug)] pub struct PicoContext { pub namespaced_variables: NamespaceVariableMap, pub variables: VariablesMap, pub local_variables: VariablesMap, pub input_json: Option<serde_json::Value>, } impl Default for PicoContext { fn default() -> Self { Self { namespaced_variables: HashMap::new(), variables: HashMap::new(), local_variables: HashMap::new(), input_json: None, } } } impl PicoContext { pub fn new() -> PicoContext { Default::default() } pub fn set_json(mut self, json: serde_json::Value) -> Self { self.input_json = Some(json); self } pub fn ns_add(&mut self, ns: &str) { let r = self .namespaced_variables .insert(ns.to_string(), HashMap::new()); if let Some(original) = r { warn!("overwritten namespace {}", ns); trace!(" original: {:?}", original); } } pub fn ns_del(&mut self, ns: &str) { let r = self.namespaced_variables.remove(ns); if let Some(original) = r { info!("removed namespace {}", ns); trace!(" original: {:?}", original); } } pub fn ns_get(&self, ns: &str, key: &str) -> Option<&PicoValue> { self.namespaced_variables.get(ns).and_then(|hm| hm.get(key)) } pub fn ns_set(&mut self, ns: &str, key: &str, value: &PicoValue) { self.namespaced_variables .get_mut(ns) .and_then(|hm| hm.insert(key.to_string(), value.clone())); } pub fn local_set(&mut self, key: &str, value: &PicoValue) { self.local_variables.insert(key.to_string(), value.clone()); } pub fn local_get(&self, key: &str) -> Option<&PicoValue> { self.local_variables.get(key) } pub fn local_clear(&mut self) { self.local_variables.clear() } pub fn get_value(&self, key: &str) -> Option<&PicoValue> { match self.local_get(key) { Some(v) => Some(v), None => { if let Some(input_json) = &self.input_json { trace!("Looking for key [{}] in input json", key); let json_path = format!("/{}", key); input_json.pointer(&json_path) } else { None } } } } pub fn get_final_ctx(&mut self) -> &VariablesMap { self.variables .insert("input".to_string(), json!(&self.input_json)); self.variables .insert("locals".to_string(), json!(&self.local_variables)); self.variables .insert("namespaced".to_string(), json!(&self.namespaced_variables)); &self.variables } } pub type PicoHashMap = HashMap<String, String>;