Phase 1.2-1.6: replace variables HashMap<String,String> with HashMap<String,Value>, rewrite str_to_dyn/dyn_to_str -> value_to_dynamic/dynamic_to_value, update resolve_string/evaluate_condition/is_truthy for Value
This commit is contained in:
@@ -2,6 +2,9 @@ use rhai::{Dynamic, Engine, Scope, AST, Module};
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use super::types::Value;
|
||||
use compact_str::CompactString;
|
||||
|
||||
pub const RHEI_PREFIX: &str = "__rhei:";
|
||||
|
||||
pub struct RheiContext {
|
||||
@@ -46,24 +49,24 @@ impl RheiContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sync_scope(&self, variables: &HashMap<String, String>) {
|
||||
pub fn sync_scope(&self, variables: &HashMap<String, Value>) {
|
||||
let mut scope = self.scope.borrow_mut();
|
||||
|
||||
for (k, v) in variables.iter() {
|
||||
if scope.contains(k) {
|
||||
if let Some(old_val) = scope.get_value::<Dynamic>(k) {
|
||||
if dyn_to_str(&old_val) == *v {
|
||||
if dynamic_to_value(&old_val) == *v {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
scope.set_value(k, str_to_dyn(v));
|
||||
scope.set_value(k, value_to_dynamic(v));
|
||||
} else {
|
||||
scope.push_dynamic(k.clone(), str_to_dyn(v));
|
||||
scope.push_dynamic(k.clone(), value_to_dynamic(v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialize(&self, variables: &mut HashMap<String, String>) {
|
||||
pub fn initialize(&self, variables: &mut HashMap<String, Value>) {
|
||||
self.sync_scope(variables);
|
||||
|
||||
let mut scope = self.scope.borrow_mut();
|
||||
@@ -72,27 +75,27 @@ impl RheiContext {
|
||||
}
|
||||
|
||||
for (name, _, val) in scope.iter_raw() {
|
||||
let s_val = dyn_to_str(&val);
|
||||
let s_val = dynamic_to_value(&val);
|
||||
if variables.get(name).map(|v| v != &s_val).unwrap_or(true) {
|
||||
variables.insert(name.to_string(), s_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval_expr(&self, expr: &str, variables: &HashMap<String, String>) -> String {
|
||||
pub fn eval_expr(&self, expr: &str, variables: &HashMap<String, Value>) -> Value {
|
||||
self.sync_scope(variables);
|
||||
let mut scope = self.scope.borrow_mut();
|
||||
|
||||
match self.engine.eval_expression_with_scope::<Dynamic>(&mut *scope, expr) {
|
||||
Ok(val) => dyn_to_str(&val),
|
||||
Ok(val) => dynamic_to_value(&val),
|
||||
Err(e) => {
|
||||
eprintln!("⚠️ Rhei eval_expr error: {e}");
|
||||
String::new()
|
||||
Value::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval_condition(&self, expr: &str, variables: &HashMap<String, String>) -> bool {
|
||||
pub fn eval_condition(&self, expr: &str, variables: &HashMap<String, Value>) -> bool {
|
||||
self.sync_scope(variables);
|
||||
let mut scope = self.scope.borrow_mut();
|
||||
|
||||
@@ -105,7 +108,7 @@ impl RheiContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_action(&self, script: &str, variables: &mut HashMap<String, String>) {
|
||||
pub fn execute_action(&self, script: &str, variables: &mut HashMap<String, Value>) {
|
||||
self.sync_scope(variables);
|
||||
let mut scope = self.scope.borrow_mut();
|
||||
|
||||
@@ -121,7 +124,7 @@ impl RheiContext {
|
||||
}
|
||||
|
||||
for (name, _, val) in scope.iter_raw() {
|
||||
let s_val = dyn_to_str(&val);
|
||||
let s_val = dynamic_to_value(&val);
|
||||
if variables.get(name).map(|v| v != &s_val).unwrap_or(true) {
|
||||
variables.insert(name.to_string(), s_val);
|
||||
}
|
||||
@@ -135,16 +138,36 @@ impl Default for RheiContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn str_to_dyn(s: &str) -> Dynamic {
|
||||
if let Ok(i) = s.parse::<i64>() { return Dynamic::from(i); }
|
||||
if let Ok(f) = s.parse::<f64>() { return Dynamic::from(f); }
|
||||
if let Ok(b) = s.parse::<bool>() { return Dynamic::from(b); }
|
||||
Dynamic::from(s.to_owned())
|
||||
pub fn value_to_dynamic(v: &Value) -> Dynamic {
|
||||
match v {
|
||||
Value::Int(i) => Dynamic::from(*i),
|
||||
Value::Float(f) => Dynamic::from(*f),
|
||||
Value::Bool(b) => Dynamic::from(*b),
|
||||
Value::Str(s) => Dynamic::from(s.to_string()),
|
||||
Value::None => Dynamic::UNIT,
|
||||
Value::Array(arr) => {
|
||||
let d: rhai::Dynamic = arr.iter().map(value_to_dynamic).collect();
|
||||
d
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dyn_to_str(d: &Dynamic) -> String {
|
||||
pub fn dynamic_to_value(d: &Dynamic) -> Value {
|
||||
if d.is_string() {
|
||||
return d.clone().into_string().unwrap_or_default();
|
||||
return Value::Str(CompactString::new(d.clone().into_string().unwrap_or_default()));
|
||||
}
|
||||
d.to_string()
|
||||
if d.is_int() {
|
||||
return Value::Int(d.as_int().unwrap_or(0));
|
||||
}
|
||||
if d.is_float() {
|
||||
return Value::Float(d.as_float().unwrap_or(0.0));
|
||||
}
|
||||
if d.is_bool() {
|
||||
return Value::Bool(d.as_bool().unwrap_or(false));
|
||||
}
|
||||
if d.is_array() {
|
||||
let arr = d.clone().into_array().unwrap_or_default();
|
||||
return Value::Array(arr.iter().map(dynamic_to_value).collect());
|
||||
}
|
||||
Value::None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user