mod discard;
pub use discard::reject_dropped_narrowing;
use ciborium::Value as CborValue;
use vantage_core::{Context, Result, error};
use vantage_rhai::rhai::Dynamic;
use vantage_rhai::{Block, Compiled, Env, Host};
use vantage_types::Record;
use super::convert::record_to_dynamic;
use super::handle::Handle;
use crate::vista::Vista;
const MODIFY: &str = "rhai modify script";
pub(crate) fn compile(host: &Host, what: &str, code: &str) -> Result<Compiled<Block>> {
host.compile(&Block::from(code))
.context(error!("rhai script failed to compile", script = what))
}
fn compile_handle_script(host: &Host, what: &'static str, code: &str) -> Result<Compiled<Block>> {
let script = compile(host, what, code)?;
let ast = script.ast().ok_or_else(|| {
error!(
"rhai script compiled to no single AST to check for dropped handles",
script = what
)
})?;
reject_dropped_narrowing(ast, what, true)?;
Ok(script)
}
pub fn eval_ref_script(
host: &Host,
code: &str,
env: Env,
row: &Record<CborValue>,
) -> Result<Vista> {
const WHAT: &str = "rhai reference build-script";
let script = compile_handle_script(host, WHAT, code)?;
let result = script
.eval(&env.var("row", record_to_dynamic(row)))
.context(error!("rhai script failed", script = WHAT))?;
finish(WHAT, result)
}
pub fn eval_modify_script(host: &Host, code: &str, vista: Vista) -> Result<Vista> {
let script = compile_handle_script(host, MODIFY, code)?;
let result = script
.eval(&Env::new().var("self", Dynamic::from(Handle::over(vista))))
.context(error!("rhai script failed", script = MODIFY))?;
finish(MODIFY, result)
}
fn finish(what: &'static str, result: Dynamic) -> Result<Vista> {
result
.try_cast::<Handle>()
.ok_or_else(|| {
error!("The script must end on a table handle", script = what).mark_incorrect_usage()
})?
.resolve(None)
}