Update docs.

This commit is contained in:
Stephen Chung 2020-10-19 14:26:15 +08:00
parent d68c951795
commit c8c4ca21ad
18 changed files with 181 additions and 152 deletions

View File

@ -7,10 +7,13 @@ Rhai - Embedded Scripting for Rust
[![crates.io](https://img.shields.io/crates/v/rhai.svg)](https://crates.io/crates/rhai/)
[![crates.io](https://img.shields.io/crates/d/rhai)](https://crates.io/crates/rhai/)
[![API Docs](https://docs.rs/rhai/badge.svg)](https://docs.rs/rhai/)
[![chat](https://img.shields.io/discord/767611025456889857.svg?logo=discord)](https://discord.gg/yZMKAQ)
[![Reddit](https://img.shields.io/reddit/subreddit-subscribers/Rhai)](https://www.reddit.com/r/Rhai)
Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way
to add scripting to any application.
Supported targets and builds
---------------------------
@ -19,6 +22,7 @@ Supported targets and builds
* `no-std`
* Minimum Rust version 1.45
Standard features
-----------------
@ -41,13 +45,15 @@ Standard features
* Serialization/deserialization support via [serde](https://crates.io/crates/serde) (requires the `serde` feature).
* Support for [minimal builds](https://schungx.github.io/rhai/start/builds/minimal.html) by excluding unneeded language [features](https://schungx.github.io/rhai/start/features.html).
Protection against attacks
--------------------------
Protected against attacks
-------------------------
* Sand-boxed - the scripting engine, if declared immutable, cannot mutate the containing environment unless [explicitly permitted](https://schungx.github.io/rhai/patterns/control.html).
* Rugged - protected against malicious attacks (such as [stack-overflow](https://schungx.github.io/rhai/safety/max-call-stack.html), [over-sized data](https://schungx.github.io/rhai/safety/max-string-size.html), and [runaway scripts](https://schungx.github.io/rhai/safety/max-operations.html) etc.) that may come from untrusted third-party user-land scripts.
* Track script evaluation [progress](https://schungx.github.io/rhai/safety/progress.html) and manually terminate a script run.
For those who actually want their own language
---------------------------------------------
@ -56,6 +62,7 @@ For those who actually want their own language
* Define [custom operators](https://schungx.github.io/rhai/engine/custom-op.html).
* Extend the language with [custom syntax](https://schungx.github.io/rhai/engine/custom-syntax.html).
Documentation
-------------
@ -65,12 +72,14 @@ To build _The Book_, first install [`mdbook`](https://github.com/rust-lang/mdBoo
and [`mdbook-tera`](https://github.com/avitex/mdbook-tera) (for templating).
Running `mdbook build` builds it.
Playground
----------
An [Online Playground](https://alvinhochun.github.io/rhai-demo/) is available with syntax-highlighting editor.
Scripts can be evaluated directly from the editor.
License
-------

View File

@ -36,8 +36,8 @@ The Rhai Scripting Language
4. [Register a Fallible Rust Function](rust/fallible.md)
6. [Override a Built-in Function](rust/override.md)
7. [Operator Overloading](rust/operators.md)
8. [Register a Custom Type and its Methods](rust/custom.md)
1. [Getters and Setters](rust/getters-setters.md)
8. [Register any Rust Type and its Methods](rust/custom.md)
1. [Property Getters and Setters](rust/getters-setters.md)
2. [Indexers](rust/indexers.md)
3. [Disable Custom Types](rust/disable-custom.md)
4. [Printing Custom Types](rust/print-custom.md)

View File

@ -3,7 +3,9 @@ Related Resources
{{#include ../links.md}}
Other online documentation resources for Rhai:
Other Online Resources for Rhai
------------------------------
* [`crates.io`](https://crates.io/crates/rhai) - Rhai crate
@ -13,7 +15,13 @@ Other online documentation resources for Rhai:
* [Online Playground][playground] - Run scripts directly from editor
Other cool projects to check out:
* [Discord Chat](https://discord.gg/yZMKAQ) - Rhai channel
* [Reddit](https://www.reddit.com/r/Rhai) - Rhai community
Other Cool Projects
-------------------
* [ChaiScript](http://chaiscript.com) - A strong inspiration for Rhai. An embedded scripting language for C++.

BIN
doc/src/images/rhai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -8,7 +8,7 @@ Prelude
-------
When using the plugins system, the entire `rhai::plugin` module must be imported as a prelude
because code generated will these imports.
because code generated will need these imports.
```rust
use rhai::plugin::*;

View File

@ -1,124 +1,118 @@
Register a Custom Type and its Methods
Register any Rust Type and its Methods
=====================================
{{#include ../links.md}}
Rhai works seamlessly with _any_ complex Rust type. The type can be registered with the `Engine`, as below.
Free Typing
-----------
Rhai works seamlessly with _any_ Rust type. The type can be _anything_; it does not
have any prerequisites other than being `Clone`. It does not need to implement
any other trait or use any custom `#[derive]`.
This allows Rhai to be integrated into an existing code base with as little plumbing
as possible, usually silently and seamlessly. External types that are not defined
within the same crate (and thus cannot implement special Rhai traits or
use special `#[derive]`) can also be used easily with Rhai.
The reason why it is termed a _custom_ type throughout this documentation is that
Rhai natively supports a number of data types with fast, internal treatment (see
the list of [standard types]). Any type outside of this list is considered _custom_.
Any type not supported natively by Rhai is stored as a Rust _trait object_, with no
restrictions other than being `Clone` (plus `Send + Sync` under the [`sync`] feature).
It runs slightly slower than natively-supported types as it does not have built-in,
optimized implementations for commonly-used functions, but for all other purposes has
no difference.
Support for custom types can be turned off via the [`no_object`] feature.
```rust
use rhai::{Engine, EvalAltResult};
use rhai::RegisterFn; // remember 'RegisterFn' is needed
#[derive(Clone)]
struct TestStruct {
field: i64
}
Register a Custom Type and its Methods
-------------------------------------
impl TestStruct {
fn update(&mut self) {
self.field += 41;
}
Any custom type must implement the `Clone` trait as this allows the [`Engine`] to pass by value.
fn new() -> Self {
TestStruct { field: 1 }
}
}
let mut engine = Engine::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
```
Register a Custom Type
---------------------
A custom type must implement `Clone` as this allows the [`Engine`] to pass by value.
If the [`sync`] feature is used, it must also be `Send + Sync`.
Notice that the custom type needs to be _registered_ using `Engine::register_type`
or `Engine::register_type_with_name`.
To use native methods on custom types in Rhai scripts, it is common to register an API
for the type using one of the `Engine::register_XXX` functions.
```rust
use rhai::{Engine, EvalAltResult};
use rhai::RegisterFn; // remember 'RegisterFn' is needed
#[derive(Clone)]
struct TestStruct {
field: i64
}
impl TestStruct {
fn update(&mut self) { // methods take &mut as first parameter
self.field += 41;
fn new() -> Self {
Self { field: 1 }
}
fn new() -> Self {
TestStruct { field: 1 }
fn update(&mut self, x: i64) { // methods take &mut as first parameter
self.field += x;
}
}
let mut engine = Engine::new();
engine.register_type::<TestStruct>();
```
Methods on the Custom Type
-------------------------
To use native custom types, methods and functions in Rhai scripts, simply register them
using one of the `Engine::register_XXX` API.
Below, the `update` and `new` methods are registered using `Engine::register_fn`.
```rust
// Most Engine API's can be chained up.
engine
.register_fn("update", TestStruct::update) // registers 'update(&mut TestStruct)'
.register_fn("new_ts", TestStruct::new); // registers 'new()'
.register_type::<TestStruct>() // register custom type
.register_fn("new_ts", TestStruct::new)
.register_fn("update", TestStruct::update);
// Cast result back to custom type.
let result = engine.eval::<TestStruct>(
r"
let x = new_ts(); // calls 'TestStruct::new'
x.update(41); // calls 'TestStruct::update'
x // 'x' holds a 'TestStruct'
"
)?;
println!("result: {}", result.field); // prints 42
```
***Note**: Rhai follows the convention that methods of custom types take a `&mut` first parameter
so that invoking methods can update the types. All other parameters in Rhai are passed by value (i.e. clones).*
Rhai follows the convention that methods of custom types take a `&mut` first parameter
to that type, so that invoking methods can always update it.
All other parameters in Rhai are passed by value (i.e. clones).
**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
Use the Custom Type in Scripts
-----------------------------
The custom type is then ready for use in scripts. Scripts can see the functions and methods registered earlier.
Get the evaluation result back out just as before, this time casting to the custom type:
```rust
let result = engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")?;
println!("result: {}", result.field); // prints 42
```
Method-Call Style vs. Function-Call Style
----------------------------------------
Any function with a first argument that is a `&mut` reference can be used
as method calls because internally they are the same thing: methods on a type is
implemented as a functions taking a `&mut` first argument.
This design is similar to Rust.
```rust
fn foo(ts: &mut TestStruct) -> i64 {
ts.field
impl TestStruct {
fn foo(&mut self) -> i64 {
self.field
}
}
engine.register_fn("foo", foo); // register a Rust native function
engine.register_fn("foo", TestStruct::foo);
let result = engine.eval::<i64>(
"let x = new_ts(); x.foo()" // 'foo' can be called like a method on 'x'
r"
let x = new_ts();
foo(x); // normal call to 'foo'
x.foo() // 'foo' can also be called like a method on 'x'
"
)?;
println!("result: {}", result); // prints 1
@ -128,8 +122,9 @@ Under [`no_object`], however, the _method_ style of function calls
(i.e. calling a function as an object-method) is no longer supported.
```rust
// Below is a syntax error under 'no_object' because 'clear' cannot be called in method style.
let result = engine.eval::<()>("let x = [1, 2, 3]; x.clear()")?;
// Below is a syntax error under 'no_object'.
let result = engine.eval("let x = [1, 2, 3]; x.clear();")?;
// ^ cannot call in method style under 'no_object'
```
@ -143,18 +138,16 @@ with a special "pretty-print" name, [`type_of()`] will return that name instead.
```rust
engine
.register_type::<TestStruct>()
.register_fn("new_ts", TestStruct::new);
.register_type::<TestStruct1>()
.register_fn("new_ts1", TestStruct1::new)
.register_type_with_name::<TestStruct2>("MyType")
.register_fn("new_ts2", TestStruct2::new);
let x = new_ts();
x.type_of() == "path::to::module::TestStruct";
let ts1_type = engine.eval::<String>(r#"let x = new_ts1(); x.type_of()"#)?;
let ts2_type = engine.eval::<String>(r#"let x = new_ts2(); x.type_of()"#)?;
engine
.register_type_with_name::<TestStruct>("Hello")
.register_fn("new_ts", TestStruct::new);
let x = new_ts();
x.type_of() == "Hello";
println!("{}", ts1_type); // prints 'path::to::TestStruct'
println!("{}", ts1_type); // prints 'MyType'
```
@ -190,7 +183,9 @@ the `==` operator must be registered for the custom type:
```rust
// Assume 'TestStruct' implements `PartialEq`
engine.register_fn("==", |item1: &mut TestStruct, item2: TestStruct| item1 == item2);
engine.register_fn("==",
|item1: &mut TestStruct, item2: TestStruct| item1 == &item2
);
// Then this works in Rhai:
let item = new_ts(); // construct a new 'TestStruct'

View File

@ -1,29 +1,32 @@
Custom Type Getters and Setters
==============================
Custom Type Property Getters and Setters
=======================================
{{#include ../links.md}}
A custom type can also expose members by registering `get` and/or `set` functions.
A [custom type] can also expose properties by registering `get` and/or `set` functions.
Getters and setters each take a `&mut` reference to the first parameter.
Getters and setters are disabled when the [`no_object`] feature is used.
| `Engine` API | Description | Return Value of Function |
| --------------------- | ------------------------------------------------- | :-----------------------------------: |
| `register_get` | register a getter | _any_ `T: Clone` |
| `register_set` | register a setter | _none_ |
| `register_get_set` | short-hand to register both a getter and a setter | _none_ |
| `register_get_result` | register a getter | `Result<Dynamic, Box<EvalAltResult>>` |
| `register_set_result` | register a setter | `Result<(), Box<EvalAltResult>>` |
| `Engine` API | Function signature(s)<br/>(`T: Clone` = custom type,<br/>`V: Clone` = data type) | Can mutate `T`? |
| --------------------- | -------------------------------------------------------------------------------- | :----------------------------: |
| `register_get` | `Fn(&mut T) -> V` | yes, but not advised |
| `register_set` | `Fn(&mut T, V)` | yes |
| `register_get_set` | getter: `Fn(&mut T) -> V`</br>setter: `Fn(&mut T, V)` | yes, but not advised in getter |
| `register_get_result` | `Fn(&mut T) -> Result<Dynamic, Box<EvalAltResult>>` | yes, but not advised |
| `register_set_result` | `Fn(&mut T, V) -> Result<(), Box<EvalAltResult>>` | yes |
By convention, property getters are not supposed to mutate the [custom type], although there is nothing
that prevents this mutation.
Cannot Override Object Maps
--------------------------
Getters and setters are only intended for [custom types].
Property getters and setters are mainly intended for [custom types].
Any getter or setter function registered for [object maps] is simply ignored because
Any getter or setter function registered for [object maps] is simply _ignored_ because
the get/set calls will be interpreted as properties on the [object maps].
@ -47,7 +50,7 @@ impl TestStruct {
}
fn new() -> Self {
TestStruct { field: "hello" }
Self { field: "hello" }
}
}

View File

@ -3,23 +3,30 @@ Custom Type Indexers
{{#include ../links.md}}
A custom type can also expose an _indexer_ by registering an indexer function.
A [custom type] can also expose an _indexer_ by registering an indexer function.
A custom type with an indexer function defined can use the bracket notation to get a property value:
A [custom type] with an indexer function defined can use the bracket notation to get a property value:
> _object_ `[` _index_ `]`
Like getters and setters, indexers take a `&mut` reference to the first parameter.
Like property [getters/setters], indexers take a `&mut` reference to the first parameter.
They also take an additional parameter of any type that serves as the _index_ within brackets.
Indexers are disabled when the [`no_index`] feature is used.
| `Engine` API | Description | Return Value of Function |
| ----------------------------- | -------------------------------------------------------- | :-----------------------------------: |
| `register_indexer_get` | register an index getter | _any_ `T: Clone` |
| `register_indexer_set` | register an index setter | _none_ |
| `register_indexer_get_set` | short-hand to register both an index getter and a setter | _none_ |
| `register_indexer_get_result` | register an index getter | `Result<Dynamic, Box<EvalAltResult>>` |
| `register_indexer_set_result` | register an index setter | `Result<(), Box<EvalAltResult>>` |
| `Engine` API | Function signature(s)<br/>(`T: Clone` = custom type,<br/>`X: Clone` = index type,<br/>`V: Clone` = data type) | Can mutate `T`? |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------- | :----------------------------: |
| `register_indexer_get` | `Fn(&mut T, X) -> V` | yes, but not advised |
| `register_indexer_set` | `Fn(&mut T, X, V)` | yes |
| `register_indexer_get_set` | getter: `Fn(&mut T, X) -> V`<br/>setter: `Fn(&mut T, X, V)` | yes, but not advised in getter |
| `register_indexer_get_result` | `Fn(&mut T, X) -> Result<Dynamic, Box<EvalAltResult>>` | yes, but not advised |
| `register_indexer_set_result` | `Fn(&mut T, X, V) -> Result<(), Box<EvalAltResult>>` | yes |
By convention, index getters are not supposed to mutate the [custom type], although there is nothing
that prevents this mutation.
**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
Cannot Override Arrays, Object Maps and Strings
@ -42,15 +49,15 @@ struct TestStruct {
impl TestStruct {
// Remember &mut must be used even for getters
fn get_field(&mut self, index: i64) -> i64 {
self.fields[index as usize]
fn get_field(&mut self, index: String) -> i64 {
self.fields[index.len()]
}
fn set_field(&mut self, index: i64, value: i64) {
self.fields[index as usize] = value
fn set_field(&mut self, index: String, value: i64) {
self.fields[index.len()] = value
}
fn new() -> Self {
TestStruct { fields: vec![1, 2, 3, 4, 5] }
Self { fields: vec![1, 2, 3, 4, 5] }
}
}
@ -63,9 +70,13 @@ 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]")?;
let result = engine.eval::<i64>(
r#"
let a = new_ts();
a["xyz"] = 42; // these indexers use strings
a["xyz"] // as the index type
"#
)?;
println!("Answer: {}", result); // prints 42
```
**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**

View File

@ -65,7 +65,7 @@ The function signature passed to `Engine::register_raw_fn` takes the following f
where:
* `T: Variant + Clone` - return type of the function.
* `T: Clone` - return type of the function.
* `context: NativeCallContext` - the current _native call context_, which exposes the following:

View File

@ -11,7 +11,7 @@ impl TestStruct {
}
fn new() -> Self {
TestStruct { x: 1 }
Self { x: 1 }
}
}

View File

@ -11,7 +11,7 @@ impl TestStruct {
}
fn new() -> Self {
TestStruct { x: 1 }
Self { x: 1 }
}
}

View File

@ -88,7 +88,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { field: 1 } }
/// fn update(&mut self, offset: i64) { self.field += offset; }
/// }
///
@ -130,7 +130,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { field: 1 } }
/// }
///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
@ -200,7 +200,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { field: 1 } }
/// // Even a getter must start with `&mut self` and not `&self`.
/// fn get_field(&mut self) -> i64 { self.field }
/// }
@ -252,7 +252,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { 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())
@ -295,7 +295,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { field: 1 } }
/// fn set_field(&mut self, new_val: i64) { self.field = new_val; }
/// }
///
@ -348,7 +348,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { field: 1 } }
/// fn set_field(&mut self, new_val: i64) -> Result<(), Box<EvalAltResult>> {
/// self.field = new_val;
/// Ok(())
@ -386,8 +386,7 @@ impl Engine {
U: Variant + Clone,
{
self.register_result_fn(&make_setter(name), move |obj: &mut T, value: U| {
callback(obj, value)?;
Ok(().into())
callback(obj, value).map(Into::into)
})
}
@ -405,7 +404,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { Self { field: 1 } }
/// // Even a getter must start with `&mut self` and not `&self`.
/// fn get_field(&mut self) -> i64 { self.field }
/// fn set_field(&mut self, new_val: i64) { self.field = new_val; }
@ -462,7 +461,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
/// 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) -> i64 { self.fields[index as usize] }
/// }
@ -534,7 +533,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
/// 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<Dynamic, Box<EvalAltResult>> {
/// Ok(self.fields[index as usize].into())
@ -600,7 +599,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
/// fn new() -> Self { Self { fields: vec![1, 2, 3, 4, 5] } }
/// fn set_field(&mut self, index: i64, value: i64) { self.fields[index as usize] = value; }
/// }
///
@ -672,7 +671,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
/// fn new() -> Self { Self { fields: vec![1, 2, 3, 4, 5] } }
/// fn set_field(&mut self, index: i64, value: i64) -> Result<(), Box<EvalAltResult>> {
/// self.fields[index as usize] = value;
/// Ok(())
@ -724,8 +723,7 @@ impl Engine {
}
self.register_result_fn(FN_IDX_SET, move |obj: &mut T, index: X, value: U| {
callback(obj, index, value)?;
Ok(().into())
callback(obj, index, value).map(Into::into)
})
}
@ -745,7 +743,7 @@ impl Engine {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
/// 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) -> i64 { self.fields[index as usize] }
/// fn set_field(&mut self, index: i64, value: i64) { self.fields[index as usize] = value; }

View File

@ -934,7 +934,9 @@ impl Engine {
level,
)
.map_err(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(_, _) => {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.ends_with("]=") =>
{
EvalAltResult::ErrorIndexingType(
self.map_type_name(val_type_name).into(),
Position::none(),
@ -1381,9 +1383,12 @@ impl Engine {
)
.map(|(v, _)| v.into())
.map_err(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(_, _) => Box::new(
EvalAltResult::ErrorIndexingType(type_name.into(), Position::none()),
),
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) if fn_sig.ends_with("]") => {
Box::new(EvalAltResult::ErrorIndexingType(
type_name.into(),
Position::none(),
))
}
_ => err,
})
}

View File

@ -84,7 +84,7 @@ fn test_array_with_structs() -> Result<(), Box<EvalAltResult>> {
}
fn new() -> Self {
TestStruct { x: 1 }
Self { x: 1 }
}
}

View File

@ -51,7 +51,7 @@ fn test_struct_with_float() -> Result<(), Box<EvalAltResult>> {
}
fn new() -> Self {
TestStruct { x: 1.0 }
Self { x: 1.0 }
}
}

View File

@ -25,7 +25,7 @@ fn test_get_set() -> Result<(), Box<EvalAltResult>> {
}
fn new() -> Self {
TestStruct {
Self {
x: 1,
y: 0,
array: vec![1, 2, 3, 4, 5],

View File

@ -15,7 +15,7 @@ fn test_method_call() -> Result<(), Box<EvalAltResult>> {
}
fn new() -> Self {
TestStruct { x: 1 }
Self { x: 1 }
}
}

View File

@ -20,7 +20,7 @@ fn test_mismatched_op_custom_type() {
impl TestStruct {
fn new() -> Self {
TestStruct { x: 1 }
Self { x: 1 }
}
}