Merge branch 'master' into plugins
This commit is contained in:
@@ -3,11 +3,12 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::engine::{calc_fn_spec, Engine, FnCallArgs};
|
||||
use crate::engine::{Engine, FnCallArgs};
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::utils::calc_fn_spec;
|
||||
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, string::ToString};
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::ToString};
|
||||
|
||||
/// A trait to register custom plugins with the `Engine`.
|
||||
///
|
||||
@@ -167,16 +168,19 @@ pub trait Plugin {
|
||||
pub struct Mut<T>(T);
|
||||
//pub struct Ref<T>(T);
|
||||
|
||||
/// Identity dereferencing function.
|
||||
/// Dereference into &mut.
|
||||
#[inline]
|
||||
pub fn identity<T>(data: &mut T) -> &mut T {
|
||||
data
|
||||
pub fn by_ref<T: Clone + 'static>(data: &mut Dynamic) -> &mut T {
|
||||
// Directly cast the &mut Dynamic into &mut T to access the underlying data.
|
||||
data.downcast_mut::<T>().unwrap()
|
||||
}
|
||||
|
||||
/// Clone dereferencing function.
|
||||
/// Dereference into value.
|
||||
#[inline]
|
||||
pub fn cloned<T: Clone>(data: &mut T) -> T {
|
||||
data.clone()
|
||||
pub fn by_value<T: Clone + 'static>(data: &mut Dynamic) -> T {
|
||||
// We consume the argument and then replace it with () - the argument is not supposed to be used again.
|
||||
// This way, we avoid having to clone the argument again, because it is already a clone when passed here.
|
||||
mem::take(data).cast::<T>()
|
||||
}
|
||||
|
||||
#[cfg(feature = "plugins")]
|
||||
@@ -194,7 +198,7 @@ macro_rules! count_args {
|
||||
|
||||
/// This macro creates a closure wrapping a registered function.
|
||||
macro_rules! make_func {
|
||||
($fn_name:ident : $fn:ident : $map:expr ; $($par:ident => $clone:expr),*) => {
|
||||
($fn_name:ident : $fn:ident : $map:expr ; $($par:ident => $convert:expr),*) => {
|
||||
// ^ function name
|
||||
// ^ function pointer
|
||||
// ^ result mapping function
|
||||
@@ -212,14 +216,16 @@ macro_rules! make_func {
|
||||
#[allow(unused_variables, unused_mut)]
|
||||
let mut drain = args.iter_mut();
|
||||
$(
|
||||
// Downcast every element, return in case of a type mismatch
|
||||
let $par: &mut $par = drain.next().unwrap().downcast_mut().unwrap();
|
||||
// Downcast every element, panic in case of a type mismatch (which shouldn't happen).
|
||||
// Call the user-supplied function using ($convert) to access it either by value or by reference.
|
||||
let $par = ($convert)(drain.next().unwrap());
|
||||
)*
|
||||
|
||||
// Call the user-supplied function using ($clone) to
|
||||
// potentially clone the value, otherwise pass the reference.
|
||||
let r = $fn($(($clone)($par)),*);
|
||||
$map(r, pos)
|
||||
// Call the function with each parameter value
|
||||
let r = $fn($($par),*);
|
||||
|
||||
// Map the result
|
||||
$map(r, pos)
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -318,18 +324,17 @@ macro_rules! def_register {
|
||||
//def_register!(imp_pop $($par => $mark => $param),*);
|
||||
};
|
||||
($p0:ident $(, $p:ident)*) => {
|
||||
def_register!(imp $p0 => $p0 => $p0 => cloned $(, $p => $p => $p => cloned)*);
|
||||
def_register!(imp $p0 => Mut<$p0> => &mut $p0 => identity $(, $p => $p => $p => cloned)*);
|
||||
def_register!(imp $p0 => $p0 => $p0 => by_value $(, $p => $p => $p => by_value)*);
|
||||
def_register!(imp $p0 => Mut<$p0> => &mut $p0 => by_ref $(, $p => $p => $p => by_value)*);
|
||||
// handle the first parameter ^ first parameter passed through
|
||||
// ^ others passed by value (cloned)
|
||||
// ^ others passed by value (by_value)
|
||||
|
||||
// Currently does not support first argument which is a reference, as there will be
|
||||
// conflicting implementations since &T: Any and T: Any cannot be distinguished
|
||||
//def_register!(imp $p0 => Ref<$p0> => &$p0 => identity $(, $p => $p => $p => Clone::clone)*);
|
||||
//def_register!(imp $p0 => Ref<$p0> => &$p0 => by_ref $(, $p => $p => $p => by_value)*);
|
||||
|
||||
def_register!($($p),*);
|
||||
};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
def_register!(A, B, C, D, E, F, G, H, J, K, L, M, N, P, Q, R, S, T, U, V);
|
||||
|
Reference in New Issue
Block a user