diff --git a/CHANGELOG.md b/CHANGELOG.md index d9aecc83..a17f951c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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`. * 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>` are now deprecated. The regular, non-`result` versions handle all functions correctly. + New features ------------ -Fallible type iterators ------------------------ +### Fallible type iterators * For very special needs, the ability to register fallible type iterators is added. diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 915b6741..22291c4f 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -303,7 +303,7 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS Ok((engine_expr, export_name, rust_mod_path)) => { let gen_mod_path = crate::register::generated_module_path(&rust_mod_path); 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(), diff --git a/src/api/build_type.rs b/src/api/build_type.rs index 7b54fadf..d03c634c 100644 --- a/src/api/build_type.rs +++ b/src/api/build_type.rs @@ -1,7 +1,8 @@ //! Trait to build a custom type for use with [`Engine`]. #![allow(deprecated)] -use crate::{types::dynamic::Variant, Engine, Identifier, RegisterNativeFunction, RhaiResultOf}; +use crate::func::register::Mut; +use crate::{types::dynamic::Variant, Engine, Identifier, RegisterNativeFunction}; use std::marker::PhantomData; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -133,17 +134,6 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { self.engine.register_fn(name, method); self } - - /// Register a custom fallible function. - #[inline(always)] - pub fn with_result_fn(&mut self, name: N, method: F) -> &mut Self - where - N: AsRef + Into, - F: RegisterNativeFunction>, - { - self.engine.register_result_fn(name, method); - self - } } impl<'a, T> TypeBuilder<'a, T> @@ -168,67 +158,39 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// Not available under `no_object`. #[inline(always)] - pub fn with_get( + pub fn with_get( &mut self, name: impl AsRef, - get_fn: impl Fn(&mut T) -> V + crate::func::SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut,), V, S> + crate::func::SendSync + 'static, ) -> &mut Self { self.engine.register_get(name, get_fn); 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( - &mut self, - name: impl AsRef, - get_fn: impl Fn(&mut T) -> RhaiResultOf + crate::func::SendSync + 'static, - ) -> &mut Self { - self.engine.register_get_result(name, get_fn); - self - } - /// Register a setter function. /// /// Not available under `no_object`. #[inline(always)] - pub fn with_set( + pub fn with_set( &mut self, name: impl AsRef, - set_fn: impl Fn(&mut T, V) + crate::func::SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, V), (), S> + crate::func::SendSync + 'static, ) -> &mut Self { self.engine.register_set(name, set_fn); self } - /// Register a fallible setter function. - /// - /// Not available under `no_object`. - #[inline(always)] - pub fn with_set_result( - &mut self, - name: impl AsRef, - 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. /// /// All function signatures must start with `&mut self` and not `&self`. /// /// Not available under `no_object`. #[inline(always)] - pub fn with_get_set( + pub fn with_get_set( &mut self, name: impl AsRef, - get_fn: impl Fn(&mut T) -> V + crate::func::SendSync + 'static, - set_fn: impl Fn(&mut T, V) + crate::func::SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut,), V, S1> + crate::func::SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, V), (), S2> + crate::func::SendSync + 'static, ) -> &mut Self { self.engine.register_get_set(name, get_fn, set_fn); self @@ -243,60 +205,34 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// Not available under both `no_index` and `no_object`. #[inline(always)] - pub fn with_indexer_get( + pub fn with_indexer_get( &mut self, - get_fn: impl Fn(&mut T, X) -> V + crate::func::SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut, X), V, S> + crate::func::SendSync + 'static, ) -> &mut Self { self.engine.register_indexer_get(get_fn); 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( - &mut self, - get_fn: impl Fn(&mut T, X) -> RhaiResultOf + crate::func::SendSync + 'static, - ) -> &mut Self { - self.engine.register_indexer_get_result(get_fn); - self - } - /// Register an index setter. /// /// Not available under both `no_index` and `no_object`. #[inline(always)] - pub fn with_indexer_set( + pub fn with_indexer_set( &mut self, - set_fn: impl Fn(&mut T, X, V) + crate::func::SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, X, V), (), S> + crate::func::SendSync + 'static, ) -> &mut Self { self.engine.register_indexer_set(set_fn); self } - /// Register an fallible index setter. - /// - /// Not available under both `no_index` and `no_object`. - #[inline(always)] - pub fn with_indexer_set_result( - &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. /// /// Not available under both `no_index` and `no_object`. #[inline(always)] - pub fn with_indexer_get_set( + pub fn with_indexer_get_set( &mut self, - get_fn: impl Fn(&mut T, X) -> V + crate::func::SendSync + 'static, - set_fn: impl Fn(&mut T, X, V) + crate::func::SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut, X), V, S1> + crate::func::SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, X, V), (), S2> + crate::func::SendSync + 'static, ) -> &mut Self { self.engine.register_indexer_get_set(get_fn, set_fn); self diff --git a/src/api/deprecated.rs b/src/api/deprecated.rs index 208c3f2a..c12effbf 100644 --- a/src/api/deprecated.rs +++ b/src/api/deprecated.rs @@ -1,8 +1,11 @@ //! Module containing all deprecated API that will be removed in the next major version. +use crate::func::register::Mut; +use crate::func::{RegisterNativeFunction, SendSync}; +use crate::types::dynamic::Variant; use crate::{ - Dynamic, Engine, EvalAltResult, FnPtr, ImmutableString, NativeCallContext, Position, - RhaiResult, RhaiResultOf, Scope, AST, + Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, NativeCallContext, + Position, RhaiResult, RhaiResultOf, Scope, AST, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -115,58 +118,6 @@ impl Engine { /// 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. - /// - /// # 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> { - /// # #[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::(), 168); - /// - /// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add1", None, [ "abc".into() ])?; - /// assert_eq!(result.cast::(), 46); - /// - /// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "bar", None, [])?; - /// assert_eq!(result.cast::(), 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")] #[cfg(not(feature = "no_function"))] #[inline(always)] @@ -181,6 +132,122 @@ impl Engine { ) -> RhaiResult { 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(&mut self, name: N, func: F) -> &mut Self + where + N: AsRef + Into, + F: RegisterNativeFunction>, + { + 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( + &mut self, + name: impl AsRef, + get_fn: impl RegisterNativeFunction<(Mut,), V, RhaiResultOf> + 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( + &mut self, + name: impl AsRef, + set_fn: impl RegisterNativeFunction<(Mut, V), (), RhaiResultOf> + 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, X), V, RhaiResultOf> + 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, X, V), (), RhaiResultOf> + SendSync + 'static, + ) -> &mut Self { + self.register_indexer_set(set_fn) + } } impl Dynamic { @@ -217,21 +284,6 @@ impl Dynamic { impl NativeCallContext<'_> { /// 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 /// /// This method is deprecated. Use [`call_fn_raw`][NativeCallContext::call_fn_raw] instead. @@ -285,18 +337,6 @@ impl FnPtr { /// [`call_raw`][FnPtr::call_raw] instead. /// /// 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( since = "1.3.0", note = "use `call_within_context` or `call_raw` instead" @@ -352,3 +392,109 @@ 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(&mut self, name: N, method: F) -> &mut Self + where + N: AsRef + Into, + F: RegisterNativeFunction>, + { + 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")] + #[inline(always)] + pub fn with_get_result( + &mut self, + name: impl AsRef, + get_fn: impl RegisterNativeFunction<(Mut,), V, RhaiResultOf> + + 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")] + #[inline(always)] + pub fn with_set_result( + &mut self, + name: impl AsRef, + set_fn: impl RegisterNativeFunction<(Mut, V), (), RhaiResultOf> + + 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")] + #[inline(always)] + pub fn with_indexer_get_result( + &mut self, + get_fn: impl RegisterNativeFunction<(Mut, X), V, RhaiResultOf> + + 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")] + #[inline(always)] + pub fn with_indexer_set_result( + &mut self, + set_fn: impl RegisterNativeFunction<(Mut, X, V), (), RhaiResultOf> + + crate::func::SendSync + + 'static, + ) -> &mut Self { + self.with_indexer_set(set_fn) + } +} diff --git a/src/api/register.rs b/src/api/register.rs index 5625773d..a2f9a56a 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -88,64 +88,6 @@ impl Engine { ); self } - /// Register a custom fallible function with the [`Engine`]. - /// - /// # Example - /// - /// ``` - /// use rhai::{Engine, EvalAltResult}; - /// - /// // Normal function - /// fn div(x: i64, y: i64) -> Result> { - /// if y == 0 { - /// // '.into()' automatically converts to 'Box' - /// Err("division by zero!".into()) - /// } else { - /// Ok(x / y) - /// } - /// } - /// - /// let mut engine = Engine::new(); - /// - /// engine.register_result_fn("div", div); - /// - /// engine.eval::("div(42, 0)") - /// .expect_err("expecting division by zero error!"); - /// ``` - #[inline] - pub fn register_result_fn(&mut self, name: N, func: F) -> &mut Self - where - N: AsRef + Into, - F: RegisterNativeFunction>, - { - 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`]. /// /// # WARNING - Low Level API @@ -363,55 +305,6 @@ impl Engine { ) -> &mut Self { 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> { - /// Ok(self.field) - /// } - /// } - /// - /// # fn main() -> Result<(), Box> { - /// let mut engine = Engine::new(); - /// - /// // Register API for the custom type. - /// engine - /// .register_type::() - /// .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::("let a = new_ts(); a.xyz")?, 1); - /// # Ok(()) - /// # } - /// ``` - #[cfg(not(feature = "no_object"))] - #[inline(always)] - pub fn register_get_result( - &mut self, - name: impl AsRef, - get_fn: impl RegisterNativeFunction<(Mut,), V, RhaiResultOf> + 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`]. /// /// Not available under `no_object`. @@ -462,57 +355,6 @@ impl Engine { ) -> &mut Self { 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> { - /// self.field = new_val; - /// Ok(()) - /// } - /// } - /// - /// # fn main() -> Result<(), Box> { - /// let mut engine = Engine::new(); - /// - /// // Register API for the custom type. - /// engine - /// .register_type::() - /// .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::("let a = new_ts(); a.xyz = 42; a")?, - /// TestStruct { field: 42 } - /// ); - /// # Ok(()) - /// # } - /// ``` - #[cfg(not(feature = "no_object"))] - #[inline(always)] - pub fn register_set_result( - &mut self, - name: impl AsRef, - set_fn: impl RegisterNativeFunction<(Mut, V), (), RhaiResultOf> + 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 /// of a registered type with the [`Engine`]. /// @@ -643,86 +485,6 @@ impl Engine { 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 - /// } - /// - /// 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> { - /// Ok(self.fields[index as usize]) - /// } - /// } - /// - /// # fn main() -> Result<(), Box> { - /// let mut engine = Engine::new(); - /// - /// // Register API for the custom type. - /// # #[cfg(not(feature = "no_object"))] - /// engine.register_type::(); - /// - /// 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::("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, X), V, RhaiResultOf> + SendSync + 'static, - ) -> &mut Self { - #[cfg(not(feature = "no_index"))] - if TypeId::of::() == TypeId::of::() { - panic!("Cannot register indexer for arrays."); - } - #[cfg(not(feature = "no_object"))] - if TypeId::of::() == TypeId::of::() { - panic!("Cannot register indexer for object maps."); - } - if TypeId::of::() == TypeId::of::() - || TypeId::of::() == TypeId::of::<&str>() - || TypeId::of::() == TypeId::of::() - { - panic!("Cannot register indexer for strings."); - } - if TypeId::of::() == TypeId::of::() { - 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`]. /// /// Not available under both `no_index` and `no_object`. @@ -798,87 +560,6 @@ impl Engine { 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 - /// } - /// - /// impl TestStruct { - /// fn new() -> Self { - /// Self { fields: vec![1, 2, 3, 4, 5] } - /// } - /// fn set_field(&mut self, index: i64, value: i64) -> Result<(), Box> { - /// self.fields[index as usize] = value; - /// Ok(()) - /// } - /// } - /// - /// # fn main() -> Result<(), Box> { - /// let mut engine = Engine::new(); - /// - /// // Register API for the custom type. - /// # #[cfg(not(feature = "no_object"))] - /// engine.register_type::(); - /// - /// 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::("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, X, V), (), RhaiResultOf> + SendSync + 'static, - ) -> &mut Self { - #[cfg(not(feature = "no_index"))] - if TypeId::of::() == TypeId::of::() { - panic!("Cannot register indexer for arrays."); - } - #[cfg(not(feature = "no_object"))] - if TypeId::of::() == TypeId::of::() { - panic!("Cannot register indexer for object maps."); - } - if TypeId::of::() == TypeId::of::() - || TypeId::of::() == TypeId::of::<&str>() - || TypeId::of::() == TypeId::of::() - { - panic!("Cannot register indexer for strings."); - } - if TypeId::of::() == TypeId::of::() { - 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`]. /// /// Not available under both `no_index` and `no_object`. diff --git a/tests/build_type.rs b/tests/build_type.rs index 6d21bb9d..9fbcc1af 100644 --- a/tests/build_type.rs +++ b/tests/build_type.rs @@ -66,7 +66,7 @@ fn build_type() -> Result<(), Box> { .with_get_set("z", Self::get_z, Self::set_z); #[cfg(not(feature = "no_index"))] - builder.with_indexer_get_result(Self::get_component); + builder.with_indexer_get(Self::get_component); } } diff --git a/tests/functions.rs b/tests/functions.rs index dddb835a..8e4a7f36 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -97,7 +97,7 @@ fn test_functions_global_module() -> Result<(), Box> { if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::ANSWER") )); - engine.register_result_fn( + engine.register_fn( "do_stuff", |context: NativeCallContext, callback: rhai::FnPtr| -> Result { callback.call_within_context(&context, ()) diff --git a/tests/get_set.rs b/tests/get_set.rs index d9065952..af1416a6 100644 --- a/tests/get_set.rs +++ b/tests/get_set.rs @@ -315,11 +315,13 @@ fn test_get_set_indexer() -> Result<(), Box> { engine .register_type_with_name::("MyMap") .register_fn("new_map", || MyMap::new()) - .register_indexer_get_result(|map: &mut MyMap, index: &str| { - map.get(index).cloned().ok_or_else(|| { - EvalAltResult::ErrorIndexNotFound(index.into(), rhai::Position::NONE).into() - }) - }) + .register_indexer_get( + |map: &mut MyMap, index: &str| -> Result<_, Box> { + 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| { map.insert(index.to_string(), value); }); diff --git a/tests/modules.rs b/tests/modules.rs index a781be3f..87bc2b76 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -598,7 +598,7 @@ fn test_module_dynamic() -> Result<(), Box> { let mut static_modules = rhai::module_resolvers::StaticModuleResolver::new(); static_modules.insert("test", module); engine.set_module_resolver(static_modules); - engine.register_result_fn("test2", test_fn); + engine.register_fn("test2", test_fn); assert_eq!(engine.eval::(r#"test2("test", 38);"#)?, 42);