Add NativeCallContext::call_fn

This commit is contained in:
Stephen Chung 2021-12-18 12:29:04 +08:00
parent 1c1247ac9a
commit fc84600b22
2 changed files with 34 additions and 2 deletions

View File

@ -12,6 +12,11 @@ New features
* Added support for integer _ranges_ via the `..` and `..=` operators. * Added support for integer _ranges_ via the `..` and `..=` operators.
Enhancements
------------
* Added `NativeCallContext::call_fn` to easily call a function.
Deprecated API's Deprecated API's
---------------- ----------------

View File

@ -5,12 +5,14 @@ use crate::ast::{FnAccess, FnCallHashes};
use crate::engine::{EvalState, Imports}; use crate::engine::{EvalState, Imports};
use crate::plugin::PluginFunction; use crate::plugin::PluginFunction;
use crate::tokenizer::{Token, TokenizeState}; use crate::tokenizer::{Token, TokenizeState};
use crate::types::dynamic::Variant;
use crate::{ use crate::{
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, Module, Position, RhaiResult, calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, FuncArgs, Module, Position,
RhaiResult, StaticVec,
}; };
use std::fmt;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{any::type_name, fmt};
/// Trait that maps to `Send + Sync` only under the `sync` feature. /// Trait that maps to `Send + Sync` only under the `sync` feature.
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
@ -225,6 +227,31 @@ impl<'a> NativeCallContext<'a> {
pub const fn namespaces(&self) -> &[&Module] { pub const fn namespaces(&self) -> &[&Module] {
self.lib self.lib
} }
/// Call a function inside the call context with the provided arguments.
#[inline]
pub fn call_fn<T: Variant + Clone>(
&self,
fn_name: impl AsRef<str>,
args: impl FuncArgs,
) -> Result<T, Box<EvalAltResult>> {
let mut arg_values = StaticVec::new_const();
args.parse(&mut arg_values);
let mut args: StaticVec<_> = arg_values.iter_mut().collect();
let result = self.call_fn_raw(fn_name, false, false, &mut args)?;
let typ = self.engine().map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
EvalAltResult::ErrorMismatchOutputType(
self.engine().map_type_name(type_name::<T>()).into(),
typ.into(),
Position::NONE,
)
.into()
})
}
/// Call a function inside the call context. /// Call a function inside the call context.
/// ///
/// If `is_method_call` is [`true`], the first argument is assumed to be the `this` pointer for /// If `is_method_call` is [`true`], the first argument is assumed to be the `this` pointer for