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:
@@ -10,10 +10,12 @@ pub use rhei::RheiContext;
|
||||
use style::StyleSheet as SS;
|
||||
pub use types::{ComponentDef, Document, Element, InterpError};
|
||||
|
||||
use compact_str::CompactString;
|
||||
use opcodes::*;
|
||||
use reader::Reader;
|
||||
use rhei::{dyn_to_str, str_to_dyn, RHEI_PREFIX};
|
||||
use rhei::{value_to_dynamic, dynamic_to_value, RHEI_PREFIX};
|
||||
use style::{AncestorInfo, ComputedStyle, StructuralContext};
|
||||
pub use types::Value;
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::OnceLock;
|
||||
@@ -51,7 +53,7 @@ impl Interpreter {
|
||||
|
||||
fn parse_block_elements<'a>(
|
||||
r: &mut Reader<'a>,
|
||||
variables: &mut HashMap<String, String>,
|
||||
variables: &mut HashMap<String, Value>,
|
||||
components: &mut HashMap<String, ComponentDef<'a>>,
|
||||
rhei_scripts: &mut Vec<String>,
|
||||
stylesheet: &mut SS,
|
||||
@@ -75,7 +77,7 @@ impl Interpreter {
|
||||
OP_GLOBAL | OP_LET => {
|
||||
let name = r.read_string()?;
|
||||
let vop = r.read_byte()?;
|
||||
if let Some(value) = r.read_value_as_string(vop)? {
|
||||
if let Some(value) = r.read_value(vop)? {
|
||||
variables.insert(name, value);
|
||||
}
|
||||
}
|
||||
@@ -292,7 +294,7 @@ impl Interpreter {
|
||||
|
||||
pub fn evaluate_vdom<'a>(
|
||||
templates: &[Element<'a>],
|
||||
variables: &mut HashMap<String, String>,
|
||||
variables: &mut HashMap<String, Value>,
|
||||
components: &HashMap<String, ComponentDef<'a>>,
|
||||
rhei: &RheiContext,
|
||||
stylesheet: &SS,
|
||||
@@ -357,7 +359,7 @@ impl Interpreter {
|
||||
let source_expr = el.get_prop("source").unwrap_or_default();
|
||||
|
||||
let resolved_source = if let Some(expr) = source_expr.strip_prefix(RHEI_PREFIX) {
|
||||
Self::normalize_rhai_array(&rhei.eval_expr(expr, variables))
|
||||
Self::normalize_rhai_array(&rhei.eval_expr(expr, variables).to_owned_string())
|
||||
} else {
|
||||
Self::resolve_string(source_expr, variables).into_owned()
|
||||
};
|
||||
@@ -369,7 +371,7 @@ impl Interpreter {
|
||||
};
|
||||
|
||||
for item in items {
|
||||
let old_val = variables.insert(var_name.to_string(), item);
|
||||
let old_val = variables.insert(var_name.to_string(), Value::Str(CompactString::new(item)));
|
||||
|
||||
output.extend(Self::evaluate_vdom(
|
||||
&el.children, variables, components, rhei, stylesheet, ancestors,
|
||||
@@ -397,7 +399,7 @@ impl Interpreter {
|
||||
|
||||
let mut old_vals = Vec::with_capacity(new_args.len());
|
||||
for (k, v) in new_args {
|
||||
old_vals.push((k.clone(), variables.insert(k, v)));
|
||||
old_vals.push((k.clone(), variables.insert(k, Value::from(v))));
|
||||
}
|
||||
|
||||
let mut vcomp = Element::new(el.type_name);
|
||||
@@ -489,9 +491,9 @@ impl Interpreter {
|
||||
stylesheet.matching_rules(el.type_name, el_id, &classes, active_pseudo, structural, ancestors, preceding_siblings, &el_attributes)
|
||||
}
|
||||
|
||||
fn resolve_prop(v: &str, variables: &HashMap<String, String>, rhei: &RheiContext) -> String {
|
||||
fn resolve_prop(v: &str, variables: &HashMap<String, Value>, rhei: &RheiContext) -> String {
|
||||
if let Some(expr) = v.strip_prefix(RHEI_PREFIX) {
|
||||
rhei.eval_expr(expr, variables)
|
||||
rhei.eval_expr(expr, variables).to_owned_string().into()
|
||||
} else {
|
||||
Self::resolve_string(v, variables).into_owned()
|
||||
}
|
||||
@@ -499,7 +501,7 @@ impl Interpreter {
|
||||
|
||||
fn evaluate_condition(
|
||||
cond: &str,
|
||||
variables: &HashMap<String, String>,
|
||||
variables: &HashMap<String, Value>,
|
||||
rhei: &RheiContext,
|
||||
) -> bool {
|
||||
if let Some(expr) = cond.strip_prefix(RHEI_PREFIX) {
|
||||
@@ -515,7 +517,7 @@ impl Interpreter {
|
||||
|
||||
let resolved = Self::resolve_string(&clean, variables).trim().to_string();
|
||||
|
||||
if Self::is_truthy(&resolved) { return true; }
|
||||
if Self::is_truthy_str(&resolved) { return true; }
|
||||
if resolved == "false" || resolved == "0" || resolved.is_empty() { return false; }
|
||||
|
||||
let operators: [(&str, fn(f64, f64) -> bool); 6] = [
|
||||
@@ -542,7 +544,19 @@ impl Interpreter {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_truthy(s: &str) -> bool {
|
||||
fn is_truthy(v: &Value) -> bool {
|
||||
match v {
|
||||
Value::Bool(b) => *b,
|
||||
Value::Int(i) => *i != 0,
|
||||
Value::Float(f) => *f != 0.0,
|
||||
Value::Str(s) => Self::is_truthy_str(s),
|
||||
Value::None => false,
|
||||
Value::Array(a) => !a.is_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_truthy_str(s: &str) -> bool {
|
||||
match s.trim() {
|
||||
"" | "false" | "0" | "null" => false,
|
||||
"true" | "1" => true,
|
||||
@@ -563,7 +577,7 @@ impl Interpreter {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_string<'a>(val: &'a str, scope: &HashMap<String, String>) -> Cow<'a, str> {
|
||||
pub fn resolve_string<'a>(val: &'a str, scope: &HashMap<String, Value>) -> Cow<'a, str> {
|
||||
if !val.contains('$') {
|
||||
return Cow::Borrowed(val);
|
||||
}
|
||||
@@ -582,7 +596,8 @@ impl Interpreter {
|
||||
}
|
||||
}
|
||||
if let Some(resolved) = scope.get(&var_name) {
|
||||
result.push_str(resolved);
|
||||
let formatted = resolved.to_owned_string();
|
||||
result.push_str(&formatted);
|
||||
} else {
|
||||
result.push('$');
|
||||
result.push_str(&var_name);
|
||||
|
||||
Reference in New Issue
Block a user