Change call_fn_dynamic to accept any type that is IntoIterator<Item=Dynamic>.
This commit is contained in:
parent
5275778952
commit
b24fdd7a4d
26
README.md
26
README.md
@ -359,16 +359,14 @@ let result: i64 = engine.call_fn(&mut scope, &ast, "hello", () )?;
|
|||||||
let result: () = engine.call_fn(&mut scope, &ast, "hidden", ())?;
|
let result: () = engine.call_fn(&mut scope, &ast, "hidden", ())?;
|
||||||
```
|
```
|
||||||
|
|
||||||
For more control, construct all arguments as `Dynamic` values and use `Engine::call_fn_dynamic`:
|
For more control, construct all arguments as `Dynamic` values and use `Engine::call_fn_dynamic`, passing it
|
||||||
|
anything that implements `IntoIterator<Item = Dynamic>` (such as a simple `Vec<Dynamic>`):
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let result: Dynamic = engine.call_fn_dynamic(&mut scope, &ast, "hello",
|
let result: Dynamic = engine.call_fn_dynamic(&mut scope, &ast, "hello",
|
||||||
&mut [ String::from("abc").into(), 123_i64.into() ])?;
|
vec![ String::from("abc").into(), 123_i64.into() ])?;
|
||||||
```
|
```
|
||||||
|
|
||||||
However, beware that `Engine::call_fn_dynamic` _consumes_ its arguments, meaning that all arguments passed to it
|
|
||||||
will be replaced by `()` afterwards. To re-use the arguments, clone them beforehand and pass in the clone.
|
|
||||||
|
|
||||||
### Creating Rust anonymous functions from Rhai script
|
### Creating Rust anonymous functions from Rhai script
|
||||||
|
|
||||||
[`Func`]: #creating-rust-anonymous-functions-from-rhai-script
|
[`Func`]: #creating-rust-anonymous-functions-from-rhai-script
|
||||||
@ -738,7 +736,7 @@ use rhai::Dynamic;
|
|||||||
|
|
||||||
let x = (42_i64).into(); // 'into()' works for standard types
|
let x = (42_i64).into(); // 'into()' works for standard types
|
||||||
|
|
||||||
let y = Dynamic::from(String::from("hello!")); // remember &str is not supported by Rhai
|
let y = Dynamic::from("hello!".to_string()); // remember &str is not supported by Rhai
|
||||||
```
|
```
|
||||||
|
|
||||||
Functions registered with the [`Engine`] can be _overloaded_ as long as the _signature_ is unique,
|
Functions registered with the [`Engine`] can be _overloaded_ as long as the _signature_ is unique,
|
||||||
@ -1124,14 +1122,14 @@ not available under [`no_index`].
|
|||||||
To use custom types for `print` and `debug`, or convert its value into a [string], it is necessary that the following
|
To use custom types for `print` and `debug`, or convert its value into a [string], it is necessary that the following
|
||||||
functions be registered (assuming the custom type is `T : Display + Debug`):
|
functions be registered (assuming the custom type is `T : Display + Debug`):
|
||||||
|
|
||||||
| Function | Signature | Typical implementation | Usage |
|
| Function | Signature | Typical implementation | Usage |
|
||||||
| ----------- | ------------------------------------------------ | ------------------------------ | --------------------------------------------------------------------------------------- |
|
| ----------- | ------------------------------------------------ | ------------------------------------- | --------------------------------------------------------------------------------------- |
|
||||||
| `to_string` | `|s: &mut T| -> String` | `s.to_string()` | Converts the custom type into a [string] |
|
| `to_string` | `|s: &mut T| -> ImmutableString` | `s.to_string().into()` | Converts the custom type into a [string] |
|
||||||
| `print` | `|s: &mut T| -> String` | `s.to_string()` | Converts the custom type into a [string] for the [`print`](#print-and-debug) statement |
|
| `print` | `|s: &mut T| -> ImmutableString` | `s.to_string().into()` | Converts the custom type into a [string] for the [`print`](#print-and-debug) statement |
|
||||||
| `debug` | `|s: &mut T| -> String` | `format!("{:?}", s)` | Converts the custom type into a [string] for the [`debug`](#print-and-debug) statement |
|
| `debug` | `|s: &mut T| -> ImmutableString` | `format!("{:?}", s).into()` | Converts the custom type into a [string] for the [`debug`](#print-and-debug) statement |
|
||||||
| `+` | `|s1: ImmutableString, s: T| -> ImmutableString` | `s1 + s` | Append the custom type to another [string], for `print("Answer: " + type);` usage |
|
| `+` | `|s1: ImmutableString, s: T| -> ImmutableString` | `s1 + s` | Append the custom type to another [string], for `print("Answer: " + type);` usage |
|
||||||
| `+` | `|s: T, s2: ImmutableString| -> String` | `s.to_string().push_str(&s2);` | Append another [string] to the custom type, for `print(type + " is the answer");` usage |
|
| `+` | `|s: T, s2: ImmutableString| -> ImmutableString` | `s.to_string().push_str(&s2).into();` | Append another [string] to the custom type, for `print(type + " is the answer");` usage |
|
||||||
| `+=` | `|s1: &mut ImmutableString, s: T|` | `s1 += s.to_string()` | Append the custom type to an existing [string], for `s += type;` usage |
|
| `+=` | `|s1: &mut ImmutableString, s: T|` | `s1 += s.to_string()` | Append the custom type to an existing [string], for `s += type;` usage |
|
||||||
|
|
||||||
`Scope` - Initializing and maintaining state
|
`Scope` - Initializing and maintaining state
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
@ -14,6 +14,7 @@ Breaking changes
|
|||||||
* `Engine::register_indexer` is renamed to `Engine::register_indexer_get`.
|
* `Engine::register_indexer` is renamed to `Engine::register_indexer_get`.
|
||||||
* `Module::set_indexer_fn` is renamed to `Module::set_indexer_get_fn`.
|
* `Module::set_indexer_fn` is renamed to `Module::set_indexer_get_fn`.
|
||||||
* The tuple `ParseError` now exposes the internal fields and the `ParseError::error_type` and `ParseError::position` methods are removed. The first tuple field is the `ParseErrorType` and the second tuple field is the `Position`.
|
* The tuple `ParseError` now exposes the internal fields and the `ParseError::error_type` and `ParseError::position` methods are removed. The first tuple field is the `ParseErrorType` and the second tuple field is the `Position`.
|
||||||
|
* `Engine::call_fn_dynamic` now takes any type that implements `IntoIterator<Item = Dynamic>`.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
34
src/api.rs
34
src/api.rs
@ -1114,7 +1114,7 @@ impl Engine {
|
|||||||
args: A,
|
args: A,
|
||||||
) -> Result<T, Box<EvalAltResult>> {
|
) -> Result<T, Box<EvalAltResult>> {
|
||||||
let mut arg_values = args.into_vec();
|
let mut arg_values = args.into_vec();
|
||||||
let result = self.call_fn_dynamic(scope, ast, name, arg_values.as_mut())?;
|
let result = self.call_fn_dynamic_raw(scope, ast, name, arg_values.as_mut())?;
|
||||||
|
|
||||||
let return_type = self.map_type_name(result.type_name());
|
let return_type = self.map_type_name(result.type_name());
|
||||||
|
|
||||||
@ -1128,13 +1128,6 @@ impl Engine {
|
|||||||
|
|
||||||
/// Call a script function defined in an `AST` with multiple `Dynamic` arguments.
|
/// Call a script function defined in an `AST` with multiple `Dynamic` arguments.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
|
||||||
///
|
|
||||||
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
|
||||||
/// This is to avoid unnecessarily cloning the arguments.
|
|
||||||
/// Do you use the arguments after this call. If you need them afterwards,
|
|
||||||
/// clone them _before_ calling this function.
|
|
||||||
///
|
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -1155,13 +1148,13 @@ impl Engine {
|
|||||||
/// scope.push("foo", 42_i64);
|
/// scope.push("foo", 42_i64);
|
||||||
///
|
///
|
||||||
/// // Call the script-defined function
|
/// // Call the script-defined function
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add", &mut [ String::from("abc").into(), 123_i64.into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add", vec![ String::from("abc").into(), 123_i64.into() ])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 168);
|
/// assert_eq!(result.cast::<i64>(), 168);
|
||||||
///
|
///
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add1", &mut [ String::from("abc").into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add1", vec![ String::from("abc").into() ])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 46);
|
/// assert_eq!(result.cast::<i64>(), 46);
|
||||||
///
|
///
|
||||||
/// let result= engine.call_fn_dynamic(&mut scope, &ast, "bar", &mut [])?;
|
/// let result= engine.call_fn_dynamic(&mut scope, &ast, "bar", vec![])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 21);
|
/// assert_eq!(result.cast::<i64>(), 21);
|
||||||
/// # }
|
/// # }
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@ -1169,6 +1162,25 @@ impl Engine {
|
|||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub fn call_fn_dynamic(
|
pub fn call_fn_dynamic(
|
||||||
|
&self,
|
||||||
|
scope: &mut Scope,
|
||||||
|
ast: &AST,
|
||||||
|
name: &str,
|
||||||
|
arg_values: impl IntoIterator<Item = Dynamic>,
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
let mut arg_values: StaticVec<_> = arg_values.into_iter().collect();
|
||||||
|
self.call_fn_dynamic_raw(scope, ast, name, arg_values.as_mut())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call a script function defined in an `AST` with multiple `Dynamic` arguments.
|
||||||
|
///
|
||||||
|
/// ## WARNING
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
pub(crate) fn call_fn_dynamic_raw(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
ast: &AST,
|
ast: &AST,
|
||||||
|
@ -216,6 +216,15 @@ impl<T> FromIterator<T> for StaticVec<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: 'static> IntoIterator for StaticVec<T> {
|
||||||
|
type Item = T;
|
||||||
|
type IntoIter = Box<dyn Iterator<Item = T>>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> StaticVec<T> {
|
impl<T> StaticVec<T> {
|
||||||
/// Create a new `StaticVec`.
|
/// Create a new `StaticVec`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
Loading…
Reference in New Issue
Block a user