Add public_only parameter to module function methods.
This commit is contained in:
parent
a3a167424b
commit
057f6435a4
@ -27,6 +27,7 @@ Breaking changes
|
|||||||
* Language keywords are now _reserved_ (even when disabled) and they can no longer be used as variable names.
|
* Language keywords are now _reserved_ (even when disabled) and they can no longer be used as variable names.
|
||||||
* Function signature for defining custom syntax is simplified.
|
* Function signature for defining custom syntax is simplified.
|
||||||
* `Engine::register_raw_fn_XXX` API shortcuts are removed.
|
* `Engine::register_raw_fn_XXX` API shortcuts are removed.
|
||||||
|
* `PackagesCollection::get_fn`, `PackagesCollection::contains_fn`, `Module::get_fn` and `Module::contains_fn` now take an additional `public_only` parameter indicating whether only public functions are accepted.
|
||||||
|
|
||||||
Housekeeping
|
Housekeeping
|
||||||
------------
|
------------
|
||||||
|
@ -19,7 +19,7 @@ use crate::utils::StaticVec;
|
|||||||
use crate::any::Variant;
|
use crate::any::Variant;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
use crate::parser::{FnAccess, ScriptFnDef};
|
use crate::parser::ScriptFnDef;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
use crate::module::ModuleResolver;
|
use crate::module::ModuleResolver;
|
||||||
@ -264,19 +264,15 @@ pub fn get_script_function_by_signature<'a>(
|
|||||||
module: &'a Module,
|
module: &'a Module,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: usize,
|
params: usize,
|
||||||
public_only: bool,
|
pub_only: bool,
|
||||||
) -> Option<&'a ScriptFnDef> {
|
) -> Option<&'a ScriptFnDef> {
|
||||||
// Qualifiers (none) + function name + number of arguments.
|
// Qualifiers (none) + function name + number of arguments.
|
||||||
let hash_script = calc_fn_hash(empty(), name, params, empty());
|
let hash_script = calc_fn_hash(empty(), name, params, empty());
|
||||||
let func = module.get_fn(hash_script)?;
|
let func = module.get_fn(hash_script, pub_only)?;
|
||||||
if !func.is_script() {
|
if func.is_script() {
|
||||||
return None;
|
Some(func.get_fn_def())
|
||||||
}
|
} else {
|
||||||
let fn_def = func.get_fn_def();
|
None
|
||||||
|
|
||||||
match fn_def.access {
|
|
||||||
FnAccess::Private if public_only => None,
|
|
||||||
FnAccess::Private | FnAccess::Public => Some(&fn_def),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,7 +794,7 @@ impl Engine {
|
|||||||
|
|
||||||
let mut val = match sub_lhs {
|
let mut val = match sub_lhs {
|
||||||
Expr::Property(p) => {
|
Expr::Property(p) => {
|
||||||
let ((prop, _, _), _) = p.as_ref();
|
let ((prop, _, _), pos) = p.as_ref();
|
||||||
let index = prop.clone().into();
|
let index = prop.clone().into();
|
||||||
self.get_indexed_mut(state, lib, target, index, *pos, false, level)?
|
self.get_indexed_mut(state, lib, target, index, *pos, false, level)?
|
||||||
}
|
}
|
||||||
@ -827,12 +823,12 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
// xxx.sub_lhs[expr] | xxx.sub_lhs.expr
|
// xxx.sub_lhs[expr] | xxx.sub_lhs.expr
|
||||||
Expr::Index(x) | Expr::Dot(x) => {
|
Expr::Index(x) | Expr::Dot(x) => {
|
||||||
let (sub_lhs, expr, pos) = x.as_ref();
|
let (sub_lhs, expr, _) = x.as_ref();
|
||||||
|
|
||||||
match sub_lhs {
|
match sub_lhs {
|
||||||
// xxx.prop[expr] | xxx.prop.expr
|
// xxx.prop[expr] | xxx.prop.expr
|
||||||
Expr::Property(p) => {
|
Expr::Property(p) => {
|
||||||
let ((_, getter, setter), _) = p.as_ref();
|
let ((_, getter, setter), pos) = p.as_ref();
|
||||||
let arg_values = &mut [target.as_mut(), &mut Default::default()];
|
let arg_values = &mut [target.as_mut(), &mut Default::default()];
|
||||||
let args = &mut arg_values[..1];
|
let args = &mut arg_values[..1];
|
||||||
let (mut val, updated) = self
|
let (mut val, updated) = self
|
||||||
@ -1304,8 +1300,8 @@ impl Engine {
|
|||||||
|
|
||||||
if let Some(CallableFunction::Method(func)) = self
|
if let Some(CallableFunction::Method(func)) = self
|
||||||
.global_module
|
.global_module
|
||||||
.get_fn(hash_fn)
|
.get_fn(hash_fn, false)
|
||||||
.or_else(|| self.packages.get_fn(hash_fn))
|
.or_else(|| self.packages.get_fn(hash_fn, false))
|
||||||
{
|
{
|
||||||
// Overriding exact implementation
|
// Overriding exact implementation
|
||||||
func(self, lib, &mut [lhs_ptr, &mut rhs_val])?;
|
func(self, lib, &mut [lhs_ptr, &mut rhs_val])?;
|
||||||
@ -1431,7 +1427,7 @@ impl Engine {
|
|||||||
let ((name, _, pos), modules, hash, args_expr, def_val) = x.as_ref();
|
let ((name, _, pos), modules, hash, args_expr, def_val) = x.as_ref();
|
||||||
self.make_qualified_function_call(
|
self.make_qualified_function_call(
|
||||||
scope, mods, state, lib, this_ptr, modules, name, args_expr, *def_val, *hash,
|
scope, mods, state, lib, this_ptr, modules, name, args_expr, *def_val, *hash,
|
||||||
true, level,
|
level,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ use crate::engine::{
|
|||||||
KEYWORD_TYPE_OF,
|
KEYWORD_TYPE_OF,
|
||||||
};
|
};
|
||||||
use crate::error::ParseErrorType;
|
use crate::error::ParseErrorType;
|
||||||
use crate::fn_native::{CallableFunction, FnCallArgs, FnPtr};
|
use crate::fn_native::{FnCallArgs, FnPtr};
|
||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, ModuleRef};
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::parser::{Expr, FnAccess, ImmutableString, AST, INT};
|
use crate::parser::{Expr, ImmutableString, AST, INT};
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
use crate::token::Position;
|
use crate::token::Position;
|
||||||
@ -105,19 +105,6 @@ fn restore_first_arg<'a>(old_this_ptr: Option<&'a mut Dynamic>, args: &mut FnCal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_public_access(func: &CallableFunction) -> Option<&CallableFunction> {
|
|
||||||
if func.access() == FnAccess::Private {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(func)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)]
|
|
||||||
fn no_check_access(func: &CallableFunction) -> Option<&CallableFunction> {
|
|
||||||
Some(func)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// Universal method for calling functions either registered with the `Engine` or written in Rhai.
|
/// Universal method for calling functions either registered with the `Engine` or written in Rhai.
|
||||||
/// Position in `EvalAltResult` is `None` and must be set afterwards.
|
/// Position in `EvalAltResult` is `None` and must be set afterwards.
|
||||||
@ -146,12 +133,6 @@ impl Engine {
|
|||||||
|
|
||||||
let native_only = hash_script == 0;
|
let native_only = hash_script == 0;
|
||||||
|
|
||||||
let check = if pub_only {
|
|
||||||
check_public_access
|
|
||||||
} else {
|
|
||||||
no_check_access
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check for stack overflow
|
// Check for stack overflow
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -170,16 +151,14 @@ impl Engine {
|
|||||||
// Then search packages
|
// Then search packages
|
||||||
// NOTE: We skip script functions for global_module and packages, and native functions for lib
|
// NOTE: We skip script functions for global_module and packages, and native functions for lib
|
||||||
let func = if !native_only {
|
let func = if !native_only {
|
||||||
lib.get_fn(hash_script).and_then(check) //.or_else(|| lib.get_fn(hash_fn)).and_then(check)
|
lib.get_fn(hash_script, pub_only) //.or_else(|| lib.get_fn(hash_fn, pub_only))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
//.or_else(|| self.global_module.get_fn(hash_script)).and_then(check)
|
//.or_else(|| self.global_module.get_fn(hash_script, pub_only))
|
||||||
.or_else(|| self.global_module.get_fn(hash_fn))
|
.or_else(|| self.global_module.get_fn(hash_fn, pub_only))
|
||||||
.and_then(check)
|
//.or_else(|| self.packages.get_fn(hash_script, pub_only))
|
||||||
//.or_else(|| self.packages.get_fn(hash_script)).and_then(check)
|
.or_else(|| self.packages.get_fn(hash_fn, pub_only));
|
||||||
.or_else(|| self.packages.get_fn(hash_fn))
|
|
||||||
.and_then(check);
|
|
||||||
|
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -274,7 +253,11 @@ impl Engine {
|
|||||||
// Getter function not found?
|
// Getter function not found?
|
||||||
if let Some(prop) = extract_prop_from_getter(fn_name) {
|
if let Some(prop) = extract_prop_from_getter(fn_name) {
|
||||||
return Err(Box::new(EvalAltResult::ErrorDotExpr(
|
return Err(Box::new(EvalAltResult::ErrorDotExpr(
|
||||||
format!("- property '{}' unknown or write-only", prop),
|
format!(
|
||||||
|
"Unknown property '{}' for {}, or it is write-only",
|
||||||
|
prop,
|
||||||
|
self.map_type_name(args[0].type_name())
|
||||||
|
),
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -282,7 +265,11 @@ impl Engine {
|
|||||||
// Setter function not found?
|
// Setter function not found?
|
||||||
if let Some(prop) = extract_prop_from_setter(fn_name) {
|
if let Some(prop) = extract_prop_from_setter(fn_name) {
|
||||||
return Err(Box::new(EvalAltResult::ErrorDotExpr(
|
return Err(Box::new(EvalAltResult::ErrorDotExpr(
|
||||||
format!("- property '{}' unknown or read-only", prop),
|
format!(
|
||||||
|
"Unknown property '{}' for {}, or it is read-only",
|
||||||
|
prop,
|
||||||
|
self.map_type_name(args[0].type_name())
|
||||||
|
),
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -401,27 +388,17 @@ impl Engine {
|
|||||||
|
|
||||||
// Has a system function an override?
|
// Has a system function an override?
|
||||||
fn has_override(&self, lib: &Module, hash_fn: u64, hash_script: u64, pub_only: bool) -> bool {
|
fn has_override(&self, lib: &Module, hash_fn: u64, hash_script: u64, pub_only: bool) -> bool {
|
||||||
let check = if pub_only {
|
|
||||||
check_public_access
|
|
||||||
} else {
|
|
||||||
no_check_access
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE: We skip script functions for global_module and packages, and native functions for lib
|
// NOTE: We skip script functions for global_module and packages, and native functions for lib
|
||||||
|
|
||||||
// First check script-defined functions
|
// First check script-defined functions
|
||||||
lib.get_fn(hash_script)
|
lib.contains_fn(hash_script, pub_only)
|
||||||
.and_then(check)
|
//|| lib.contains_fn(hash_fn, pub_only)
|
||||||
//.or_else(|| lib.get_fn(hash_fn)).and_then(check)
|
|
||||||
// Then check registered functions
|
// Then check registered functions
|
||||||
//.or_else(|| self.global_module.get_fn(hash_script)).and_then(check)
|
//|| self.global_module.contains_fn(hash_script, pub_only)
|
||||||
.or_else(|| self.global_module.get_fn(hash_fn))
|
|| self.global_module.contains_fn(hash_fn, pub_only)
|
||||||
.and_then(check)
|
|
||||||
// Then check packages
|
// Then check packages
|
||||||
//.or_else(|| self.packages.get_fn(hash_script)).and_then(check)
|
//|| self.packages.contains_fn(hash_script, pub_only)
|
||||||
.or_else(|| self.packages.get_fn(hash_fn))
|
|| self.packages.contains_fn(hash_fn, pub_only)
|
||||||
.and_then(check)
|
|
||||||
.is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an actual function call, taking care of special functions
|
/// Perform an actual function call, taking care of special functions
|
||||||
@ -840,7 +817,6 @@ impl Engine {
|
|||||||
args_expr: &[Expr],
|
args_expr: &[Expr],
|
||||||
def_val: Option<bool>,
|
def_val: Option<bool>,
|
||||||
hash_script: u64,
|
hash_script: u64,
|
||||||
pub_only: bool,
|
|
||||||
level: usize,
|
level: usize,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let modules = modules.as_ref().unwrap();
|
let modules = modules.as_ref().unwrap();
|
||||||
@ -887,13 +863,7 @@ impl Engine {
|
|||||||
let module = search_imports(mods, state, modules)?;
|
let module = search_imports(mods, state, modules)?;
|
||||||
|
|
||||||
// First search in script-defined functions (can override built-in)
|
// First search in script-defined functions (can override built-in)
|
||||||
let check = if pub_only {
|
let func = match module.get_qualified_fn(hash_script) {
|
||||||
check_public_access
|
|
||||||
} else {
|
|
||||||
no_check_access
|
|
||||||
};
|
|
||||||
|
|
||||||
let func = match module.get_qualified_fn(hash_script).and_then(check) {
|
|
||||||
// Then search in Rust functions
|
// Then search in Rust functions
|
||||||
None => {
|
None => {
|
||||||
self.inc_operations(state)?;
|
self.inc_operations(state)?;
|
||||||
@ -907,7 +877,7 @@ impl Engine {
|
|||||||
// 3) The final hash is the XOR of the two hashes.
|
// 3) The final hash is the XOR of the two hashes.
|
||||||
let hash_qualified_fn = hash_script ^ hash_fn_args;
|
let hash_qualified_fn = hash_script ^ hash_fn_args;
|
||||||
|
|
||||||
module.get_qualified_fn(hash_qualified_fn).and_then(check)
|
module.get_qualified_fn(hash_qualified_fn)
|
||||||
}
|
}
|
||||||
r => r,
|
r => r,
|
||||||
};
|
};
|
||||||
|
@ -355,10 +355,20 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// let mut module = Module::new();
|
/// let mut module = Module::new();
|
||||||
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn contains_fn(&self, hash_fn: u64) -> bool {
|
pub fn contains_fn(&self, hash_fn: u64, public_only: bool) -> bool {
|
||||||
self.functions.contains_key(&hash_fn)
|
if public_only {
|
||||||
|
self.functions
|
||||||
|
.get(&hash_fn)
|
||||||
|
.map(|(_, access, _, _)| match access {
|
||||||
|
FnAccess::Public => true,
|
||||||
|
FnAccess::Private => false,
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
} else {
|
||||||
|
self.functions.contains_key(&hash_fn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust function into the module, returning a hash key.
|
/// Set a Rust function into the module, returning a hash key.
|
||||||
@ -443,7 +453,7 @@ impl Module {
|
|||||||
/// Ok(orig) // return Result<T, Box<EvalAltResult>>
|
/// Ok(orig) // return Result<T, Box<EvalAltResult>>
|
||||||
/// });
|
/// });
|
||||||
///
|
///
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_raw_fn<T: Variant + Clone>(
|
pub fn set_raw_fn<T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -468,7 +478,7 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// let mut module = Module::new();
|
/// let mut module = Module::new();
|
||||||
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_0<T: Variant + Clone>(
|
pub fn set_fn_0<T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -491,7 +501,7 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// let mut module = Module::new();
|
/// let mut module = Module::new();
|
||||||
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_1<A: Variant + Clone, T: Variant + Clone>(
|
pub fn set_fn_1<A: Variant + Clone, T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -516,7 +526,7 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// let mut module = Module::new();
|
/// let mut module = Module::new();
|
||||||
/// let hash = module.set_fn_1_mut("calc", |x: &mut i64| { *x += 1; Ok(*x) });
|
/// let hash = module.set_fn_1_mut("calc", |x: &mut i64| { *x += 1; Ok(*x) });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_1_mut<A: Variant + Clone, T: Variant + Clone>(
|
pub fn set_fn_1_mut<A: Variant + Clone, T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -541,7 +551,7 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// let mut module = Module::new();
|
/// let mut module = Module::new();
|
||||||
/// let hash = module.set_getter_fn("value", |x: &mut i64| { Ok(*x) });
|
/// let hash = module.set_getter_fn("value", |x: &mut i64| { Ok(*x) });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn set_getter_fn<A: Variant + Clone, T: Variant + Clone>(
|
pub fn set_getter_fn<A: Variant + Clone, T: Variant + Clone>(
|
||||||
@ -565,7 +575,7 @@ impl Module {
|
|||||||
/// let hash = module.set_fn_2("calc", |x: i64, y: ImmutableString| {
|
/// let hash = module.set_fn_2("calc", |x: i64, y: ImmutableString| {
|
||||||
/// Ok(x + y.len() as i64)
|
/// Ok(x + y.len() as i64)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_2<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
pub fn set_fn_2<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -596,7 +606,7 @@ impl Module {
|
|||||||
/// let hash = module.set_fn_2_mut("calc", |x: &mut i64, y: ImmutableString| {
|
/// let hash = module.set_fn_2_mut("calc", |x: &mut i64, y: ImmutableString| {
|
||||||
/// *x += y.len() as i64; Ok(*x)
|
/// *x += y.len() as i64; Ok(*x)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_2_mut<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
pub fn set_fn_2_mut<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -628,7 +638,7 @@ impl Module {
|
|||||||
/// *x = y.len() as i64;
|
/// *x = y.len() as i64;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn set_setter_fn<A: Variant + Clone, B: Variant + Clone>(
|
pub fn set_setter_fn<A: Variant + Clone, B: Variant + Clone>(
|
||||||
@ -653,7 +663,7 @@ impl Module {
|
|||||||
/// let hash = module.set_indexer_get_fn(|x: &mut i64, y: ImmutableString| {
|
/// let hash = module.set_indexer_get_fn(|x: &mut i64, y: ImmutableString| {
|
||||||
/// Ok(*x + y.len() as i64)
|
/// Ok(*x + y.len() as i64)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -677,7 +687,7 @@ impl Module {
|
|||||||
/// let hash = module.set_fn_3("calc", |x: i64, y: ImmutableString, z: i64| {
|
/// let hash = module.set_fn_3("calc", |x: i64, y: ImmutableString, z: i64| {
|
||||||
/// Ok(x + y.len() as i64 + z)
|
/// Ok(x + y.len() as i64 + z)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_3<
|
pub fn set_fn_3<
|
||||||
A: Variant + Clone,
|
A: Variant + Clone,
|
||||||
@ -714,7 +724,7 @@ impl Module {
|
|||||||
/// let hash = module.set_fn_3_mut("calc", |x: &mut i64, y: ImmutableString, z: i64| {
|
/// let hash = module.set_fn_3_mut("calc", |x: &mut i64, y: ImmutableString, z: i64| {
|
||||||
/// *x += y.len() as i64 + z; Ok(*x)
|
/// *x += y.len() as i64 + z; Ok(*x)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_3_mut<
|
pub fn set_fn_3_mut<
|
||||||
A: Variant + Clone,
|
A: Variant + Clone,
|
||||||
@ -752,7 +762,7 @@ impl Module {
|
|||||||
/// *x = y.len() as i64 + value;
|
/// *x = y.len() as i64 + value;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -796,8 +806,8 @@ impl Module {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// );
|
/// );
|
||||||
/// assert!(module.contains_fn(hash_get));
|
/// assert!(module.contains_fn(hash_get, true));
|
||||||
/// assert!(module.contains_fn(hash_set));
|
/// assert!(module.contains_fn(hash_set, true));
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -825,7 +835,7 @@ impl Module {
|
|||||||
/// let hash = module.set_fn_4("calc", |x: i64, y: ImmutableString, z: i64, _w: ()| {
|
/// let hash = module.set_fn_4("calc", |x: i64, y: ImmutableString, z: i64, _w: ()| {
|
||||||
/// Ok(x + y.len() as i64 + z)
|
/// Ok(x + y.len() as i64 + z)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_4<
|
pub fn set_fn_4<
|
||||||
A: Variant + Clone,
|
A: Variant + Clone,
|
||||||
@ -869,7 +879,7 @@ impl Module {
|
|||||||
/// let hash = module.set_fn_4_mut("calc", |x: &mut i64, y: ImmutableString, z: i64, _w: ()| {
|
/// let hash = module.set_fn_4_mut("calc", |x: &mut i64, y: ImmutableString, z: i64, _w: ()| {
|
||||||
/// *x += y.len() as i64 + z; Ok(*x)
|
/// *x += y.len() as i64 + z; Ok(*x)
|
||||||
/// });
|
/// });
|
||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_fn_4_mut<
|
pub fn set_fn_4_mut<
|
||||||
A: Variant + Clone,
|
A: Variant + Clone,
|
||||||
@ -903,8 +913,14 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// The `u64` hash is calculated by the function `crate::calc_fn_hash`.
|
/// The `u64` hash is calculated by the function `crate::calc_fn_hash`.
|
||||||
/// It is also returned by the `set_fn_XXX` calls.
|
/// It is also returned by the `set_fn_XXX` calls.
|
||||||
pub(crate) fn get_fn(&self, hash_fn: u64) -> Option<&Func> {
|
pub(crate) fn get_fn(&self, hash_fn: u64, public_only: bool) -> Option<&Func> {
|
||||||
self.functions.get(&hash_fn).map(|(_, _, _, v)| v)
|
self.functions
|
||||||
|
.get(&hash_fn)
|
||||||
|
.and_then(|(_, access, _, f)| match access {
|
||||||
|
_ if !public_only => Some(f),
|
||||||
|
FnAccess::Public => Some(f),
|
||||||
|
FnAccess::Private => None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a modules-qualified function.
|
/// Get a modules-qualified function.
|
||||||
|
@ -61,14 +61,15 @@ impl PackagesCollection {
|
|||||||
self.0.insert(0, package);
|
self.0.insert(0, package);
|
||||||
}
|
}
|
||||||
/// Does the specified function hash key exist in the `PackagesCollection`?
|
/// Does the specified function hash key exist in the `PackagesCollection`?
|
||||||
pub fn contains_fn(&self, hash: u64) -> bool {
|
#[allow(dead_code)]
|
||||||
self.0.iter().any(|p| p.contains_fn(hash))
|
pub fn contains_fn(&self, hash: u64, public_only: bool) -> bool {
|
||||||
|
self.0.iter().any(|p| p.contains_fn(hash, public_only))
|
||||||
}
|
}
|
||||||
/// Get specified function via its hash key.
|
/// Get specified function via its hash key.
|
||||||
pub fn get_fn(&self, hash: u64) -> Option<&CallableFunction> {
|
pub fn get_fn(&self, hash: u64, public_only: bool) -> Option<&CallableFunction> {
|
||||||
self.0
|
self.0
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.get_fn(hash))
|
.map(|p| p.get_fn(hash, public_only))
|
||||||
.find(|f| f.is_some())
|
.find(|f| f.is_some())
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ impl fmt::Display for EvalAltResult {
|
|||||||
| Self::ErrorVariableNotFound(s, _)
|
| Self::ErrorVariableNotFound(s, _)
|
||||||
| Self::ErrorModuleNotFound(s, _) => write!(f, "{}: '{}'", desc, s)?,
|
| Self::ErrorModuleNotFound(s, _) => write!(f, "{}: '{}'", desc, s)?,
|
||||||
|
|
||||||
Self::ErrorDotExpr(s, _) if !s.is_empty() => write!(f, "{} {}", desc, s)?,
|
Self::ErrorDotExpr(s, _) if !s.is_empty() => write!(f, "{}", s)?,
|
||||||
|
|
||||||
Self::ErrorIndexingType(_, _)
|
Self::ErrorIndexingType(_, _)
|
||||||
| Self::ErrorNumericIndexExpr(_)
|
| Self::ErrorNumericIndexExpr(_)
|
||||||
|
@ -35,7 +35,7 @@ fn test_module_sub_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let m2 = m.get_sub_module("universe").unwrap();
|
let m2 = m.get_sub_module("universe").unwrap();
|
||||||
|
|
||||||
assert!(m2.contains_var("answer"));
|
assert!(m2.contains_var("answer"));
|
||||||
assert!(m2.contains_fn(hash_inc));
|
assert!(m2.contains_fn(hash_inc, false));
|
||||||
|
|
||||||
assert_eq!(m2.get_var_value::<INT>("answer").unwrap(), 41);
|
assert_eq!(m2.get_var_value::<INT>("answer").unwrap(), 41);
|
||||||
|
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#![cfg(not(feature = "no_std"))]
|
#![cfg(not(feature = "no_std"))]
|
||||||
#![cfg(not(target_arch = "wasm32"))]
|
#![cfg(not(target_arch = "wasm32"))]
|
||||||
|
|
||||||
use rhai::{Engine, EvalAltResult, INT};
|
use rhai::{Engine, EvalAltResult};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use rhai::FLOAT;
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_float")]
|
||||||
|
use rhai::INT;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_timestamp() -> Result<(), Box<EvalAltResult>> {
|
fn test_timestamp() -> Result<(), Box<EvalAltResult>> {
|
||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user