diff --git a/src/fn_call.rs b/src/fn_call.rs index ce78d7f6..f4c9cb83 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -204,7 +204,11 @@ impl Engine { } // Run external function - let result = func.get_native_fn()(self, lib, args)?; + let result = if func.is_plugin_fn() { + func.get_plugin_fn().call(args, Position::none())? + } else { + func.get_native_fn()(self, lib, args)? + }; // Restore the original reference restore_first_arg(old_this_ptr, args); diff --git a/src/plugin.rs b/src/plugin.rs index 01a652e3..0cff4886 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -2,18 +2,11 @@ use crate::stdlib::{any::TypeId, boxed::Box}; -pub use crate::any::{Dynamic, Variant}; -pub use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn}; -pub use crate::parser::{ - FnAccess, - FnAccess::{Private, Public}, - AST, -}; -pub use crate::result::EvalAltResult; -pub use crate::scope::{Entry as ScopeEntry, EntryType as ScopeEntryType, Scope}; -pub use crate::token::{Position, Token}; -pub use crate::utils::StaticVec; -pub use crate::Engine; +use crate::any::Dynamic; +use crate::engine::Engine; +pub use crate::fn_native::CallableFunction; +use crate::result::EvalAltResult; +use crate::token::Position; #[cfg(features = "sync")] /// Represents an externally-written plugin for the Rhai interpreter. @@ -38,7 +31,8 @@ pub trait PluginFunction { fn is_method_call(&self) -> bool; fn is_varadic(&self) -> bool; - fn call(&self, args: &mut[&mut Dynamic], pos: Position) -> Result>; + fn call(&self, args: &mut [&mut Dynamic], pos: Position) + -> Result>; fn clone_boxed(&self) -> Box; diff --git a/src/settings.rs b/src/settings.rs index d638499c..d4949a41 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -18,9 +18,9 @@ impl Engine { /// /// When searching for functions, packages loaded later are preferred. /// In other words, loaded packages are searched in reverse order. - pub fn load_package(&mut self, package: PackageLibrary) -> &mut Self { + pub fn load_package(&mut self, package: impl Into) -> &mut Self { // Push the package to the top - packages are searched in reverse order - self.packages.push(package); + self.packages.push(package.into()); self } diff --git a/tests/closures.rs b/tests/closures.rs index 3aec4865..27ecc5e6 100644 --- a/tests/closures.rs +++ b/tests/closures.rs @@ -16,7 +16,7 @@ fn test_fn_ptr_curry_call() -> Result<(), Box> { ); let mut engine = Engine::new(); - engine.load_package(module.into()); + engine.load_package(module); #[cfg(not(feature = "no_object"))] assert_eq!( diff --git a/tests/plugins.rs b/tests/plugins.rs index b6a36cf3..95edbf47 100644 --- a/tests/plugins.rs +++ b/tests/plugins.rs @@ -1,8 +1,12 @@ -use rhai::{export_module, exported_module}; +use rhai::{ + export_fn, export_module, exported_module, + plugin::{CallableFunction, PluginFunction}, + register_exported_fn, +}; use rhai::{Engine, EvalAltResult, INT}; #[export_module] -pub mod array_package { +mod special_array_package { use rhai::{Array, INT}; pub fn len(array: &mut Array, mul: INT) -> INT { @@ -10,15 +14,25 @@ pub mod array_package { } } +#[export_fn] +fn make_greeting(n: INT) -> String { + format!("{} {}", n, if n > 1 { "kitties" } else { "kitty" }).into() +} + #[test] -fn test_plugins() -> Result<(), Box> { +fn test_plugins_package() -> Result<(), Box> { let mut engine = Engine::new(); - let m = exported_module!(array_package); + let mut m = exported_module!(special_array_package); + register_exported_fn!(m, "greet", make_greeting); - engine.load_package(m.into()); + engine.load_package(m); - assert_eq!(engine.eval::("let a = [1, 2, 3]; a.len(2)")?, 6); + assert_eq!(engine.eval::("let a = [1, 2, 3]; len(a, 2)")?, 6); + assert_eq!( + engine.eval::("let a = [1, 2, 3]; greet(len(a, 2))")?, + "6 kitties" + ); Ok(()) }