Merge pull request #624 from schungx/master
Deprecate _result registration methods.
This commit is contained in:
commit
56b732d83b
@ -10,11 +10,15 @@ Bug fixes
|
|||||||
* API for registering property getters/setters and indexers to an `Engine` now works with functions that take a first parameter of `NativeCallContext`.
|
* API for registering property getters/setters and indexers to an `Engine` now works with functions that take a first parameter of `NativeCallContext`.
|
||||||
* Missing API function `Module::set_getter_setter_fn` is added.
|
* Missing API function `Module::set_getter_setter_fn` is added.
|
||||||
|
|
||||||
|
Deprecated API
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* All versions of the `Engine::register_XXX_result` API that register a function returning `Result<T, Box<EvalAltResult>>` are now deprecated. The regular, non-`result` versions handle all functions correctly.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Fallible type iterators
|
### Fallible type iterators
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* For very special needs, the ability to register fallible type iterators is added.
|
* For very special needs, the ability to register fallible type iterators is added.
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS
|
|||||||
Ok((engine_expr, export_name, rust_mod_path)) => {
|
Ok((engine_expr, export_name, rust_mod_path)) => {
|
||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
proc_macro::TokenStream::from(quote! {
|
proc_macro::TokenStream::from(quote! {
|
||||||
#engine_expr.register_result_fn(#export_name, #gen_mod_path::dynamic_result_fn)
|
#engine_expr.register_fn(#export_name, #gen_mod_path::dynamic_result_fn)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
//! Trait to build a custom type for use with [`Engine`].
|
//! Trait to build a custom type for use with [`Engine`].
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
|
|
||||||
use crate::{types::dynamic::Variant, Engine, Identifier, RegisterNativeFunction, RhaiResultOf};
|
use crate::{types::dynamic::Variant, Engine, Identifier, RegisterNativeFunction};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
use crate::func::register::Mut;
|
||||||
|
|
||||||
/// Trait to build the API of a custom type for use with an [`Engine`]
|
/// Trait to build the API of a custom type for use with an [`Engine`]
|
||||||
/// (i.e. register the type and its getters, setters, methods, etc.).
|
/// (i.e. register the type and its getters, setters, methods, etc.).
|
||||||
///
|
///
|
||||||
@ -133,17 +136,6 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> {
|
|||||||
self.engine.register_fn(name, method);
|
self.engine.register_fn(name, method);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a custom fallible function.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn with_result_fn<N, A, F, R, S>(&mut self, name: N, method: F) -> &mut Self
|
|
||||||
where
|
|
||||||
N: AsRef<str> + Into<Identifier>,
|
|
||||||
F: RegisterNativeFunction<A, R, RhaiResultOf<S>>,
|
|
||||||
{
|
|
||||||
self.engine.register_result_fn(name, method);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> TypeBuilder<'a, T>
|
impl<'a, T> TypeBuilder<'a, T>
|
||||||
@ -168,67 +160,39 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> {
|
|||||||
///
|
///
|
||||||
/// Not available under `no_object`.
|
/// Not available under `no_object`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_get<V: Variant + Clone>(
|
pub fn with_get<V: Variant + Clone, S>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
get_fn: impl Fn(&mut T) -> V + crate::func::SendSync + 'static,
|
get_fn: impl RegisterNativeFunction<(Mut<T>,), V, S> + crate::func::SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.engine.register_get(name, get_fn);
|
self.engine.register_get(name, get_fn);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a fallible getter function.
|
|
||||||
///
|
|
||||||
/// The function signature must start with `&mut self` and not `&self`.
|
|
||||||
///
|
|
||||||
/// Not available under `no_object`.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn with_get_result<V: Variant + Clone>(
|
|
||||||
&mut self,
|
|
||||||
name: impl AsRef<str>,
|
|
||||||
get_fn: impl Fn(&mut T) -> RhaiResultOf<V> + crate::func::SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
self.engine.register_get_result(name, get_fn);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a setter function.
|
/// Register a setter function.
|
||||||
///
|
///
|
||||||
/// Not available under `no_object`.
|
/// Not available under `no_object`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_set<V: Variant + Clone>(
|
pub fn with_set<V: Variant + Clone, S>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
set_fn: impl Fn(&mut T, V) + crate::func::SendSync + 'static,
|
set_fn: impl RegisterNativeFunction<(Mut<T>, V), (), S> + crate::func::SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.engine.register_set(name, set_fn);
|
self.engine.register_set(name, set_fn);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a fallible setter function.
|
|
||||||
///
|
|
||||||
/// Not available under `no_object`.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn with_set_result<V: Variant + Clone>(
|
|
||||||
&mut self,
|
|
||||||
name: impl AsRef<str>,
|
|
||||||
set_fn: impl Fn(&mut T, V) -> RhaiResultOf<()> + crate::func::SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
self.engine.register_set_result(name, set_fn);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Short-hand for registering both getter and setter functions.
|
/// Short-hand for registering both getter and setter functions.
|
||||||
///
|
///
|
||||||
/// All function signatures must start with `&mut self` and not `&self`.
|
/// All function signatures must start with `&mut self` and not `&self`.
|
||||||
///
|
///
|
||||||
/// Not available under `no_object`.
|
/// Not available under `no_object`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_get_set<V: Variant + Clone>(
|
pub fn with_get_set<V: Variant + Clone, S1, S2>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
get_fn: impl Fn(&mut T) -> V + crate::func::SendSync + 'static,
|
get_fn: impl RegisterNativeFunction<(Mut<T>,), V, S1> + crate::func::SendSync + 'static,
|
||||||
set_fn: impl Fn(&mut T, V) + crate::func::SendSync + 'static,
|
set_fn: impl RegisterNativeFunction<(Mut<T>, V), (), S2> + crate::func::SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.engine.register_get_set(name, get_fn, set_fn);
|
self.engine.register_get_set(name, get_fn, set_fn);
|
||||||
self
|
self
|
||||||
@ -243,60 +207,34 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> {
|
|||||||
///
|
///
|
||||||
/// Not available under both `no_index` and `no_object`.
|
/// Not available under both `no_index` and `no_object`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_indexer_get<X: Variant + Clone, V: Variant + Clone>(
|
pub fn with_indexer_get<X: Variant + Clone, V: Variant + Clone, S>(
|
||||||
&mut self,
|
&mut self,
|
||||||
get_fn: impl Fn(&mut T, X) -> V + crate::func::SendSync + 'static,
|
get_fn: impl RegisterNativeFunction<(Mut<T>, X), V, S> + crate::func::SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.engine.register_indexer_get(get_fn);
|
self.engine.register_indexer_get(get_fn);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register an fallible index getter.
|
|
||||||
///
|
|
||||||
/// The function signature must start with `&mut self` and not `&self`.
|
|
||||||
///
|
|
||||||
/// Not available under both `no_index` and `no_object`.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn with_indexer_get_result<X: Variant + Clone, V: Variant + Clone>(
|
|
||||||
&mut self,
|
|
||||||
get_fn: impl Fn(&mut T, X) -> RhaiResultOf<V> + crate::func::SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
self.engine.register_indexer_get_result(get_fn);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register an index setter.
|
/// Register an index setter.
|
||||||
///
|
///
|
||||||
/// Not available under both `no_index` and `no_object`.
|
/// Not available under both `no_index` and `no_object`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_indexer_set<X: Variant + Clone, V: Variant + Clone>(
|
pub fn with_indexer_set<X: Variant + Clone, V: Variant + Clone, S>(
|
||||||
&mut self,
|
&mut self,
|
||||||
set_fn: impl Fn(&mut T, X, V) + crate::func::SendSync + 'static,
|
set_fn: impl RegisterNativeFunction<(Mut<T>, X, V), (), S> + crate::func::SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.engine.register_indexer_set(set_fn);
|
self.engine.register_indexer_set(set_fn);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register an fallible index setter.
|
|
||||||
///
|
|
||||||
/// Not available under both `no_index` and `no_object`.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn with_indexer_set_result<X: Variant + Clone, V: Variant + Clone>(
|
|
||||||
&mut self,
|
|
||||||
set_fn: impl Fn(&mut T, X, V) -> RhaiResultOf<()> + crate::func::SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
self.engine.register_indexer_set_result(set_fn);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Short-hand for registering both index getter and setter functions.
|
/// Short-hand for registering both index getter and setter functions.
|
||||||
///
|
///
|
||||||
/// Not available under both `no_index` and `no_object`.
|
/// Not available under both `no_index` and `no_object`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_indexer_get_set<X: Variant + Clone, V: Variant + Clone>(
|
pub fn with_indexer_get_set<X: Variant + Clone, V: Variant + Clone, S1, S2>(
|
||||||
&mut self,
|
&mut self,
|
||||||
get_fn: impl Fn(&mut T, X) -> V + crate::func::SendSync + 'static,
|
get_fn: impl RegisterNativeFunction<(Mut<T>, X), V, S1> + crate::func::SendSync + 'static,
|
||||||
set_fn: impl Fn(&mut T, X, V) + crate::func::SendSync + 'static,
|
set_fn: impl RegisterNativeFunction<(Mut<T>, X, V), (), S2> + crate::func::SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.engine.register_indexer_get_set(get_fn, set_fn);
|
self.engine.register_indexer_get_set(get_fn, set_fn);
|
||||||
self
|
self
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
//! Module containing all deprecated API that will be removed in the next major version.
|
//! Module containing all deprecated API that will be removed in the next major version.
|
||||||
|
|
||||||
|
use crate::func::RegisterNativeFunction;
|
||||||
|
use crate::types::dynamic::Variant;
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, Engine, EvalAltResult, FnPtr, ImmutableString, NativeCallContext, Position,
|
Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, NativeCallContext,
|
||||||
RhaiResult, RhaiResultOf, Scope, AST,
|
Position, RhaiResult, RhaiResultOf, Scope, AST,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
use crate::func::register::Mut;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -115,58 +120,6 @@ impl Engine {
|
|||||||
/// This method is deprecated. Use [`run_ast_with_scope`][Engine::run_ast_with_scope] instead.
|
/// This method is deprecated. Use [`run_ast_with_scope`][Engine::run_ast_with_scope] instead.
|
||||||
///
|
///
|
||||||
/// This method will be removed in the next major version.
|
/// This method will be removed in the next major version.
|
||||||
///
|
|
||||||
/// # WARNING - Low Level API
|
|
||||||
///
|
|
||||||
/// This function is very low level.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
|
||||||
/// This is to avoid unnecessarily cloning the arguments.
|
|
||||||
///
|
|
||||||
/// Do not use the arguments after this call. If they are needed afterwards,
|
|
||||||
/// clone them _before_ calling this function.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// # #[cfg(not(feature = "no_function"))]
|
|
||||||
/// # {
|
|
||||||
/// use rhai::{Engine, Scope, Dynamic};
|
|
||||||
///
|
|
||||||
/// let engine = Engine::new();
|
|
||||||
///
|
|
||||||
/// let ast = engine.compile("
|
|
||||||
/// fn add(x, y) { len(x) + y + foo }
|
|
||||||
/// fn add1(x) { len(x) + 1 + foo }
|
|
||||||
/// fn bar() { foo/2 }
|
|
||||||
/// fn action(x) { this += x; } // function using 'this' pointer
|
|
||||||
/// ")?;
|
|
||||||
///
|
|
||||||
/// let mut scope = Scope::new();
|
|
||||||
/// scope.push("foo", 42_i64);
|
|
||||||
///
|
|
||||||
/// // Call the script-defined function
|
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add", None, [ "abc".into(), 123_i64.into() ])?;
|
|
||||||
/// // ^^^^ no 'this' pointer
|
|
||||||
/// assert_eq!(result.cast::<i64>(), 168);
|
|
||||||
///
|
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add1", None, [ "abc".into() ])?;
|
|
||||||
/// assert_eq!(result.cast::<i64>(), 46);
|
|
||||||
///
|
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "bar", None, [])?;
|
|
||||||
/// assert_eq!(result.cast::<i64>(), 21);
|
|
||||||
///
|
|
||||||
/// let mut value: Dynamic = 1_i64.into();
|
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "action", Some(&mut value), [ 41_i64.into() ])?;
|
|
||||||
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
|
||||||
/// assert_eq!(value.as_int().expect("value should be INT"), 42);
|
|
||||||
/// # }
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[deprecated(since = "1.1.0", note = "use `call_fn_raw` instead")]
|
#[deprecated(since = "1.1.0", note = "use `call_fn_raw` instead")]
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -181,6 +134,130 @@ impl Engine {
|
|||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
self.call_fn_raw(scope, ast, eval_ast, true, name, this_ptr, arg_values)
|
self.call_fn_raw(scope, ast, eval_ast, true, name, this_ptr, arg_values)
|
||||||
}
|
}
|
||||||
|
/// Register a custom fallible function with the [`Engine`].
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use [`register_fn`][Engine::register_fn] instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `register_fn` instead")]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn register_result_fn<N, A, F, R, S>(&mut self, name: N, func: F) -> &mut Self
|
||||||
|
where
|
||||||
|
N: AsRef<str> + Into<Identifier>,
|
||||||
|
F: RegisterNativeFunction<A, R, RhaiResultOf<S>>,
|
||||||
|
{
|
||||||
|
self.register_fn(name, func)
|
||||||
|
}
|
||||||
|
/// Register a getter function for a member of a registered type with the [`Engine`].
|
||||||
|
///
|
||||||
|
/// The function signature must start with `&mut self` and not `&self`.
|
||||||
|
///
|
||||||
|
/// Not available under `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use [`register_get`][Engine::register_get] instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `register_get` instead")]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn register_get_result<T: Variant + Clone, V: Variant + Clone, S>(
|
||||||
|
&mut self,
|
||||||
|
name: impl AsRef<str>,
|
||||||
|
get_fn: impl RegisterNativeFunction<(Mut<T>,), V, RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.register_get(name, get_fn)
|
||||||
|
}
|
||||||
|
/// Register a setter function for a member of a registered type with the [`Engine`].
|
||||||
|
///
|
||||||
|
/// Not available under `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use [`register_set`][Engine::register_set] instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `register_set` instead")]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn register_set_result<T: Variant + Clone, V: Variant + Clone, S>(
|
||||||
|
&mut self,
|
||||||
|
name: impl AsRef<str>,
|
||||||
|
set_fn: impl RegisterNativeFunction<(Mut<T>, V), (), RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.register_set(name, set_fn)
|
||||||
|
}
|
||||||
|
/// Register an index getter for a custom type with the [`Engine`].
|
||||||
|
///
|
||||||
|
/// The function signature must start with `&mut self` and not `&self`.
|
||||||
|
///
|
||||||
|
/// Not available under both `no_index` and `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use [`register_indexer_get`][Engine::register_indexer_get] instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the type is [`Array`][crate::Array], [`Map`][crate::Map], [`String`],
|
||||||
|
/// [`ImmutableString`][crate::ImmutableString], `&str` or [`INT`][crate::INT].
|
||||||
|
/// Indexers for arrays, object maps, strings and integers cannot be registered.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `register_indexer_get` instead")]
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn register_indexer_get_result<
|
||||||
|
T: Variant + Clone,
|
||||||
|
X: Variant + Clone,
|
||||||
|
V: Variant + Clone,
|
||||||
|
S,
|
||||||
|
>(
|
||||||
|
&mut self,
|
||||||
|
get_fn: impl RegisterNativeFunction<(Mut<T>, X), V, RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.register_indexer_get(get_fn)
|
||||||
|
}
|
||||||
|
/// Register an index setter for a custom type with the [`Engine`].
|
||||||
|
///
|
||||||
|
/// Not available under both `no_index` and `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use [`register_indexer_set`][Engine::register_indexer_set] instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the type is [`Array`][crate::Array], [`Map`][crate::Map], [`String`],
|
||||||
|
/// [`ImmutableString`][crate::ImmutableString], `&str` or [`INT`][crate::INT].
|
||||||
|
/// Indexers for arrays, object maps, strings and integers cannot be registered.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `register_indexer_set` instead")]
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn register_indexer_set_result<
|
||||||
|
T: Variant + Clone,
|
||||||
|
X: Variant + Clone,
|
||||||
|
V: Variant + Clone,
|
||||||
|
S,
|
||||||
|
>(
|
||||||
|
&mut self,
|
||||||
|
set_fn: impl RegisterNativeFunction<(Mut<T>, X, V), (), RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.register_indexer_set(set_fn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dynamic {
|
impl Dynamic {
|
||||||
@ -217,21 +294,6 @@ impl Dynamic {
|
|||||||
impl NativeCallContext<'_> {
|
impl NativeCallContext<'_> {
|
||||||
/// Call a function inside the call context.
|
/// Call a function inside the call context.
|
||||||
///
|
///
|
||||||
/// # WARNING - Low Level API
|
|
||||||
///
|
|
||||||
/// This function is very low level.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// All arguments may be _consumed_, meaning that they may be replaced by `()`. This is to avoid
|
|
||||||
/// unnecessarily cloning the arguments.
|
|
||||||
///
|
|
||||||
/// Do not use the arguments after this call. If they are needed afterwards, clone them _before_
|
|
||||||
/// calling this function.
|
|
||||||
///
|
|
||||||
/// If `is_method` is [`true`], the first argument is assumed to be passed by reference and is
|
|
||||||
/// not consumed.
|
|
||||||
///
|
|
||||||
/// # Deprecated
|
/// # Deprecated
|
||||||
///
|
///
|
||||||
/// This method is deprecated. Use [`call_fn_raw`][NativeCallContext::call_fn_raw] instead.
|
/// This method is deprecated. Use [`call_fn_raw`][NativeCallContext::call_fn_raw] instead.
|
||||||
@ -285,18 +347,6 @@ impl FnPtr {
|
|||||||
/// [`call_raw`][FnPtr::call_raw] instead.
|
/// [`call_raw`][FnPtr::call_raw] instead.
|
||||||
///
|
///
|
||||||
/// This method will be removed in the next major version.
|
/// This method will be removed in the next major version.
|
||||||
///
|
|
||||||
/// # WARNING - Low Level API
|
|
||||||
///
|
|
||||||
/// This function is very low level.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
|
||||||
/// This is to avoid unnecessarily cloning the arguments.
|
|
||||||
///
|
|
||||||
/// Do not use the arguments after this call. If they are needed afterwards,
|
|
||||||
/// clone them _before_ calling this function.
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "1.3.0",
|
since = "1.3.0",
|
||||||
note = "use `call_within_context` or `call_raw` instead"
|
note = "use `call_within_context` or `call_raw` instead"
|
||||||
@ -352,3 +402,113 @@ impl Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
impl<'a, T: Variant + Clone> crate::TypeBuilder<'a, T> {
|
||||||
|
/// Register a custom fallible function.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use `with_fn` instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `with_fn` instead")]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn with_result_fn<N, A, F, R, S>(&mut self, name: N, method: F) -> &mut Self
|
||||||
|
where
|
||||||
|
N: AsRef<str> + Into<Identifier>,
|
||||||
|
F: RegisterNativeFunction<A, R, RhaiResultOf<S>>,
|
||||||
|
{
|
||||||
|
self.with_fn(name, method)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register a fallible getter function.
|
||||||
|
///
|
||||||
|
/// The function signature must start with `&mut self` and not `&self`.
|
||||||
|
///
|
||||||
|
/// Not available under `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use `with_get` instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `with_get` instead")]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn with_get_result<V: Variant + Clone, S>(
|
||||||
|
&mut self,
|
||||||
|
name: impl AsRef<str>,
|
||||||
|
get_fn: impl RegisterNativeFunction<(Mut<T>,), V, RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.with_get(name, get_fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register a fallible setter function.
|
||||||
|
///
|
||||||
|
/// Not available under `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use `with_set` instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `with_set` instead")]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn with_set_result<V: Variant + Clone, S>(
|
||||||
|
&mut self,
|
||||||
|
name: impl AsRef<str>,
|
||||||
|
set_fn: impl RegisterNativeFunction<(Mut<T>, V), (), RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.with_set(name, set_fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register an fallible index getter.
|
||||||
|
///
|
||||||
|
/// The function signature must start with `&mut self` and not `&self`.
|
||||||
|
///
|
||||||
|
/// Not available under both `no_index` and `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use `with_indexer_get` instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `with_indexer_get` instead")]
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn with_indexer_get_result<X: Variant + Clone, V: Variant + Clone, S>(
|
||||||
|
&mut self,
|
||||||
|
get_fn: impl RegisterNativeFunction<(Mut<T>, X), V, RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.with_indexer_get(get_fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register an fallible index setter.
|
||||||
|
///
|
||||||
|
/// Not available under both `no_index` and `no_object`.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use `with_indexer_set` instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
#[deprecated(since = "1.9.1", note = "use `with_indexer_set` instead")]
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn with_indexer_set_result<X: Variant + Clone, V: Variant + Clone, S>(
|
||||||
|
&mut self,
|
||||||
|
set_fn: impl RegisterNativeFunction<(Mut<T>, X, V), (), RhaiResultOf<S>>
|
||||||
|
+ crate::func::SendSync
|
||||||
|
+ 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.with_indexer_set(set_fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
//! Module that defines the public function/module registration API of [`Engine`].
|
//! Module that defines the public function/module registration API of [`Engine`].
|
||||||
|
|
||||||
use crate::func::register::Mut;
|
|
||||||
use crate::func::{FnCallArgs, RegisterNativeFunction, SendSync};
|
use crate::func::{FnCallArgs, RegisterNativeFunction, SendSync};
|
||||||
use crate::types::dynamic::Variant;
|
use crate::types::dynamic::Variant;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -10,6 +9,9 @@ use std::any::{type_name, TypeId};
|
|||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
use crate::func::register::Mut;
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// Get the global namespace module (which is the fist module in `global_modules`).
|
/// Get the global namespace module (which is the fist module in `global_modules`).
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -88,64 +90,6 @@ impl Engine {
|
|||||||
);
|
);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Register a custom fallible function with the [`Engine`].
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rhai::{Engine, EvalAltResult};
|
|
||||||
///
|
|
||||||
/// // Normal function
|
|
||||||
/// fn div(x: i64, y: i64) -> Result<i64, Box<EvalAltResult>> {
|
|
||||||
/// if y == 0 {
|
|
||||||
/// // '.into()' automatically converts to 'Box<EvalAltResult::ErrorRuntime>'
|
|
||||||
/// Err("division by zero!".into())
|
|
||||||
/// } else {
|
|
||||||
/// Ok(x / y)
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// let mut engine = Engine::new();
|
|
||||||
///
|
|
||||||
/// engine.register_result_fn("div", div);
|
|
||||||
///
|
|
||||||
/// engine.eval::<i64>("div(42, 0)")
|
|
||||||
/// .expect_err("expecting division by zero error!");
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn register_result_fn<N, A, F, R, S>(&mut self, name: N, func: F) -> &mut Self
|
|
||||||
where
|
|
||||||
N: AsRef<str> + Into<Identifier>,
|
|
||||||
F: RegisterNativeFunction<A, R, RhaiResultOf<S>>,
|
|
||||||
{
|
|
||||||
let param_types = F::param_types();
|
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
|
||||||
let param_type_names: crate::StaticVec<_> = F::param_names()
|
|
||||||
.iter()
|
|
||||||
.map(|ty| format!("_: {}", self.format_type_name(ty)))
|
|
||||||
.chain(Some(self.format_type_name(F::return_type_name()).into()))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
|
||||||
let param_type_names: crate::StaticVec<_> =
|
|
||||||
param_type_names.iter().map(String::as_str).collect();
|
|
||||||
#[cfg(feature = "metadata")]
|
|
||||||
let param_type_names = Some(param_type_names.as_ref());
|
|
||||||
|
|
||||||
#[cfg(not(feature = "metadata"))]
|
|
||||||
let param_type_names: Option<&[&str]> = None;
|
|
||||||
|
|
||||||
self.global_namespace_mut().set_fn(
|
|
||||||
name,
|
|
||||||
FnNamespace::Global,
|
|
||||||
FnAccess::Public,
|
|
||||||
param_type_names,
|
|
||||||
param_types,
|
|
||||||
func.into_callable_function(),
|
|
||||||
);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
/// Register a function of the [`Engine`].
|
/// Register a function of the [`Engine`].
|
||||||
///
|
///
|
||||||
/// # WARNING - Low Level API
|
/// # WARNING - Low Level API
|
||||||
@ -363,55 +307,6 @@ impl Engine {
|
|||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.register_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn)
|
self.register_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn)
|
||||||
}
|
}
|
||||||
/// Register a getter function for a member of a registered type with the [`Engine`].
|
|
||||||
///
|
|
||||||
/// The function signature must start with `&mut self` and not `&self`.
|
|
||||||
///
|
|
||||||
/// Not available under `no_object`.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rhai::{Engine, Dynamic, EvalAltResult};
|
|
||||||
///
|
|
||||||
/// #[derive(Clone)]
|
|
||||||
/// struct TestStruct {
|
|
||||||
/// field: i64
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl TestStruct {
|
|
||||||
/// fn new() -> Self {
|
|
||||||
/// Self { field: 1 }
|
|
||||||
/// }
|
|
||||||
/// // Even a getter must start with `&mut self` and not `&self`.
|
|
||||||
/// fn get_field(&mut self) -> Result<i64, Box<EvalAltResult>> {
|
|
||||||
/// Ok(self.field)
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// let mut engine = Engine::new();
|
|
||||||
///
|
|
||||||
/// // Register API for the custom type.
|
|
||||||
/// engine
|
|
||||||
/// .register_type::<TestStruct>()
|
|
||||||
/// .register_fn("new_ts", TestStruct::new)
|
|
||||||
/// // Register a getter on a property (notice it doesn't have to be the same name).
|
|
||||||
/// .register_get_result("xyz", TestStruct::get_field);
|
|
||||||
///
|
|
||||||
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1);
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn register_get_result<T: Variant + Clone, V: Variant + Clone, S>(
|
|
||||||
&mut self,
|
|
||||||
name: impl AsRef<str>,
|
|
||||||
get_fn: impl RegisterNativeFunction<(Mut<T>,), V, RhaiResultOf<S>> + SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
self.register_result_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn)
|
|
||||||
}
|
|
||||||
/// Register a setter function for a member of a registered type with the [`Engine`].
|
/// Register a setter function for a member of a registered type with the [`Engine`].
|
||||||
///
|
///
|
||||||
/// Not available under `no_object`.
|
/// Not available under `no_object`.
|
||||||
@ -462,57 +357,6 @@ impl Engine {
|
|||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.register_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn)
|
self.register_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn)
|
||||||
}
|
}
|
||||||
/// Register a setter function for a member of a registered type with the [`Engine`].
|
|
||||||
///
|
|
||||||
/// Not available under `no_object`.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rhai::{Engine, Dynamic, EvalAltResult};
|
|
||||||
///
|
|
||||||
/// #[derive(Debug, Clone, Eq, PartialEq)]
|
|
||||||
/// struct TestStruct {
|
|
||||||
/// field: i64
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl TestStruct {
|
|
||||||
/// fn new() -> Self {
|
|
||||||
/// Self { field: 1 }
|
|
||||||
/// }
|
|
||||||
/// fn set_field(&mut self, new_val: i64) -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// self.field = new_val;
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// let mut engine = Engine::new();
|
|
||||||
///
|
|
||||||
/// // Register API for the custom type.
|
|
||||||
/// engine
|
|
||||||
/// .register_type::<TestStruct>()
|
|
||||||
/// .register_fn("new_ts", TestStruct::new)
|
|
||||||
/// // Register a setter on a property (notice it doesn't have to be the same name)
|
|
||||||
/// .register_set_result("xyz", TestStruct::set_field);
|
|
||||||
///
|
|
||||||
/// // Notice that, with a getter, there is no way to get the property value
|
|
||||||
/// assert_eq!(
|
|
||||||
/// engine.eval::<TestStruct>("let a = new_ts(); a.xyz = 42; a")?,
|
|
||||||
/// TestStruct { field: 42 }
|
|
||||||
/// );
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn register_set_result<T: Variant + Clone, V: Variant + Clone, S>(
|
|
||||||
&mut self,
|
|
||||||
name: impl AsRef<str>,
|
|
||||||
set_fn: impl RegisterNativeFunction<(Mut<T>, V), (), RhaiResultOf<S>> + SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
self.register_result_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn)
|
|
||||||
}
|
|
||||||
/// Short-hand for registering both getter and setter functions
|
/// Short-hand for registering both getter and setter functions
|
||||||
/// of a registered type with the [`Engine`].
|
/// of a registered type with the [`Engine`].
|
||||||
///
|
///
|
||||||
@ -643,86 +487,6 @@ impl Engine {
|
|||||||
|
|
||||||
self.register_fn(crate::engine::FN_IDX_GET, get_fn)
|
self.register_fn(crate::engine::FN_IDX_GET, get_fn)
|
||||||
}
|
}
|
||||||
/// Register an index getter for a custom type with the [`Engine`].
|
|
||||||
///
|
|
||||||
/// The function signature must start with `&mut self` and not `&self`.
|
|
||||||
///
|
|
||||||
/// Not available under both `no_index` and `no_object`.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the type is [`Array`][crate::Array], [`Map`][crate::Map], [`String`],
|
|
||||||
/// [`ImmutableString`][crate::ImmutableString], `&str` or [`INT`][crate::INT].
|
|
||||||
/// Indexers for arrays, object maps, strings and integers cannot be registered.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rhai::{Engine, Dynamic, EvalAltResult};
|
|
||||||
///
|
|
||||||
/// #[derive(Clone)]
|
|
||||||
/// struct TestStruct {
|
|
||||||
/// fields: Vec<i64>
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl TestStruct {
|
|
||||||
/// fn new() -> Self {
|
|
||||||
/// Self { fields: vec![1, 2, 3, 4, 5] }
|
|
||||||
/// }
|
|
||||||
/// // Even a getter must start with `&mut self` and not `&self`.
|
|
||||||
/// fn get_field(&mut self, index: i64) -> Result<i64, Box<EvalAltResult>> {
|
|
||||||
/// Ok(self.fields[index as usize])
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// let mut engine = Engine::new();
|
|
||||||
///
|
|
||||||
/// // Register API for the custom type.
|
|
||||||
/// # #[cfg(not(feature = "no_object"))]
|
|
||||||
/// engine.register_type::<TestStruct>();
|
|
||||||
///
|
|
||||||
/// engine
|
|
||||||
/// .register_fn("new_ts", TestStruct::new)
|
|
||||||
/// // Register an indexer.
|
|
||||||
/// .register_indexer_get_result(TestStruct::get_field);
|
|
||||||
///
|
|
||||||
/// # #[cfg(not(feature = "no_index"))]
|
|
||||||
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3);
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
|
||||||
#[inline]
|
|
||||||
pub fn register_indexer_get_result<
|
|
||||||
T: Variant + Clone,
|
|
||||||
X: Variant + Clone,
|
|
||||||
V: Variant + Clone,
|
|
||||||
S,
|
|
||||||
>(
|
|
||||||
&mut self,
|
|
||||||
get_fn: impl RegisterNativeFunction<(Mut<T>, X), V, RhaiResultOf<S>> + SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Array>() {
|
|
||||||
panic!("Cannot register indexer for arrays.");
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Map>() {
|
|
||||||
panic!("Cannot register indexer for object maps.");
|
|
||||||
}
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<String>()
|
|
||||||
|| TypeId::of::<T>() == TypeId::of::<&str>()
|
|
||||||
|| TypeId::of::<T>() == TypeId::of::<crate::ImmutableString>()
|
|
||||||
{
|
|
||||||
panic!("Cannot register indexer for strings.");
|
|
||||||
}
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::INT>() {
|
|
||||||
panic!("Cannot register indexer for integers.");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.register_result_fn(crate::engine::FN_IDX_GET, get_fn)
|
|
||||||
}
|
|
||||||
/// Register an index setter for a custom type with the [`Engine`].
|
/// Register an index setter for a custom type with the [`Engine`].
|
||||||
///
|
///
|
||||||
/// Not available under both `no_index` and `no_object`.
|
/// Not available under both `no_index` and `no_object`.
|
||||||
@ -798,87 +562,6 @@ impl Engine {
|
|||||||
|
|
||||||
self.register_fn(crate::engine::FN_IDX_SET, set_fn)
|
self.register_fn(crate::engine::FN_IDX_SET, set_fn)
|
||||||
}
|
}
|
||||||
/// Register an index setter for a custom type with the [`Engine`].
|
|
||||||
///
|
|
||||||
/// Not available under both `no_index` and `no_object`.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the type is [`Array`][crate::Array], [`Map`][crate::Map], [`String`],
|
|
||||||
/// [`ImmutableString`][crate::ImmutableString], `&str` or [`INT`][crate::INT].
|
|
||||||
/// Indexers for arrays, object maps, strings and integers cannot be registered.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rhai::{Engine, Dynamic, EvalAltResult};
|
|
||||||
///
|
|
||||||
/// #[derive(Clone)]
|
|
||||||
/// struct TestStruct {
|
|
||||||
/// fields: Vec<i64>
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl TestStruct {
|
|
||||||
/// fn new() -> Self {
|
|
||||||
/// Self { fields: vec![1, 2, 3, 4, 5] }
|
|
||||||
/// }
|
|
||||||
/// fn set_field(&mut self, index: i64, value: i64) -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// self.fields[index as usize] = value;
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
|
||||||
/// let mut engine = Engine::new();
|
|
||||||
///
|
|
||||||
/// // Register API for the custom type.
|
|
||||||
/// # #[cfg(not(feature = "no_object"))]
|
|
||||||
/// engine.register_type::<TestStruct>();
|
|
||||||
///
|
|
||||||
/// engine
|
|
||||||
/// .register_fn("new_ts", TestStruct::new)
|
|
||||||
/// // Register an indexer.
|
|
||||||
/// .register_indexer_set_result(TestStruct::set_field);
|
|
||||||
///
|
|
||||||
/// # #[cfg(not(feature = "no_index"))]
|
|
||||||
/// let result = engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?;
|
|
||||||
///
|
|
||||||
/// # #[cfg(not(feature = "no_index"))]
|
|
||||||
/// assert_eq!(result.fields[2], 42);
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
|
||||||
#[inline]
|
|
||||||
pub fn register_indexer_set_result<
|
|
||||||
T: Variant + Clone,
|
|
||||||
X: Variant + Clone,
|
|
||||||
V: Variant + Clone,
|
|
||||||
S,
|
|
||||||
>(
|
|
||||||
&mut self,
|
|
||||||
set_fn: impl RegisterNativeFunction<(Mut<T>, X, V), (), RhaiResultOf<S>> + SendSync + 'static,
|
|
||||||
) -> &mut Self {
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Array>() {
|
|
||||||
panic!("Cannot register indexer for arrays.");
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Map>() {
|
|
||||||
panic!("Cannot register indexer for object maps.");
|
|
||||||
}
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<String>()
|
|
||||||
|| TypeId::of::<T>() == TypeId::of::<&str>()
|
|
||||||
|| TypeId::of::<T>() == TypeId::of::<crate::ImmutableString>()
|
|
||||||
{
|
|
||||||
panic!("Cannot register indexer for strings.");
|
|
||||||
}
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::INT>() {
|
|
||||||
panic!("Cannot register indexer for integers.");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.register_result_fn(crate::engine::FN_IDX_SET, set_fn)
|
|
||||||
}
|
|
||||||
/// Short-hand for registering both index getter and setter functions for a custom type with the [`Engine`].
|
/// Short-hand for registering both index getter and setter functions for a custom type with the [`Engine`].
|
||||||
///
|
///
|
||||||
/// Not available under both `no_index` and `no_object`.
|
/// Not available under both `no_index` and `no_object`.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! Module defining external-loaded modules for Rhai.
|
//! Module defining external-loaded modules for Rhai.
|
||||||
|
|
||||||
use crate::ast::FnAccess;
|
use crate::ast::FnAccess;
|
||||||
use crate::func::register::Mut;
|
|
||||||
use crate::func::{
|
use crate::func::{
|
||||||
shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, RegisterNativeFunction,
|
shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, RegisterNativeFunction,
|
||||||
SendSync,
|
SendSync,
|
||||||
@ -21,6 +20,9 @@ use std::{
|
|||||||
ops::{Add, AddAssign},
|
ops::{Add, AddAssign},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
use crate::func::register::Mut;
|
||||||
|
|
||||||
/// A type representing the namespace of a function.
|
/// A type representing the namespace of a function.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
#[cfg_attr(feature = "metadata", derive(serde::Serialize))]
|
#[cfg_attr(feature = "metadata", derive(serde::Serialize))]
|
||||||
@ -586,10 +588,10 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// assert_eq!(module.get_custom_type(name), Some("MyType"));
|
/// assert_eq!(module.get_custom_type(name), Some("MyType"));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_custom_type(&self, key: &str) -> Option<&str> {
|
pub fn get_custom_type(&self, key: &str) -> Option<&str> {
|
||||||
self.custom_types.get(key)
|
self.custom_types.get(key).map(|t| t.display_name.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if this [`Module`] contains no items.
|
/// Returns `true` if this [`Module`] contains no items.
|
||||||
|
@ -3,14 +3,18 @@
|
|||||||
use crate::Identifier;
|
use crate::Identifier;
|
||||||
use std::{any::type_name, collections::BTreeMap, fmt};
|
use std::{any::type_name, collections::BTreeMap, fmt};
|
||||||
|
|
||||||
/// _(internals)_ A custom type.
|
/// _(internals)_ Information for a custom type.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
pub type CustomType = Identifier;
|
#[derive(Debug, Eq, PartialEq, Clone, Hash, Default)]
|
||||||
|
pub struct CustomTypeInfo {
|
||||||
|
/// Friendly display name of the custom type.
|
||||||
|
pub display_name: Identifier,
|
||||||
|
}
|
||||||
|
|
||||||
/// _(internals)_ A collection of custom types.
|
/// _(internals)_ A collection of custom types.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
#[derive(Clone, Hash, Default)]
|
#[derive(Clone, Hash, Default)]
|
||||||
pub struct CustomTypesCollection(BTreeMap<Identifier, CustomType>);
|
pub struct CustomTypesCollection(BTreeMap<Identifier, CustomTypeInfo>);
|
||||||
|
|
||||||
impl fmt::Debug for CustomTypesCollection {
|
impl fmt::Debug for CustomTypesCollection {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
@ -33,21 +37,31 @@ impl CustomTypesCollection {
|
|||||||
/// Register a custom type.
|
/// Register a custom type.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn add(&mut self, type_name: impl Into<Identifier>, name: impl Into<Identifier>) {
|
pub fn add(&mut self, type_name: impl Into<Identifier>, name: impl Into<Identifier>) {
|
||||||
self.add_raw(type_name, name.into());
|
self.add_raw(
|
||||||
|
type_name,
|
||||||
|
CustomTypeInfo {
|
||||||
|
display_name: name.into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/// Register a custom type.
|
/// Register a custom type.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn add_type<T>(&mut self, name: &str) {
|
pub fn add_type<T>(&mut self, name: &str) {
|
||||||
self.add_raw(type_name::<T>(), name.into());
|
self.add_raw(
|
||||||
|
type_name::<T>(),
|
||||||
|
CustomTypeInfo {
|
||||||
|
display_name: name.into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/// Register a custom type.
|
/// Register a custom type.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn add_raw(&mut self, type_name: impl Into<Identifier>, custom_type: CustomType) {
|
pub fn add_raw(&mut self, type_name: impl Into<Identifier>, custom_type: CustomTypeInfo) {
|
||||||
self.0.insert(type_name.into(), custom_type);
|
self.0.insert(type_name.into(), custom_type);
|
||||||
}
|
}
|
||||||
/// Find a custom type.
|
/// Find a custom type.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get(&self, key: &str) -> Option<&str> {
|
pub fn get(&self, key: &str) -> Option<&CustomTypeInfo> {
|
||||||
self.0.get(key).map(CustomType::as_str)
|
self.0.get(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ pub mod interner;
|
|||||||
pub mod parse_error;
|
pub mod parse_error;
|
||||||
pub mod scope;
|
pub mod scope;
|
||||||
|
|
||||||
pub use custom_types::{CustomType, CustomTypesCollection};
|
pub use custom_types::{CustomTypeInfo, CustomTypesCollection};
|
||||||
pub use dynamic::Dynamic;
|
pub use dynamic::Dynamic;
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
pub use dynamic::Instant;
|
pub use dynamic::Instant;
|
||||||
|
@ -66,7 +66,7 @@ fn build_type() -> Result<(), Box<EvalAltResult>> {
|
|||||||
.with_get_set("z", Self::get_z, Self::set_z);
|
.with_get_set("z", Self::get_z, Self::set_z);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
builder.with_indexer_get_result(Self::get_component);
|
builder.with_indexer_get(Self::get_component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ fn test_functions_global_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::ANSWER")
|
if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::ANSWER")
|
||||||
));
|
));
|
||||||
|
|
||||||
engine.register_result_fn(
|
engine.register_fn(
|
||||||
"do_stuff",
|
"do_stuff",
|
||||||
|context: NativeCallContext, callback: rhai::FnPtr| -> Result<INT, _> {
|
|context: NativeCallContext, callback: rhai::FnPtr| -> Result<INT, _> {
|
||||||
callback.call_within_context(&context, ())
|
callback.call_within_context(&context, ())
|
||||||
|
@ -315,11 +315,13 @@ fn test_get_set_indexer() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine
|
engine
|
||||||
.register_type_with_name::<MyMap>("MyMap")
|
.register_type_with_name::<MyMap>("MyMap")
|
||||||
.register_fn("new_map", || MyMap::new())
|
.register_fn("new_map", || MyMap::new())
|
||||||
.register_indexer_get_result(|map: &mut MyMap, index: &str| {
|
.register_indexer_get(
|
||||||
map.get(index).cloned().ok_or_else(|| {
|
|map: &mut MyMap, index: &str| -> Result<_, Box<EvalAltResult>> {
|
||||||
EvalAltResult::ErrorIndexNotFound(index.into(), rhai::Position::NONE).into()
|
map.get(index).cloned().ok_or_else(|| {
|
||||||
})
|
EvalAltResult::ErrorIndexNotFound(index.into(), rhai::Position::NONE).into()
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
.register_indexer_set(|map: &mut MyMap, index: &str, value: INT| {
|
.register_indexer_set(|map: &mut MyMap, index: &str, value: INT| {
|
||||||
map.insert(index.to_string(), value);
|
map.insert(index.to_string(), value);
|
||||||
});
|
});
|
||||||
|
@ -598,7 +598,7 @@ fn test_module_dynamic() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let mut static_modules = rhai::module_resolvers::StaticModuleResolver::new();
|
let mut static_modules = rhai::module_resolvers::StaticModuleResolver::new();
|
||||||
static_modules.insert("test", module);
|
static_modules.insert("test", module);
|
||||||
engine.set_module_resolver(static_modules);
|
engine.set_module_resolver(static_modules);
|
||||||
engine.register_result_fn("test2", test_fn);
|
engine.register_fn("test2", test_fn);
|
||||||
|
|
||||||
assert_eq!(engine.eval::<INT>(r#"test2("test", 38);"#)?, 42);
|
assert_eq!(engine.eval::<INT>(r#"test2("test", 38);"#)?, 42);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user