Make API chainable.
This commit is contained in:
@@ -17,12 +17,12 @@ use rhai::{Engine, RegisterFn};
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
// Register a custom operator called 'foo' and give it
|
||||
// a precedence of 160 (i.e. between +|- and *|/)
|
||||
engine.register_custom_operator("foo", 160).unwrap();
|
||||
|
||||
// Register the implementation of the customer operator as a function
|
||||
engine.register_fn("foo", |x: i64, y: i64| (x * y) - (x + y));
|
||||
// Register a custom operator named 'foo' and give it a precedence of 160
|
||||
// (i.e. between +|- and *|/)
|
||||
// Also register the implementation of the customer operator as a function
|
||||
engine
|
||||
.register_custom_operator("foo", 160).unwrap()
|
||||
.register_fn("foo", |x: i64, y: i64| (x * y) - (x + y));
|
||||
|
||||
// The custom operator can be used in expressions
|
||||
let result = engine.eval_expression::<i64>("1 + 2 * 3 foo 4 - 5 / 6")?;
|
||||
@@ -71,9 +71,9 @@ All custom operators must be _binary_ (i.e. they take two operands).
|
||||
_Unary_ custom operators are not supported.
|
||||
|
||||
```rust
|
||||
engine.register_custom_operator("foo", 160).unwrap();
|
||||
|
||||
engine.register_fn("foo", |x: i64| x * x);
|
||||
engine
|
||||
.register_custom_operator("foo", 160).unwrap()
|
||||
.register_fn("foo", |x: i64| x * x);
|
||||
|
||||
engine.eval::<i64>("1 + 2 * 3 foo 4 - 5 / 6")?; // error: function 'foo (i64, i64)' not found
|
||||
```
|
||||
|
@@ -13,8 +13,9 @@ use rhai::Engine;
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
engine.disable_symbol("if"); // disable the 'if' keyword
|
||||
engine.disable_symbol("+="); // disable the '+=' operator
|
||||
engine
|
||||
.disable_symbol("if") // disable the 'if' keyword
|
||||
.disable_symbol("+="); // disable the '+=' operator
|
||||
|
||||
// The following all return parse errors.
|
||||
|
||||
|
@@ -9,7 +9,7 @@ Support for custom types can be turned off via the [`no_object`] feature.
|
||||
|
||||
```rust
|
||||
use rhai::{Engine, EvalAltResult};
|
||||
use rhai::RegisterFn;
|
||||
use rhai::RegisterFn; // remember 'RegisterFn' is needed
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TestStruct {
|
||||
@@ -28,14 +28,14 @@ impl TestStruct {
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
engine.register_type::<TestStruct>();
|
||||
|
||||
engine.register_fn("update", TestStruct::update);
|
||||
engine.register_fn("new_ts", TestStruct::new);
|
||||
engine
|
||||
.register_type::<TestStruct>() // most API's can be chained up
|
||||
.register_fn("update", TestStruct::update)
|
||||
.register_fn("new_ts", TestStruct::new);
|
||||
|
||||
let result = engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")?;
|
||||
|
||||
println!("result: {}", result.field); // prints 42
|
||||
println!("result: {}", result.field); // prints 42
|
||||
```
|
||||
|
||||
Register a Custom Type
|
||||
@@ -52,7 +52,7 @@ struct TestStruct {
|
||||
}
|
||||
|
||||
impl TestStruct {
|
||||
fn update(&mut self) { // methods take &mut as first parameter
|
||||
fn update(&mut self) { // methods take &mut as first parameter
|
||||
self.field += 41;
|
||||
}
|
||||
|
||||
@@ -75,8 +75,9 @@ using one of the `Engine::register_XXX` API.
|
||||
Below, the `update` and `new` methods are registered using `Engine::register_fn`.
|
||||
|
||||
```rust
|
||||
engine.register_fn("update", TestStruct::update); // registers 'update(&mut TestStruct)'
|
||||
engine.register_fn("new_ts", TestStruct::new); // registers 'new()'
|
||||
engine
|
||||
.register_fn("update", TestStruct::update) // registers 'update(&mut TestStruct)'
|
||||
.register_fn("new_ts", TestStruct::new); // registers 'new()'
|
||||
```
|
||||
|
||||
***Note**: Rhai follows the convention that methods of custom types take a `&mut` first parameter
|
||||
@@ -107,13 +108,13 @@ fn foo(ts: &mut TestStruct) -> i64 {
|
||||
ts.field
|
||||
}
|
||||
|
||||
engine.register_fn("foo", foo); // register a Rust native function
|
||||
engine.register_fn("foo", foo); // register a Rust native function
|
||||
|
||||
let result = engine.eval::<i64>(
|
||||
"let x = new_ts(); x.foo()" // 'foo' can be called like a method on 'x'
|
||||
"let x = new_ts(); x.foo()" // 'foo' can be called like a method on 'x'
|
||||
)?;
|
||||
|
||||
println!("result: {}", result); // prints 1
|
||||
println!("result: {}", result); // prints 1
|
||||
```
|
||||
|
||||
Under [`no_object`], however, the _method_ style of function calls
|
||||
@@ -133,13 +134,17 @@ If `Engine::register_type_with_name` is used to register the custom type
|
||||
with a special "pretty-print" name, [`type_of()`] will return that name instead.
|
||||
|
||||
```rust
|
||||
engine.register_type::<TestStruct>();
|
||||
engine.register_fn("new_ts", TestStruct::new);
|
||||
engine
|
||||
.register_type::<TestStruct>()
|
||||
.register_fn("new_ts", TestStruct::new);
|
||||
|
||||
let x = new_ts();
|
||||
x.type_of() == "path::to::module::TestStruct";
|
||||
|
||||
engine.register_type_with_name::<TestStruct>("Hello");
|
||||
engine.register_fn("new_ts", TestStruct::new);
|
||||
engine
|
||||
.register_type_with_name::<TestStruct>("Hello")
|
||||
.register_fn("new_ts", TestStruct::new);
|
||||
|
||||
let x = new_ts();
|
||||
x.type_of() == "Hello";
|
||||
```
|
||||
|
@@ -31,8 +31,9 @@ fn get_any_value() -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
engine.register_fn("add", add_len);
|
||||
engine.register_fn("add_str", add_len_str);
|
||||
engine
|
||||
.register_fn("add", add_len)
|
||||
.register_fn("add_str", add_len_str);
|
||||
|
||||
let result = engine.eval::<i64>(r#"add(40, "xx")"#)?;
|
||||
|
||||
|
@@ -19,9 +19,10 @@ fn show_it<T: Display>(x: &mut T) {
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
engine.register_fn("print", show_it::<i64>);
|
||||
engine.register_fn("print", show_it::<bool>);
|
||||
engine.register_fn("print", show_it::<ImmutableString>);
|
||||
engine
|
||||
.register_fn("print", show_it::<i64>)
|
||||
.register_fn("print", show_it::<bool>)
|
||||
.register_fn("print", show_it::<ImmutableString>);
|
||||
```
|
||||
|
||||
The above example shows how to register multiple functions
|
||||
|
@@ -30,10 +30,10 @@ impl TestStruct {
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
engine.register_type::<TestStruct>();
|
||||
|
||||
engine.register_get_set("xyz", TestStruct::get_field, TestStruct::set_field);
|
||||
engine.register_fn("new_ts", TestStruct::new);
|
||||
engine
|
||||
.register_type::<TestStruct>()
|
||||
.register_get_set("xyz", TestStruct::get_field, TestStruct::set_field)
|
||||
.register_fn("new_ts", TestStruct::new);
|
||||
|
||||
// Return result can be 'String' - Rhai will automatically convert it from 'ImmutableString'
|
||||
let result = engine.eval::<String>(r#"let a = new_ts(); a.xyz = "42"; a.xyz"#)?;
|
||||
|
@@ -38,8 +38,9 @@ engine.register_type::<TestStruct>();
|
||||
engine.register_fn("new_ts", TestStruct::new);
|
||||
|
||||
// Shorthand: engine.register_indexer_get_set(TestStruct::get_field, TestStruct::set_field);
|
||||
engine.register_indexer_get(TestStruct::get_field);
|
||||
engine.register_indexer_set(TestStruct::set_field);
|
||||
engine
|
||||
.register_indexer_get(TestStruct::get_field)
|
||||
.register_indexer_set(TestStruct::set_field);
|
||||
|
||||
let result = engine.eval::<i64>("let a = new_ts(); a[2] = 42; a[2]")?;
|
||||
|
||||
|
@@ -15,3 +15,4 @@ A number of other configuration options are available from the `Engine` to fine-
|
||||
| `set_max_string_size` | [`unchecked`] | Set the maximum length (in UTF-8 bytes) for [strings]. See [maximum length of strings]. |
|
||||
| `set_max_array_size` | [`unchecked`], [`no_index`] | Set the maximum size for [arrays]. See [maximum size of arrays]. |
|
||||
| `set_max_map_size` | [`unchecked`], [`no_object`] | Set the maximum number of properties for [object maps]. See [maximum size of object maps]. |
|
||||
| `disable_symbol` | | Disable a certain keyword or operator. See [disable keywords and operators]. |
|
||||
|
@@ -28,11 +28,11 @@ let mut scope = Scope::new();
|
||||
// Then push (i.e. add) some initialized variables into the state.
|
||||
// Remember the system number types in Rhai are i64 (i32 if 'only_i32') ond f64.
|
||||
// Better stick to them or it gets hard working with the script.
|
||||
scope.push("y", 42_i64);
|
||||
scope.push("z", 999_i64);
|
||||
|
||||
// 'set_value' adds a variable when one doesn't exist
|
||||
scope.set_value("s", "hello, world!".to_string()); // remember to use 'String', not '&str'
|
||||
scope
|
||||
.push("y", 42_i64)
|
||||
.push("z", 999_i64)
|
||||
.set_value("s", "hello, world!".to_string()); //'set_value' adds a variable when one doesn't exist
|
||||
// remember to use 'String', not '&str'
|
||||
|
||||
// First invocation
|
||||
engine.eval_with_scope::<()>(&mut scope, r"
|
||||
|
@@ -11,9 +11,10 @@ fn get_len1(s: String) -> i64 { s.len() as i64 } // <- Rhai will not
|
||||
fn get_len2(s: &str) -> i64 { s.len() as i64 } // <- Rhai finds this function fine
|
||||
fn get_len3(s: ImmutableString) -> i64 { s.len() as i64 } // <- the above is equivalent to this
|
||||
|
||||
engine.register_fn("len1", get_len1);
|
||||
engine.register_fn("len2", get_len2);
|
||||
engine.register_fn("len3", get_len3);
|
||||
engine
|
||||
.register_fn("len1", get_len1)
|
||||
.register_fn("len2", get_len2)
|
||||
.register_fn("len3", get_len3);
|
||||
|
||||
let len = engine.eval::<i64>("x.len1()")?; // error: function 'len1 (&str | ImmutableString)' not found
|
||||
let len = engine.eval::<i64>("x.len2()")?; // works fine
|
||||
|
Reference in New Issue
Block a user