Add support for custom type indexers.

This commit is contained in:
Stephen Chung
2020-05-05 20:38:48 +08:00
parent 798e1df298
commit f081040767
5 changed files with 144 additions and 23 deletions

View File

@@ -15,7 +15,7 @@ Rhai's current features set:
* Easy-to-use language similar to JS+Rust
* Easy integration with Rust [native functions](#working-with-functions) and [types](#custom-types-and-methods),
including [getter/setter](#getters-and-setters)/[methods](#members-and-methods)
including [getters/setters](#getters-and-setters), [methods](#members-and-methods) and [indexers](#indexers)
* Easily [call a script-defined function](#calling-rhai-functions-from-rust) from Rust
* Freely pass variables/constants into a script via an external [`Scope`]
* Fairly efficient (1 million iterations in 0.75 sec on my 5 year old laptop)
@@ -923,6 +923,41 @@ let result = engine.eval::<i64>("let a = new_ts(); a.xyz = 42; a.xyz")?;
println!("Answer: {}", result); // prints 42
```
Indexers
--------
Custom types can also expose an _indexer_ by registering an indexer function.
A custom with an indexer function defined can use the bracket '`[]`' notation to get a property value
(but not update it - indexers are read-only).
```rust
#[derive(Clone)]
struct TestStruct {
fields: Vec<i64>
}
impl TestStruct {
fn get_field(&mut self, index: i64) -> i64 {
self.field
}
fn new() -> Self {
TestStruct { field: vec![1, 2, 42, 4, 5] }
}
}
let engine = Engine::new();
engine.register_type::<TestStruct>();
engine.register_fn("new_ts", TestStruct::new);
engine.register_indexer(TestStruct::get_field);
let result = engine.eval::<i64>("let a = new_ts(); a[2]")?;
println!("Answer: {}", result); // prints 42
```
Needless to say, `register_type`, `register_type_with_name`, `register_get`, `register_set` and `register_get_set`
are not available when the [`no_object`] feature is turned on.