migration to JS engine #1
96
src/botscript.rs
Normal file
96
src/botscript.rs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
use quickjs_rusty::Context;
|
||||||
|
use quickjs_rusty::ContextError;
|
||||||
|
use quickjs_rusty::ExecutionError;
|
||||||
|
use quickjs_rusty::OwnedJsValue as JsValue;
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum ScriptError {
|
||||||
|
#[error("error context: {0:?}")]
|
||||||
|
ContextError(#[from] ContextError),
|
||||||
|
#[error("error running: {0:?}")]
|
||||||
|
ExecutionError(#[from] ExecutionError),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ScriptResult<T> = Result<T, ScriptError>;
|
||||||
|
|
||||||
|
// TODO: remove this function since it is suitable only for early development
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
|
fn print(s: String) {
|
||||||
|
println!("{s}");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Runner {
|
||||||
|
context: Context,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Runner {
|
||||||
|
pub fn init() -> ScriptResult<Self> {
|
||||||
|
let context = Context::new(None)?;
|
||||||
|
|
||||||
|
context.add_callback("print", |a: String| {
|
||||||
|
print(a);
|
||||||
|
|
||||||
|
None::<bool>
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Runner { context })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_script(&self, content: &str) -> ScriptResult<JsValue> {
|
||||||
|
let ctx = &self.context;
|
||||||
|
|
||||||
|
let val = ctx.eval(content, false)?;
|
||||||
|
|
||||||
|
Ok(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
// allowing this since it is better for debugging tests)
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_run_script_valid() {
|
||||||
|
let runner = Runner::init().unwrap();
|
||||||
|
let val = runner.run_script(r#"print"#).unwrap();
|
||||||
|
println!("Val: {:?}", val);
|
||||||
|
let val = runner.run_script(r#"print('Hello from JS!');"#).unwrap();
|
||||||
|
println!("Val: {:?}", val);
|
||||||
|
assert!(val.is_null());
|
||||||
|
let val = runner.run_script(r#"const a = 1+2; a"#).unwrap();
|
||||||
|
println!("Val: {:?}", val);
|
||||||
|
assert_eq!(val.to_int(), Ok(3));
|
||||||
|
let val = runner.run_script(r#"a + 39"#).unwrap();
|
||||||
|
println!("Val: {:?}", val);
|
||||||
|
assert_eq!(val.to_int(), Ok(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_run_script_file_main() {
|
||||||
|
let runner = Runner::init().unwrap();
|
||||||
|
let val = runner.run_script(include_str!("../mainbot.js")).unwrap();
|
||||||
|
println!("config: {:?}", val);
|
||||||
|
let val = runner.run_script("start_buttons()").unwrap();
|
||||||
|
println!("Val: {:?}", val.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_run_script_invalid() {
|
||||||
|
let runner = Runner::init().unwrap();
|
||||||
|
let result = runner.run_script(r#"invalid_script();"#);
|
||||||
|
|
||||||
|
assert!(result.is_err());
|
||||||
|
let errstr =
|
||||||
|
if let Err(ScriptError::ExecutionError(ExecutionError::Exception(errstr))) = result {
|
||||||
|
errstr.to_string().unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("test returned wrong error!, {result:?}");
|
||||||
|
};
|
||||||
|
if errstr != "ReferenceError: invalid_script is not defined" {
|
||||||
|
panic!("test returned an error, but the wrong one, {errstr}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
pub mod admin;
|
pub mod admin;
|
||||||
|
pub mod botscript;
|
||||||
pub mod db;
|
pub mod db;
|
||||||
pub mod mongodb_storage;
|
pub mod mongodb_storage;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user