rhai/tests/plugins.rs

170 lines
4.6 KiB
Rust
Raw Normal View History

2022-01-04 15:16:20 +01:00
#![cfg(not(feature = "no_index"))]
#![cfg(not(feature = "no_module"))]
2020-08-07 02:41:06 +02:00
use rhai::plugin::*;
2020-08-02 09:39:16 +02:00
use rhai::{Engine, EvalAltResult, INT};
2020-08-20 16:11:41 +02:00
mod test {
use rhai::plugin::*;
2020-08-02 09:39:16 +02:00
2020-08-20 16:11:41 +02:00
#[export_module]
pub mod special_array_package {
use rhai::{Array, INT};
pub const MYSTIC_NUMBER: INT = 42;
2020-09-13 16:12:11 +02:00
#[cfg(not(feature = "no_object"))]
pub mod feature {
2020-09-04 09:42:31 +02:00
use rhai::{Array, Dynamic, EvalAltResult};
#[rhai_fn(get = "foo", return_raw)]
#[inline(always)]
2021-03-03 15:49:29 +01:00
pub fn foo(array: &mut Array) -> Result<Dynamic, Box<EvalAltResult>> {
Ok(array[0].clone())
}
2020-08-20 16:11:41 +02:00
}
2020-09-19 12:18:40 +02:00
pub fn hash(_text: String) -> INT {
42
}
pub fn hash2(_text: &str) -> INT {
42
}
2020-09-19 12:18:40 +02:00
2020-09-04 05:57:40 +02:00
#[rhai_fn(name = "test", name = "hi")]
2020-08-20 16:11:41 +02:00
pub fn len(array: &mut Array, mul: INT) -> INT {
(array.len() as INT) * mul
}
#[rhai_fn(name = "+")]
pub fn funky_add(x: INT, y: INT) -> INT {
x / 2 + y * 2
}
#[rhai_fn(name = "no_effect", set = "no_effect", pure)]
pub fn no_effect(array: &mut Array, value: INT) {
// array is not modified
println!("Array = {:?}, Value = {}", array, value);
2021-05-13 04:34:24 +02:00
}
}
2020-08-02 09:39:16 +02:00
}
2020-08-14 07:43:26 +02:00
macro_rules! gen_unary_functions {
($op_name:ident = $op_fn:ident ( $($arg_type:ident),+ ) -> $return_type:ident) => {
mod $op_name { $(
#[allow(non_snake_case)]
2020-08-14 07:43:26 +02:00
pub mod $arg_type {
use super::super::*;
#[export_fn(name="test")]
2020-08-14 07:43:26 +02:00
pub fn single(x: $arg_type) -> $return_type {
super::super::$op_fn(x)
}
}
)* }
}
2020-08-02 12:53:25 +02:00
}
2020-08-14 07:43:26 +02:00
macro_rules! reg_functions {
($mod_name:ident += $op_name:ident :: $func:ident ( $($arg_type:ident),+ )) => {
$(register_exported_fn!($mod_name, stringify!($op_name), $op_name::$arg_type::$func);)*
}
}
2020-11-03 14:50:14 +01:00
fn make_greeting(n: impl std::fmt::Display) -> String {
2022-08-11 13:01:23 +02:00
format!("{n} kitties")
2020-08-14 07:43:26 +02:00
}
gen_unary_functions!(greet = make_greeting(INT, bool, char) -> String);
2022-08-30 07:56:25 +02:00
macro_rules! expand_enum {
($module:ident : $typ:ty => $($variant:ident),+) => {
#[export_module]
pub mod $module {
$(
2022-09-03 05:29:29 +02:00
#[allow(non_upper_case_globals)]
2022-08-30 07:56:25 +02:00
pub const $variant: $typ = <$typ>::$variant;
)*
}
};
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum MyEnum {
Foo,
Bar,
Baz,
Hello,
World,
}
expand_enum! { my_enum_module: MyEnum => Foo, Bar, Baz, Hello, World }
2020-08-02 09:39:16 +02:00
#[test]
2020-08-02 12:53:25 +02:00
fn test_plugins_package() -> Result<(), Box<EvalAltResult>> {
2020-08-02 09:39:16 +02:00
let mut engine = Engine::new();
let mut m = Module::new();
2020-09-13 16:12:11 +02:00
combine_with_exported_module!(&mut m, "test", test::special_array_package);
2022-08-30 07:56:25 +02:00
combine_with_exported_module!(&mut m, "enum", my_enum_module);
engine.register_global_module(m.into());
2020-08-02 09:39:16 +02:00
2020-08-14 07:43:26 +02:00
reg_functions!(engine += greet::single(INT, bool, char));
assert_eq!(engine.eval::<INT>("MYSTIC_NUMBER")?, 42);
2020-08-19 07:39:20 +02:00
#[cfg(not(feature = "no_object"))]
2021-05-13 04:34:24 +02:00
{
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; a.foo")?, 1);
engine.run("const A = [1, 2, 3]; A.no_effect(42);")?;
engine.run("const A = [1, 2, 3]; A.no_effect = 42;")?;
2021-05-13 04:34:24 +02:00
assert!(
matches!(*engine.run("const A = [1, 2, 3]; A.test(42);").expect_err("should error"),
2022-02-08 02:02:15 +01:00
EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "array")
2021-05-13 04:34:24 +02:00
)
}
2020-08-19 07:39:20 +02:00
2020-09-19 12:18:40 +02:00
assert_eq!(engine.eval::<INT>(r#"hash("hello")"#)?, 42);
assert_eq!(engine.eval::<INT>(r#"hash2("hello")"#)?, 42);
2020-09-04 05:57:40 +02:00
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; test(a, 2)")?, 6);
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; hi(a, 2)")?, 6);
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; test(a, 2)")?, 6);
2022-09-03 09:15:42 +02:00
assert_eq!(engine.eval::<INT>("2 + 2")?, 5);
2020-08-02 12:53:25 +02:00
assert_eq!(
engine.eval::<String>("let a = [1, 2, 3]; greet(test(a, 2))")?,
2020-08-02 12:53:25 +02:00
"6 kitties"
);
2020-08-02 09:39:16 +02:00
engine.register_static_module("test", exported_module!(test::special_array_package).into());
2020-09-13 16:12:11 +02:00
assert_eq!(engine.eval::<INT>("test::MYSTIC_NUMBER")?, 42);
2020-09-13 16:12:11 +02:00
2020-08-02 09:39:16 +02:00
Ok(())
}
#[test]
fn test_plugins_parameters() -> Result<(), Box<EvalAltResult>> {
#[export_module]
mod rhai_std {
pub fn noop(_: &str) {}
}
let mut engine = Engine::new();
let std = exported_module!(rhai_std);
engine.register_static_module("std", std.into());
assert_eq!(
engine.eval::<String>(
r#"
let s = "hello";
std::noop(s);
s
"#
)?,
"hello"
);
Ok(())
}