use rhai::{Dynamic, Engine};
use std::fs;
use std::sync::RwLock;
thread_local! {
static INIT_MAP: RwLock<Option<rhai::Map>> = const { RwLock::new(None) };
static IS_BEGIN_PHASE: RwLock<bool> = const { RwLock::new(false) };
}
pub fn set_init_map(map: rhai::Map) {
INIT_MAP.with(|m| {
*m.write().unwrap() = Some(map);
});
}
pub fn set_begin_phase(is_begin: bool) {
IS_BEGIN_PHASE.with(|b| {
*b.write().unwrap() = is_begin;
});
}
pub fn is_begin_phase() -> bool {
IS_BEGIN_PHASE.with(|b| *b.read().unwrap())
}
fn read_file_impl(path: String) -> Result<String, Box<rhai::EvalAltResult>> {
if !is_begin_phase() {
return Err("read_file() can only be called during --begin phase".into());
}
let content = fs::read_to_string(&path).map_err(|e| {
Box::<rhai::EvalAltResult>::from(format!("Failed to read file '{}': {}", path, e))
})?;
let content = if let Some(stripped) = content.strip_prefix('\u{feff}') {
stripped
} else {
&content
};
Ok(content.to_string())
}
fn read_lines_impl(path: String) -> Result<rhai::Array, Box<rhai::EvalAltResult>> {
if !is_begin_phase() {
return Err("read_lines() can only be called during --begin phase".into());
}
let content = fs::read_to_string(&path).map_err(|e| {
Box::<rhai::EvalAltResult>::from(format!("Failed to read file '{}': {}", path, e))
})?;
let content = if let Some(stripped) = content.strip_prefix('\u{feff}') {
stripped
} else {
&content
};
let lines: rhai::Array = content
.lines()
.map(|line| Dynamic::from(line.to_string()))
.collect();
Ok(lines)
}
pub fn register_functions(engine: &mut Engine) {
engine.register_fn("read_file", read_file_impl);
engine.register_fn("read_lines", read_lines_impl);
}
pub fn deep_freeze_map(map: &mut rhai::Map) {
set_init_map(map.clone());
for (_, value) in map.iter_mut() {
deep_freeze_dynamic(value);
}
}
fn deep_freeze_dynamic(_value: &mut Dynamic) {
}