Expand getter/setter/indexer API.
This commit is contained in:
parent
5d908a1153
commit
5e6d5e8e80
@ -4,6 +4,11 @@ Rhai Release Notes
|
|||||||
Version 0.19.0
|
Version 0.19.0
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
New features
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Adds `Engine::register_get_result`, `Engine::register_set_result`, `Engine::register_indexer_get_result`, `Engine::register_indexer_set_result` API.
|
||||||
|
|
||||||
|
|
||||||
Version 0.18.1
|
Version 0.18.1
|
||||||
==============
|
==============
|
||||||
|
208
src/api.rs
208
src/api.rs
@ -18,7 +18,7 @@ use crate::engine::{FN_IDX_GET, FN_IDX_SET};
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::{
|
use crate::{
|
||||||
engine::{make_getter, make_setter, Map},
|
engine::{make_getter, make_setter, Map},
|
||||||
fn_register::RegisterFn,
|
fn_register::{RegisterFn, RegisterResultFn},
|
||||||
token::Token,
|
token::Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -224,6 +224,54 @@ impl Engine {
|
|||||||
self.register_fn(&make_getter(name), callback)
|
self.register_fn(&make_getter(name), callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register a getter function for a member of a registered type with the `Engine`.
|
||||||
|
/// Returns `Result<Dynamic, Box<EvalAltResult>>`.
|
||||||
|
///
|
||||||
|
/// The function signature must start with `&mut self` and not `&self`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};
|
||||||
|
///
|
||||||
|
/// #[derive(Clone)]
|
||||||
|
/// struct TestStruct {
|
||||||
|
/// field: i64
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl TestStruct {
|
||||||
|
/// fn new() -> Self { TestStruct { field: 1 } }
|
||||||
|
///
|
||||||
|
/// // Even a getter must start with `&mut self` and not `&self`.
|
||||||
|
/// fn get_field(&mut self) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
/// Ok(self.field.into())
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||||
|
/// let mut engine = Engine::new();
|
||||||
|
///
|
||||||
|
/// // Register the custom type.
|
||||||
|
/// engine.register_type::<TestStruct>();
|
||||||
|
///
|
||||||
|
/// engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
///
|
||||||
|
/// // Register a getter on a property (notice it doesn't have to be the same name).
|
||||||
|
/// engine.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"))]
|
||||||
|
pub fn register_get_result<T: Variant + Clone>(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
callback: impl Fn(&mut T) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.register_result_fn(&make_getter(name), callback)
|
||||||
|
}
|
||||||
|
|
||||||
/// 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`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -273,6 +321,59 @@ impl Engine {
|
|||||||
self.register_fn(&make_setter(name), callback)
|
self.register_fn(&make_setter(name), callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register a setter function for a member of a registered type with the `Engine`.
|
||||||
|
/// Returns `Result<Dynamic, Box<EvalAltResult>>`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};
|
||||||
|
///
|
||||||
|
/// #[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
/// struct TestStruct {
|
||||||
|
/// field: i64
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl TestStruct {
|
||||||
|
/// fn new() -> Self { TestStruct { field: 1 } }
|
||||||
|
/// fn set_field(&mut self, new_val: i64) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
/// self.field = new_val;
|
||||||
|
/// Ok(().into())
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||||
|
/// let mut engine = Engine::new();
|
||||||
|
///
|
||||||
|
/// // Register the custom type.
|
||||||
|
/// engine.register_type::<TestStruct>();
|
||||||
|
///
|
||||||
|
/// engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
///
|
||||||
|
/// // Register a setter on a property (notice it doesn't have to be the same name)
|
||||||
|
/// engine.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"))]
|
||||||
|
pub fn register_set_result<T, U>(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
callback: impl Fn(&mut T, U) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
|
||||||
|
) -> &mut Self
|
||||||
|
where
|
||||||
|
T: Variant + Clone,
|
||||||
|
U: Variant + Clone,
|
||||||
|
{
|
||||||
|
self.register_result_fn(&make_setter(name), callback)
|
||||||
|
}
|
||||||
|
|
||||||
/// Shorthand for registering both getter and setter functions
|
/// Shorthand for registering both getter and setter functions
|
||||||
/// of a registered type with the `Engine`.
|
/// of a registered type with the `Engine`.
|
||||||
///
|
///
|
||||||
@ -375,6 +476,58 @@ impl Engine {
|
|||||||
self.register_fn(FN_IDX_GET, callback)
|
self.register_fn(FN_IDX_GET, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register an index getter for a registered type with the `Engine`.
|
||||||
|
/// Returns `Result<Dynamic, Box<EvalAltResult>>`.
|
||||||
|
///
|
||||||
|
/// The function signature must start with `&mut self` and not `&self`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};
|
||||||
|
///
|
||||||
|
/// #[derive(Clone)]
|
||||||
|
/// struct TestStruct {
|
||||||
|
/// fields: Vec<i64>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl TestStruct {
|
||||||
|
/// fn new() -> Self { TestStruct { 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<Dynamic, Box<EvalAltResult>> {
|
||||||
|
/// Ok(self.fields[index as usize].into())
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||||
|
/// let mut engine = Engine::new();
|
||||||
|
///
|
||||||
|
/// // Register the custom type.
|
||||||
|
/// engine.register_type::<TestStruct>();
|
||||||
|
///
|
||||||
|
/// engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
///
|
||||||
|
/// // Register an indexer.
|
||||||
|
/// engine.register_indexer_get_result(TestStruct::get_field);
|
||||||
|
///
|
||||||
|
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3);
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
pub fn register_indexer_get_result<T, X>(
|
||||||
|
&mut self,
|
||||||
|
callback: impl Fn(&mut T, X) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
|
||||||
|
) -> &mut Self
|
||||||
|
where
|
||||||
|
T: Variant + Clone,
|
||||||
|
X: Variant + Clone,
|
||||||
|
{
|
||||||
|
self.register_result_fn(FN_IDX_GET, callback)
|
||||||
|
}
|
||||||
|
|
||||||
/// Register an index setter for a registered type with the `Engine`.
|
/// Register an index setter for a registered type with the `Engine`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -424,6 +577,59 @@ impl Engine {
|
|||||||
self.register_fn(FN_IDX_SET, callback)
|
self.register_fn(FN_IDX_SET, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register an index setter for a registered type with the `Engine`.
|
||||||
|
/// Returns `Result<Dynamic, Box<EvalAltResult>>`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};
|
||||||
|
///
|
||||||
|
/// #[derive(Clone)]
|
||||||
|
/// struct TestStruct {
|
||||||
|
/// fields: Vec<i64>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl TestStruct {
|
||||||
|
/// fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
|
||||||
|
/// fn set_field(&mut self, index: i64, value: i64) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
/// self.fields[index as usize] = value;
|
||||||
|
/// Ok(().into())
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||||
|
/// let mut engine = Engine::new();
|
||||||
|
///
|
||||||
|
/// // Register the custom type.
|
||||||
|
/// engine.register_type::<TestStruct>();
|
||||||
|
///
|
||||||
|
/// engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
///
|
||||||
|
/// // Register an indexer.
|
||||||
|
/// engine.register_indexer_set_result(TestStruct::set_field);
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2],
|
||||||
|
/// 42
|
||||||
|
/// );
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
pub fn register_indexer_set_result<T, X, U>(
|
||||||
|
&mut self,
|
||||||
|
callback: impl Fn(&mut T, X, U) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
|
||||||
|
) -> &mut Self
|
||||||
|
where
|
||||||
|
T: Variant + Clone,
|
||||||
|
U: Variant + Clone,
|
||||||
|
X: Variant + Clone,
|
||||||
|
{
|
||||||
|
self.register_result_fn(FN_IDX_SET, callback)
|
||||||
|
}
|
||||||
|
|
||||||
/// Shorthand for register both index getter and setter functions for a registered type with the `Engine`.
|
/// Shorthand for register both index getter and setter functions for a registered type with the `Engine`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
Loading…
Reference in New Issue
Block a user