diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d7ad9fad..f5b7f4e33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Deprecated API's ---------------- * `ParseErrorType::MalformedCallExpr` and `ParseErrorType::MalformedInExpr` are deprecated and will be removed in the next major version. +* `Module::get_custom_type` is deprecated in favor of `Module::get_custom_type_display_by_name` and other new methods. New features ------------ @@ -43,7 +44,7 @@ New features * Added `Engine::max_variables` and `Engine::set_max_variables` to limit the maximum number of variables allowed within a scope at any time. This is to guard against defining a huge number of variables containing large data just beyond individual data size limits. When `max_variables` is exceeded a new error, `ErrorTooManyVariables`, is returned. * Added `zip` function for arrays. * Added `on_print` and `on_debug` definitions for `TypeBuilder`. -* Doc-comments are now included in custom type definitions within plugin modules. They can be accessed via `Module::get_custom_type_comments`. These doc-comments for custom types are also exported in JSON via `Engine::gen_fn_metadata_to_json`. +* Doc-comments are now included in custom type definitions within plugin modules. They can be accessed via `Module::get_custom_type_raw`. These doc-comments for custom types are also exported in JSON via `Engine::gen_fn_metadata_to_json`. Enhancements ------------ @@ -51,6 +52,7 @@ Enhancements * [`once_cell`](https://crates.io/crates/once_cell) is used in `std` environments instead of the home-brew `SusLock` which is removed. * Originally, unit tests use the `?` operator liberally to simplify code. However, this causes the loss of proper line numbers when a test fails, making it difficult to identify the exact location of the failure. This is now fixed by changing to `unwrap()`. * Many inlined collections are turned back into `Vec` because they are not transient and do not appear to improve performance. Using `Vec` seems to be yield better performance as it probably enables more compiler optimizations. +* General code clean-up to remove optimizations tricks that are not obviously beneficial in favor of clearer code. Version 1.15.1 diff --git a/src/api/build_type.rs b/src/api/build_type.rs index ae83def26..5b5e77a66 100644 --- a/src/api/build_type.rs +++ b/src/api/build_type.rs @@ -98,7 +98,6 @@ impl Engine { /// /// To define a pretty-print name, call [`with_name`][`TypeBuilder::with_name`], /// to use [`Engine::register_type_with_name`] instead. -#[must_use] pub struct TypeBuilder<'a, T: Variant + Clone> { engine: &'a mut Engine, name: Option<&'static str>, diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 3206755d3..bba9a2586 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -14,7 +14,6 @@ use std::{any::type_name, mem}; /// Options for calling a script-defined function via [`Engine::call_fn_with_options`]. #[derive(Debug, Hash)] #[non_exhaustive] -#[must_use] pub struct CallFnOptions<'t> { /// A value for binding to the `this` pointer (if any). Default [`None`]. pub this_ptr: Option<&'t mut Dynamic>, @@ -36,6 +35,7 @@ impl Default for CallFnOptions<'_> { impl<'a> CallFnOptions<'a> { /// Create a default [`CallFnOptions`]. #[inline(always)] + #[must_use] pub fn new() -> Self { Self { this_ptr: None, @@ -46,24 +46,28 @@ impl<'a> CallFnOptions<'a> { } /// Bind to the `this` pointer. #[inline(always)] + #[must_use] pub fn bind_this_ptr(mut self, value: &'a mut Dynamic) -> Self { self.this_ptr = Some(value); self } /// Set the custom state of this evaluation run (if any). #[inline(always)] + #[must_use] pub fn with_tag(mut self, value: impl Variant + Clone) -> Self { self.tag = Some(Dynamic::from(value)); self } /// Set whether to evaluate the [`AST`] to load necessary modules before calling the function. #[inline(always)] + #[must_use] pub const fn eval_ast(mut self, value: bool) -> Self { self.eval_ast = value; self } /// Set whether to rewind the [`Scope`] after the function call. #[inline(always)] + #[must_use] pub const fn rewind_scope(mut self, value: bool) -> Self { self.rewind_scope = value; self diff --git a/src/api/deprecated.rs b/src/api/deprecated.rs index 1baf0cf74..5241d0074 100644 --- a/src/api/deprecated.rs +++ b/src/api/deprecated.rs @@ -25,7 +25,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`run_file`][Engine::run_file] instead. + /// This method is deprecated. + /// Use [`run_file`][Engine::run_file] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `run_file` instead")] @@ -43,7 +44,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`run_file_with_scope`][Engine::run_file_with_scope] instead. + /// This method is deprecated. + /// Use [`run_file_with_scope`][Engine::run_file_with_scope] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `run_file_with_scope` instead")] @@ -59,7 +61,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`run`][Engine::run] instead. + /// This method is deprecated. + /// Use [`run`][Engine::run] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `run` instead")] @@ -73,7 +76,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`run_with_scope`][Engine::run_with_scope] instead. + /// This method is deprecated. + /// Use [`run_with_scope`][Engine::run_with_scope] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `run_with_scope` instead")] @@ -87,7 +91,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`run_ast`][Engine::run_ast] instead. + /// This method is deprecated. + /// Use [`run_ast`][Engine::run_ast] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `run_ast` instead")] @@ -101,7 +106,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`run_ast_with_scope`][Engine::run_ast_with_scope] instead. + /// This method is deprecated. + /// Use [`run_ast_with_scope`][Engine::run_ast_with_scope] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `run_ast_with_scope` instead")] @@ -118,7 +124,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`call_fn_with_options`][Engine::call_fn_with_options] instead. + /// This method is deprecated. + /// Use [`call_fn_with_options`][Engine::call_fn_with_options] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `call_fn_with_options` instead")] @@ -142,7 +149,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`call_fn_with_options`][Engine::call_fn_with_options] instead. + /// This method is deprecated. + /// Use [`call_fn_with_options`][Engine::call_fn_with_options] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.12.0", note = "use `call_fn_with_options` instead")] @@ -181,7 +189,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`register_fn`][Engine::register_fn] instead. + /// This method is deprecated. + /// Use [`register_fn`][Engine::register_fn] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `register_fn` instead")] @@ -201,7 +210,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`register_get`][Engine::register_get] instead. + /// This method is deprecated. + /// Use [`register_get`][Engine::register_get] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `register_get` instead")] @@ -220,7 +230,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`register_set`][Engine::register_set] instead. + /// This method is deprecated. + /// Use [`register_set`][Engine::register_set] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `register_set` instead")] @@ -241,7 +252,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`register_indexer_get`][Engine::register_indexer_get] instead. + /// This method is deprecated. + /// Use [`register_indexer_get`][Engine::register_indexer_get] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `register_indexer_get` instead")] @@ -264,7 +276,8 @@ impl Engine { /// /// # Deprecated /// - /// This method is deprecated. Use [`register_indexer_set`][Engine::register_indexer_set] instead. + /// This method is deprecated. + /// Use [`register_indexer_set`][Engine::register_indexer_set] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `register_indexer_set` instead")] @@ -340,7 +353,8 @@ impl Dynamic { /// /// # Deprecated /// - /// This method is deprecated. Use [`into_string`][Dynamic::into_string] instead. + /// This method is deprecated. + /// Use [`into_string`][Dynamic::into_string] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `into_string` instead")] @@ -354,7 +368,8 @@ impl Dynamic { /// /// # Deprecated /// - /// This method is deprecated. Use [`into_immutable_string`][Dynamic::into_immutable_string] instead. + /// This method is deprecated. + /// Use [`into_immutable_string`][Dynamic::into_immutable_string] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.1.0", note = "use `into_immutable_string` instead")] @@ -389,7 +404,8 @@ impl NativeCallContext<'_> { /// /// # Deprecated /// - /// This method is deprecated. Use [`call_fn_raw`][NativeCallContext::call_fn_raw] instead. + /// This method is deprecated. + /// Use [`call_fn_raw`][NativeCallContext::call_fn_raw] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.2.0", note = "use `call_fn_raw` instead")] @@ -418,7 +434,8 @@ impl FnPtr { /// /// # Deprecated /// - /// This method is deprecated. Use [`curry().len()`][`FnPtr::curry`] instead. + /// This method is deprecated. + /// Use [`curry().len()`][`FnPtr::curry`] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.8.0", note = "use `curry().len()` instead")] @@ -436,8 +453,8 @@ impl FnPtr { /// /// # Deprecated /// - /// This method is deprecated. Use [`call_within_context`][FnPtr::call_within_context] or - /// [`call_raw`][FnPtr::call_raw] instead. + /// This method is deprecated. + /// Use [`call_within_context`][FnPtr::call_within_context] or [`call_raw`][FnPtr::call_raw] instead. /// /// This method will be removed in the next major version. #[deprecated( @@ -461,7 +478,8 @@ impl crate::Expression<'_> { /// /// # Deprecated /// - /// This method is deprecated. Use [`get_string_value`][crate::Expression::get_string_value] instead. + /// This method is deprecated. + /// Use [`get_string_value`][crate::Expression::get_string_value] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.4.0", note = "use `get_string_value` instead")] @@ -481,7 +499,8 @@ impl Position { /// /// # Deprecated /// - /// This function is deprecated. Use [`new`][Position::new] (which panics when `line` is zero) instead. + /// This function is deprecated. + /// Use [`new`][Position::new] (which panics when `line` is zero) instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.6.0", note = "use `new` instead")] @@ -502,7 +521,8 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// # Deprecated /// - /// This method is deprecated. Use `with_fn` instead. + /// This method is deprecated. + /// Use [`with_fn`][`TypeBuilder::with_fn`] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `with_fn` instead")] @@ -528,7 +548,8 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// # Deprecated /// - /// This method is deprecated. Use `with_get` instead. + /// This method is deprecated. + /// Use [`with_get`][`TypeBuilder::with_get`] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `with_get` instead")] @@ -548,7 +569,8 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// # Deprecated /// - /// This method is deprecated. Use `with_set` instead. + /// This method is deprecated. + /// Use [`with_set`][`TypeBuilder::with_set`] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `with_set` instead")] @@ -570,7 +592,8 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// # Deprecated /// - /// This method is deprecated. Use `with_indexer_get` instead. + /// This method is deprecated. + /// Use [`with_indexer_get`][`TypeBuilder::with_indexer_get`] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `with_indexer_get` instead")] @@ -589,7 +612,8 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// /// # Deprecated /// - /// This method is deprecated. Use `with_indexer_set` instead. + /// This method is deprecated. + /// Use [`with_indexer_set`][`TypeBuilder::with_indexer_set`] instead. /// /// This method will be removed in the next major version. #[deprecated(since = "1.9.1", note = "use `with_indexer_set` instead")] @@ -608,7 +632,8 @@ impl Module { /// /// # Deprecated /// - /// This method is deprecated. Use `new` instead. + /// This method is deprecated. + /// Use [`new`][`Module::new`] instead. /// /// This method will be removed in the next major version. #[inline(always)] @@ -617,6 +642,24 @@ impl Module { pub const fn with_capacity(_capacity: usize) -> Self { Self::new() } + + /// Get the display name of a registered custom type. + /// + /// # Deprecated + /// + /// This method is deprecated. + /// Use [`get_custom_type_display_by_name`][`Module::get_custom_type_display_by_name`] instead. + /// + /// This method will be removed in the next major version. + #[inline(always)] + #[must_use] + #[deprecated( + since = "1.16.0", + note = "use `get_custom_type_display_by_name` instead" + )] + pub fn get_custom_type(&self, type_name: &str) -> Option<&str> { + self.get_custom_type_display_by_name(type_name) + } } #[cfg(not(feature = "no_index"))] diff --git a/src/api/events.rs b/src/api/events.rs index 2875d03b8..8e58999a3 100644 --- a/src/api/events.rs +++ b/src/api/events.rs @@ -1,50 +1,10 @@ //! Module that defines public event handlers for [`Engine`]. use crate::func::SendSync; -use crate::{Dynamic, Engine, EvalContext, Position, RhaiResultOf}; +use crate::{Dynamic, Engine, EvalContext, Position, RhaiResultOf, VarDefInfo}; #[cfg(feature = "no_std")] use std::prelude::v1::*; -/// Information on a variable definition. -#[derive(Debug, Hash)] -pub struct VarDefInfo<'a> { - /// Name of the variable to be defined. - pub(crate) name: &'a str, - /// `true` if the statement is `const`, otherwise it is `let`. - pub(crate) is_const: bool, - /// The current nesting level, with zero being the global level. - pub(crate) nesting_level: usize, - /// Will the variable _shadow_ an existing variable? - pub(crate) will_shadow: bool, -} - -impl<'a> VarDefInfo<'a> { - /// Name of the variable to be defined. - #[inline(always)] - #[must_use] - pub const fn name(&self) -> &str { - self.name - } - /// `true` if the statement is `const`, otherwise it is `let`. - #[inline(always)] - #[must_use] - pub const fn is_const(&self) -> bool { - self.is_const - } - /// The current nesting level, with zero being the global level. - #[inline(always)] - #[must_use] - pub const fn nesting_level(&self) -> usize { - self.nesting_level - } - /// Will the variable _shadow_ an existing variable? - #[inline(always)] - #[must_use] - pub const fn will_shadow_other_variables(&self) -> bool { - self.will_shadow - } -} - impl Engine { /// Provide a callback that will be invoked before each variable access. /// diff --git a/src/api/formatting.rs b/src/api/formatting.rs index 69d25983b..6f56dce77 100644 --- a/src/api/formatting.rs +++ b/src/api/formatting.rs @@ -203,13 +203,13 @@ impl Engine { pub fn map_type_name<'a>(&'a self, name: &'a str) -> &'a str { self.global_modules .iter() - .find_map(|m| m.get_custom_type(name)) + .find_map(|m| m.get_custom_type_display_by_name(name)) .or_else(|| { #[cfg(not(feature = "no_module"))] return self .global_sub_modules .values() - .find_map(|m| m.get_custom_type(name)); + .find_map(|m| m.get_custom_type_display_by_name(name)); #[cfg(feature = "no_module")] return None; @@ -234,13 +234,13 @@ impl Engine { self.global_modules .iter() - .find_map(|m| m.get_custom_type(name)) + .find_map(|m| m.get_custom_type_display_by_name(name)) .or_else(|| { #[cfg(not(feature = "no_module"))] return self .global_sub_modules .values() - .find_map(|m| m.get_custom_type(name)); + .find_map(|m| m.get_custom_type_display_by_name(name)); #[cfg(feature = "no_module")] return None; diff --git a/src/api/optimize.rs b/src/api/optimize.rs index 25a24b76d..d3a2e97f4 100644 --- a/src/api/optimize.rs +++ b/src/api/optimize.rs @@ -53,7 +53,7 @@ impl Engine { let mut _new_ast = self.optimize_into_ast( Some(scope), - ast.take_statements(), + ast.take_statements().to_vec().into(), #[cfg(not(feature = "no_function"))] ast.shared_lib() .iter_fn() @@ -63,12 +63,7 @@ impl Engine { ); #[cfg(feature = "metadata")] - match ast.doc_mut() { - Some(doc) => _new_ast.set_doc(std::mem::take(doc)), - None => { - _new_ast.clear_doc(); - } - } + _new_ast.set_doc(std::mem::take(ast.doc_mut())); _new_ast } diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 304c49566..e7b25c747 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -1,6 +1,6 @@ //! Module defining the AST (abstract syntax tree). -use super::{ASTFlags, Expr, FnAccess, Stmt, StmtBlock, StmtBlockContainer}; +use super::{ASTFlags, Expr, FnAccess, Stmt}; use crate::{Dynamic, FnNamespace, ImmutableString, Position}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -8,6 +8,7 @@ use std::{ borrow::Borrow, fmt, hash::Hash, + mem, ops::{Add, AddAssign}, ptr, }; @@ -21,17 +22,17 @@ use std::{ pub struct AST { /// Source of the [`AST`]. source: Option, - /// [`AST`] documentation. - #[cfg(feature = "metadata")] - doc: Option>, /// Global statements. - body: Option>, + body: Box<[Stmt]>, /// Script-defined functions. #[cfg(not(feature = "no_function"))] lib: crate::SharedModule, /// Embedded module resolver, if any. #[cfg(not(feature = "no_module"))] resolver: Option>, + /// [`AST`] documentation. + #[cfg(feature = "metadata")] + doc: crate::SmartString, } impl Default for AST { @@ -54,19 +55,12 @@ impl fmt::Debug for AST { #[cfg(not(feature = "no_module"))] fp.field("resolver", &self.resolver); - fp.field( - "body", - &self - .body - .as_deref() - .map(|b| b.as_slice()) - .unwrap_or_default(), - ); + fp.field("body", &self.body); #[cfg(not(feature = "no_function"))] for (.., fn_def) in self.lib.iter_script_fn() { let sig = fn_def.to_string(); - fp.field(&sig, &fn_def.body.as_slice()); + fp.field(&sig, &fn_def.body.statements()); } fp.finish() @@ -82,13 +76,14 @@ impl AST { statements: impl IntoIterator, #[cfg(not(feature = "no_function"))] functions: impl Into, ) -> Self { - let stmt = StmtBlock::new(statements, Position::NONE, Position::NONE); - Self { source: None, #[cfg(feature = "metadata")] - doc: None, - body: (!stmt.is_empty()).then(|| stmt.into()), + doc: crate::SmartString::new_const(), + body: statements + .into_iter() + .collect::>() + .into_boxed_slice(), #[cfg(not(feature = "no_function"))] lib: functions.into(), #[cfg(not(feature = "no_module"))] @@ -104,13 +99,14 @@ impl AST { statements: impl IntoIterator, #[cfg(not(feature = "no_function"))] functions: impl Into, ) -> Self { - let stmt = StmtBlock::new(statements, Position::NONE, Position::NONE); - Self { source: None, #[cfg(feature = "metadata")] - doc: None, - body: (!stmt.is_empty()).then(|| stmt.into()), + doc: crate::SmartString::new_const(), + body: statements + .into_iter() + .collect::>() + .into_boxed_slice(), #[cfg(not(feature = "no_function"))] lib: functions.into(), #[cfg(not(feature = "no_module"))] @@ -159,8 +155,8 @@ impl AST { Self { source: None, #[cfg(feature = "metadata")] - doc: None, - body: None, + doc: crate::SmartString::new_const(), + body: <_>::default(), #[cfg(not(feature = "no_function"))] lib: crate::Module::new().into(), #[cfg(not(feature = "no_module"))] @@ -209,65 +205,51 @@ impl AST { #[inline(always)] #[must_use] pub fn doc(&self) -> &str { - self.doc.as_ref().map(|s| s.as_str()).unwrap_or_default() - } - /// Clear the documentation. - /// Exported under the `metadata` feature only. - #[cfg(feature = "metadata")] - #[inline(always)] - pub fn clear_doc(&mut self) -> &mut Self { - self.doc = None; - self + &self.doc } /// Get a mutable reference to the documentation. - /// - /// Only available under `metadata`. #[cfg(feature = "metadata")] #[inline(always)] #[must_use] #[allow(dead_code)] - pub(crate) fn doc_mut(&mut self) -> Option<&mut crate::SmartString> { - self.doc.as_deref_mut() + pub(crate) fn doc_mut(&mut self) -> &mut crate::SmartString { + &mut self.doc } /// Set the documentation. - /// - /// Only available under `metadata`. #[cfg(feature = "metadata")] #[inline(always)] pub(crate) fn set_doc(&mut self, doc: impl Into) { - let doc = doc.into(); - self.doc = (!doc.is_empty()).then(|| doc.into()); + self.doc = doc.into(); + } + /// Clear the documentation. + /// Exported under the `metadata` feature only. + #[cfg(feature = "metadata")] + #[inline(always)] + pub fn clear_doc(&mut self) -> &mut Self { + self.doc.clear(); + self } /// Get the statements. #[cfg(not(feature = "internals"))] #[inline(always)] #[must_use] - pub(crate) fn statements(&self) -> &[Stmt] { - self.body - .as_deref() - .map(StmtBlock::statements) - .unwrap_or_default() + pub(crate) const fn statements(&self) -> &[Stmt] { + &self.body } /// _(internals)_ Get the statements. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[inline(always)] #[must_use] - pub fn statements(&self) -> &[Stmt] { - self.body - .as_deref() - .map(StmtBlock::statements) - .unwrap_or_default() + pub const fn statements(&self) -> &[Stmt] { + &self.body } /// Extract the statements. #[allow(dead_code)] #[inline(always)] #[must_use] - pub(crate) fn take_statements(&mut self) -> StmtBlockContainer { - self.body - .as_deref_mut() - .map(StmtBlock::take_statements) - .unwrap_or_default() + pub(crate) fn take_statements(&mut self) -> Box<[Stmt]> { + mem::take(&mut self.body) } /// Does this [`AST`] contain script-defined functions? /// @@ -361,7 +343,7 @@ impl AST { source: self.source.clone(), #[cfg(feature = "metadata")] doc: self.doc.clone(), - body: None, + body: <_>::default(), lib: lib.into(), #[cfg(not(feature = "no_module"))] resolver: self.resolver.clone(), @@ -559,15 +541,15 @@ impl AST { other: &Self, _filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool, ) -> Self { - let merged = match (&self.body, &other.body) { - (Some(body), Some(other)) => { - let mut body = body.as_ref().clone(); + let merged = match (self.body.as_ref(), other.body.as_ref()) { + ([], []) => <_>::default(), + (_, []) => self.body.to_vec(), + ([], _) => other.body.to_vec(), + (body, other) => { + let mut body = body.to_vec(); body.extend(other.iter().cloned()); body } - (Some(body), None) => body.as_ref().clone(), - (None, Some(body)) => body.as_ref().clone(), - (None, None) => StmtBlock::NONE, }; #[cfg(not(feature = "no_function"))] @@ -614,13 +596,13 @@ impl AST { } #[cfg(feature = "metadata")] - match (&other.doc, &mut _ast.doc) { - (Some(other_doc), Some(ast_doc)) => { - ast_doc.push('\n'); - ast_doc.push_str(other_doc); + match (other.doc.as_str(), _ast.doc.as_str()) { + ("", _) => (), + (_, "") => _ast.doc = other.doc.clone(), + (_, _) => { + _ast.doc.push('\n'); + _ast.doc.push_str(&other.doc); } - (Some(other_doc), None) => _ast.doc = Some(other_doc.clone()), - _ => (), } _ast @@ -708,11 +690,15 @@ impl AST { } } - match (&mut self.body, other.body) { - (Some(body), Some(other)) => body.extend(other.into_iter()), - (Some(_), None) => (), - (None, body @ Some(_)) => self.body = body, - (None, None) => (), + match (self.body.as_ref(), other.body.as_ref()) { + (_, []) => (), + ([], _) => self.body = other.body, + (_, _) => { + let mut body = self.body.to_vec(); + let other = other.body.to_vec(); + body.extend(other); + self.body = body.into_boxed_slice(); + } } #[cfg(not(feature = "no_function"))] @@ -721,13 +707,13 @@ impl AST { } #[cfg(feature = "metadata")] - match (other.doc, &mut self.doc) { - (Some(ref other_doc), Some(self_doc)) => { - self_doc.push('\n'); - self_doc.push_str(other_doc); + match (other.doc.as_str(), self.doc.as_str()) { + ("", _) => (), + (_, "") => self.doc = other.doc, + (_, _) => { + self.doc.push('\n'); + self.doc.push_str(&other.doc); } - (Some(other_doc), None) => self.doc = Some(other_doc), - _ => (), } self @@ -810,7 +796,7 @@ impl AST { /// Clear all statements in the [`AST`], leaving only function definitions. #[inline(always)] pub fn clear_statements(&mut self) -> &mut Self { - self.body = None; + self.body = <_>::default(); self } /// Extract all top-level literal constant and/or variable definitions. diff --git a/src/ast/expr.rs b/src/ast/expr.rs index d6404fd2f..af8837c78 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -391,7 +391,7 @@ impl fmt::Debug for Expr { } f.write_str(&x.3)?; #[cfg(not(feature = "no_module"))] - if let Some(n) = x.1.index() { + if let Some(n) = x.1.index { write!(f, " #{n}")?; } if let Some(n) = i.map_or_else(|| x.0, |n| NonZeroUsize::new(n.get() as usize)) { diff --git a/src/ast/flags.rs b/src/ast/flags.rs index 6528a8916..ecdef34da 100644 --- a/src/ast/flags.rs +++ b/src/ast/flags.rs @@ -6,8 +6,11 @@ use std::prelude::v1::*; /// A type representing the access mode of a function. #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "metadata", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "metadata", serde(rename_all = "camelCase"))] +#[cfg_attr( + feature = "metadata", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "camelCase") +)] #[non_exhaustive] pub enum FnAccess { /// Private function. @@ -53,6 +56,11 @@ bitflags! { } } +impl ASTFlags { + /// No flags. + pub const NONE: Self = Self::empty(); +} + impl std::fmt::Debug for ASTFlags { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", &self.0) diff --git a/src/ast/ident.rs b/src/ast/ident.rs index ffc5f9686..e80691286 100644 --- a/src/ast/ident.rs +++ b/src/ast/ident.rs @@ -3,12 +3,7 @@ use crate::{ImmutableString, Position}; #[cfg(feature = "no_std")] use std::prelude::v1::*; -use std::{ - borrow::Borrow, - fmt, - hash::Hash, - ops::{Deref, DerefMut}, -}; +use std::{borrow::Borrow, fmt, hash::Hash}; /// _(internals)_ An identifier containing a name and a [position][Position]. /// Exported under the `internals` feature only. @@ -45,22 +40,6 @@ impl AsRef for Ident { } } -impl Deref for Ident { - type Target = ImmutableString; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.name - } -} - -impl DerefMut for Ident { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.name - } -} - impl Ident { /// Get the name of the identifier as a string slice. #[inline(always)] @@ -68,4 +47,10 @@ impl Ident { pub fn as_str(&self) -> &str { self.name.as_str() } + /// Is the identifier empty? + #[inline(always)] + #[must_use] + pub fn is_empty(&self) -> bool { + self.name.is_empty() + } } diff --git a/src/ast/namespace.rs b/src/ast/namespace.rs index c6cd91e93..3721fb81f 100644 --- a/src/ast/namespace.rs +++ b/src/ast/namespace.rs @@ -5,11 +5,7 @@ use crate::ast::Ident; use crate::{Position, StaticVec}; #[cfg(feature = "no_std")] use std::prelude::v1::*; -use std::{ - fmt, - num::NonZeroUsize, - ops::{Deref, DerefMut}, -}; +use std::{fmt, num::NonZeroUsize}; /// _(internals)_ A chain of [module][crate::Module] names to namespace-qualify a variable or function call. /// Exported under the `internals` feature only. @@ -22,9 +18,12 @@ use std::{ /// A [`StaticVec`] is used because the vast majority of namespace-qualified access contains only /// one level, and it is wasteful to always allocate a [`Vec`] with one element. #[derive(Clone, Eq, PartialEq, Default, Hash)] +#[non_exhaustive] pub struct Namespace { - path: StaticVec, - index: Option, + /// Path segments. + pub path: StaticVec, + /// Cached index into the current stack of imported [modules][crate::Module], if any. + pub index: Option, } impl fmt::Debug for Namespace { @@ -67,22 +66,6 @@ impl fmt::Display for Namespace { } } -impl Deref for Namespace { - type Target = StaticVec; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.path - } -} - -impl DerefMut for Namespace { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.path - } -} - impl From> for Namespace { #[inline] fn from(mut path: Vec) -> Self { @@ -108,26 +91,11 @@ impl Namespace { index: None, path: StaticVec::new_const(), }; - - /// Create a new [`Namespace`]. - #[inline(always)] - #[must_use] - pub fn new(root: impl Into) -> Self { - let mut path = StaticVec::new_const(); - path.push(root.into()); - - Self { index: None, path } - } - /// Get the [`Scope`][crate::Scope] index offset. + /// Is this [`Namespace`] empty? #[inline(always)] #[must_use] - pub(crate) const fn index(&self) -> Option { - self.index - } - /// Set the [`Scope`][crate::Scope] index offset. - #[inline(always)] - pub(crate) fn set_index(&mut self, index: Option) { - self.index = index; + pub fn is_empty(&self) -> bool { + self.path.is_empty() } /// Get the [position][Position] of this [`Namespace`]. /// diff --git a/src/ast/script_fn.rs b/src/ast/script_fn.rs index d9695c1b2..a566871a2 100644 --- a/src/ast/script_fn.rs +++ b/src/ast/script_fn.rs @@ -23,18 +23,17 @@ pub struct ScriptFnDef { pub this_type: Option, /// Names of function parameters. pub params: FnArgsVec, - /// _(metadata)_ Function doc-comments (if any). - /// Exported under the `metadata` feature only. + /// _(metadata)_ Function doc-comments (if any). Exported under the `metadata` feature only. /// /// Doc-comments are comment lines beginning with `///` or comment blocks beginning with `/**`, /// placed immediately before a function definition. /// - /// Block doc-comments are kept in a single string slice with line-breaks within. + /// Block doc-comments are kept in a single string with line-breaks within. /// - /// Line doc-comments are merged, with line-breaks, into a single string slice without a termination line-break. + /// Line doc-comments are merged, with line-breaks, into a single string without a termination line-break. /// - /// Leading white-spaces are stripped, and each string slice always starts with the - /// corresponding doc-comment leader: `///` or `/**`. + /// Leading white-spaces are stripped, and each string always starts with the corresponding + /// doc-comment leader: `///` or `/**`. /// /// Each line in non-block doc-comments starts with `///`. #[cfg(feature = "metadata")] @@ -76,17 +75,30 @@ impl fmt::Display for ScriptFnDef { /// /// Created by [`AST::iter_functions`][super::AST::iter_functions]. #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Hash)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "camelCase") +)] #[non_exhaustive] pub struct ScriptFnMetadata<'a> { /// Function name. pub name: &'a str, /// Function parameters (if any). + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty") + )] pub params: Vec<&'a str>, /// Function access mode. pub access: FnAccess, - #[cfg(not(feature = "no_object"))] /// Type of `this` pointer, if any. /// Not available under `no_object`. + #[cfg(not(feature = "no_object"))] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] pub this_type: Option<&'a str>, /// _(metadata)_ Function doc-comments (if any). /// Exported under the `metadata` feature only. @@ -103,6 +115,10 @@ pub struct ScriptFnMetadata<'a> { /// /// Each line in non-block doc-comments starts with `///`. #[cfg(feature = "metadata")] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty") + )] pub comments: Vec<&'a str>, } diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 6af5300b9..cab19ed00 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -15,7 +15,7 @@ use std::{ hash::{Hash, Hasher}, mem, num::NonZeroUsize, - ops::{Deref, DerefMut, Range, RangeInclusive}, + ops::{Range, RangeInclusive}, }; /// _(internals)_ An op-assignment operator. @@ -365,7 +365,7 @@ impl RangeCase { } } -pub type CaseBlocksList = smallvec::SmallVec<[usize; 1]>; +pub type CaseBlocksList = smallvec::SmallVec<[usize; 2]>; /// _(internals)_ A type containing all cases for a `switch` statement. /// Exported under the `internals` feature only. @@ -473,6 +473,12 @@ impl StmtBlock { pub fn statements(&self) -> &[Stmt] { &self.block } + /// Get the statements of this statements block. + #[inline(always)] + #[must_use] + pub fn statements_mut(&mut self) -> &mut StmtBlockContainer { + &mut self.block + } /// Extract the statements. #[inline(always)] #[must_use] @@ -519,22 +525,6 @@ impl StmtBlock { } } -impl Deref for StmtBlock { - type Target = StmtBlockContainer; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.block - } -} - -impl DerefMut for StmtBlock { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.block - } -} - impl Borrow<[Stmt]> for StmtBlock { #[inline(always)] #[must_use] diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index 8c0fd67de..15fd0d3f1 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -21,6 +21,7 @@ static INDEXER_HASHES: OnceCell<(u64, u64)> = OnceCell::new(); #[must_use] fn hash_idx() -> (u64, u64) { *INDEXER_HASHES.get_or_init(|| { + #[allow(clippy::useless_conversion)] ( calc_fn_hash(None, FN_IDX_GET, 2), calc_fn_hash(None, FN_IDX_SET, 3), @@ -551,7 +552,7 @@ impl Engine { #[cfg(not(feature = "no_index"))] ChainType::Indexing => { // Check for existence with the null conditional operator - if parent.options().contains(ASTFlags::NEGATED) && target.is_unit() { + if parent.options().contains(ASTFlags::NEGATED) && target.as_ref().is_unit() { return Ok((Dynamic::UNIT, false)); } @@ -570,6 +571,7 @@ impl Engine { let idx_pos = x.lhs.start_position(); let (try_setter, result) = { + let target = target.as_mut(); let mut obj = self.get_indexed_mut( global, caches, target, idx_val, idx_pos, op_pos, false, true, )?; @@ -590,6 +592,7 @@ impl Engine { if let Some(mut new_val) = try_setter { // Try to call index setter if value is changed + let target = target.as_mut(); let idx = &mut idx_val_for_setter; let new_val = &mut new_val; // The return value of a indexer setter (usually `()`) is thrown away and not used. @@ -610,6 +613,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(global, caches, scope, this_ptr, parent)?; + let target = target.as_mut(); let idx_val = &mut idx_values.pop().unwrap(); let idx = &mut idx_val.clone(); @@ -666,6 +670,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(global, caches, scope, this_ptr, parent)?; + let target = target.as_mut(); let idx_val = &mut idx_values.pop().unwrap(); self.get_indexed_mut( @@ -679,11 +684,11 @@ impl Engine { #[cfg(not(feature = "no_object"))] ChainType::Dotting => { // Check for existence with the Elvis operator - if parent.options().contains(ASTFlags::NEGATED) && target.is_unit() { + if parent.options().contains(ASTFlags::NEGATED) && target.as_ref().is_unit() { return Ok((Dynamic::UNIT, false)); } - match (rhs, new_val, target.is_map()) { + match (rhs, new_val, target.as_ref().is_map()) { // xxx.fn_name(...) = ??? (Expr::MethodCall(..), Some(..), ..) => { unreachable!("method call cannot be assigned to") @@ -722,6 +727,7 @@ impl Engine { let index = &mut x.2.clone().into(); { + let target = target.as_mut(); let val_target = &mut self.get_indexed_mut( global, caches, target, index, *pos, op_pos, true, false, )?; @@ -737,6 +743,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(global, caches, scope, this_ptr, rhs)?; + let target = target.as_mut(); let index = &mut x.2.clone().into(); let val = self.get_indexed_mut( global, caches, target, index, *pos, op_pos, false, false, @@ -760,6 +767,7 @@ impl Engine { .or_else(|err| match *err { // Try an indexer if property does not exist ERR::ErrorDotExpr(..) => { + let target = target.as_mut(); let mut prop = name.into(); self.call_indexer_get( global, caches, target, &mut prop, op_pos, @@ -794,6 +802,7 @@ impl Engine { .or_else(|err| match *err { // Try an indexer if property does not exist ERR::ErrorDotExpr(..) => { + let target = target.as_mut(); let idx = &mut name.into(); let new_val = &mut new_val; self.call_indexer_set( @@ -822,6 +831,7 @@ impl Engine { |err| match *err { // Try an indexer if property does not exist ERR::ErrorDotExpr(..) => { + let target = target.as_mut(); let mut prop = name.into(); self.call_indexer_get(global, caches, target, &mut prop, op_pos) .map(|r| (r, false)) @@ -847,6 +857,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(global, caches, scope, _tp, _node)?; + let target = target.as_mut(); let index = &mut p.2.clone().into(); self.get_indexed_mut( global, caches, target, index, pos, op_pos, false, true, @@ -914,6 +925,7 @@ impl Engine { .or_else(|err| match *err { // Try an indexer if property does not exist ERR::ErrorDotExpr(..) => { + let target = target.as_mut(); let mut prop = name.into(); self.call_indexer_get( global, caches, target, &mut prop, op_pos, @@ -950,8 +962,9 @@ impl Engine { .or_else(|err| match *err { // Try an indexer if property does not exist ERR::ErrorDotExpr(..) => { + let target = target.as_mut(); let idx = &mut name.into(); - let new_val = val; + let new_val = val.as_mut(); self.call_indexer_set( global, caches, target, idx, new_val, is_ref_mut, op_pos, diff --git a/src/eval/eval_context.rs b/src/eval/eval_context.rs index 9f4350bc0..fc596629a 100644 --- a/src/eval/eval_context.rs +++ b/src/eval/eval_context.rs @@ -175,7 +175,7 @@ impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> { self.caches, self.scope, this_ptr, - stmts, + stmts.statements(), rewind_scope, ), _ => self diff --git a/src/eval/expr.rs b/src/eval/expr.rs index 634000e7e..a79b6e7cd 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -25,7 +25,7 @@ impl Engine { // Qualified - check if the root module is directly indexed if !global.always_search_scope { - if let Some(index) = namespace.index() { + if let Some(index) = namespace.index { let offset = global.num_imports() - index.get(); if let m @ Some(_) = global.get_shared_import(offset) { @@ -86,14 +86,14 @@ impl Engine { // global::VARIABLE #[cfg(not(feature = "no_function"))] - if ns.len() == 1 && ns.root() == crate::engine::KEYWORD_GLOBAL { + if ns.path.len() == 1 && ns.root() == crate::engine::KEYWORD_GLOBAL { if let Some(ref constants) = global.constants { if let Some(value) = crate::func::locked_write(constants).get_mut(var_name.as_str()) { let mut target: Target = value.clone().into(); // Module variables are constant - target.set_access_mode(AccessMode::ReadOnly); + target.as_mut().set_access_mode(AccessMode::ReadOnly); return Ok(target); } } @@ -390,7 +390,9 @@ impl Engine { .and_then(|r| self.check_data_size(r, expr.start_position())) } - Expr::Stmt(x) => self.eval_stmt_block(global, caches, scope, this_ptr, x, true), + Expr::Stmt(x) => { + self.eval_stmt_block(global, caches, scope, this_ptr, x.statements(), true) + } #[cfg(not(feature = "no_index"))] Expr::Index(..) => { diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 30fed04ad..3832d1a48 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -1,7 +1,6 @@ //! Module defining functions for evaluating a statement. use super::{Caches, EvalContext, GlobalRuntimeState, Target}; -use crate::api::events::VarDefInfo; use crate::ast::{ ASTFlags, BinaryExpr, ConditionalExpr, Expr, FlowControl, OpAssignment, Stmt, SwitchCasesCollection, @@ -9,7 +8,7 @@ use crate::ast::{ use crate::func::{get_builtin_op_assignment_fn, get_hasher}; use crate::tokenizer::Token; use crate::types::dynamic::{AccessMode, Union}; -use crate::{Dynamic, Engine, RhaiResult, RhaiResultOf, Scope, ERR, INT}; +use crate::{Dynamic, Engine, RhaiResult, RhaiResultOf, Scope, VarDefInfo, ERR, INT}; use std::hash::{Hash, Hasher}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -121,7 +120,7 @@ impl Engine { mut new_val: Dynamic, ) -> RhaiResultOf<()> { // Assignment to constant variable? - if target.is_read_only() { + if target.as_ref().is_read_only() { let name = root.get_variable_name(false).unwrap_or_default(); let pos = root.start_position(); return Err(ERR::ErrorAssignmentToConstant(name.to_string(), pos).into()); @@ -130,7 +129,7 @@ impl Engine { let pos = op_info.position(); if let Some((hash_x, hash, op_x, op_x_str, op, op_str)) = op_info.get_op_assignment_info() { - let mut lock_guard = target.write_lock::().unwrap(); + let mut lock_guard = target.as_mut().write_lock::().unwrap(); let mut done = false; // Short-circuit built-in op-assignments if under Fast Operators mode @@ -247,10 +246,10 @@ impl Engine { match target { // Lock it again just in case it is shared Target::RefMut(_) | Target::TempValue(_) => { - *target.write_lock::().unwrap() = new_val + *target.as_mut().write_lock::().unwrap() = new_val } #[allow(unreachable_patterns)] - _ => **target = new_val, + _ => *target.as_mut() = new_val, } } @@ -285,11 +284,11 @@ impl Engine { .map(Dynamic::flatten), // Block scope - Stmt::Block(statements, ..) => { - if statements.is_empty() { + Stmt::Block(stmts, ..) => { + if stmts.is_empty() { Ok(Dynamic::UNIT) } else { - self.eval_stmt_block(global, caches, scope, this_ptr, statements, true) + self.eval_stmt_block(global, caches, scope, this_ptr, stmts.statements(), true) } } @@ -389,8 +388,8 @@ impl Engine { // Variable definition Stmt::Var(x, options, pos) => { - if !self.allow_shadowing() && scope.contains(&x.0) { - return Err(ERR::ErrorVariableExists(x.0.to_string(), *pos).into()); + if !self.allow_shadowing() && scope.contains(x.0.as_str()) { + return Err(ERR::ErrorVariableExists(x.0.as_str().to_string(), *pos).into()); } // Let/const statement @@ -405,14 +404,14 @@ impl Engine { // Check variable definition filter if let Some(ref filter) = self.def_var_filter { - let will_shadow = scope.contains(var_name); + let will_shadow = scope.contains(var_name.as_str()); let is_const = access == AccessMode::ReadOnly; - let info = VarDefInfo { - name: var_name, + let info = VarDefInfo::new( + var_name.as_str(), is_const, - nesting_level: global.scope_level, + global.scope_level, will_shadow, - }; + ); let orig_scope_len = scope.len(); let context = EvalContext::new(self, global, caches, scope, this_ptr.as_deref_mut()); @@ -424,7 +423,11 @@ impl Engine { } if !filter_result? { - return Err(ERR::ErrorForbiddenVariable(var_name.to_string(), *pos).into()); + return Err(ERR::ErrorForbiddenVariable( + var_name.as_str().to_string(), + *pos, + ) + .into()); } } @@ -487,21 +490,17 @@ impl Engine { // If statement Stmt::If(x, ..) => { - let FlowControl { - expr, - body: if_block, - branch: else_block, - } = &**x; + let FlowControl { expr, body, branch } = &**x; let guard_val = self .eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)? .as_bool() .map_err(|typ| self.make_type_mismatch_err::(typ, expr.position()))?; - if guard_val && !if_block.is_empty() { - self.eval_stmt_block(global, caches, scope, this_ptr, if_block, true) - } else if !guard_val && !else_block.is_empty() { - self.eval_stmt_block(global, caches, scope, this_ptr, else_block, true) + if guard_val && !body.is_empty() { + self.eval_stmt_block(global, caches, scope, this_ptr, body.statements(), true) + } else if !guard_val && !branch.is_empty() { + self.eval_stmt_block(global, caches, scope, this_ptr, branch.statements(), true) } else { Ok(Dynamic::UNIT) } @@ -594,8 +593,9 @@ impl Engine { loop { let this_ptr = this_ptr.as_deref_mut(); + let statements = body.statements(); - match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) { + match self.eval_stmt_block(global, caches, scope, this_ptr, statements, true) { Ok(..) => (), Err(err) => match *err { ERR::LoopBreak(false, ..) => (), @@ -625,8 +625,9 @@ impl Engine { } let this_ptr = this_ptr.as_deref_mut(); + let statements = body.statements(); - match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) { + match self.eval_stmt_block(global, caches, scope, this_ptr, statements, true) { Ok(..) => (), Err(err) => match *err { ERR::LoopBreak(false, ..) => (), @@ -645,8 +646,11 @@ impl Engine { loop { if !body.is_empty() { let this_ptr = this_ptr.as_deref_mut(); + let statements = body.statements(); - match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) { + match self + .eval_stmt_block(global, caches, scope, this_ptr, statements, true) + { Ok(..) => (), Err(err) => match *err { ERR::LoopBreak(false, ..) => continue, @@ -755,8 +759,11 @@ impl Engine { // Run block let this_ptr = this_ptr.as_deref_mut(); + let statements = body.statements(); - match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) { + match self + .eval_stmt_block(global, caches, scope, this_ptr, statements, true) + { Ok(_) => (), Err(err) => match *err { ERR::LoopBreak(false, ..) => (), @@ -788,9 +795,9 @@ impl Engine { // Try/Catch statement Stmt::TryCatch(x, ..) => { let FlowControl { - body: try_block, + body, expr: catch_var, - branch: catch_block, + branch, } = &**x; match self.eval_stmt_block( @@ -798,7 +805,7 @@ impl Engine { caches, scope, this_ptr.as_deref_mut(), - try_block, + body.statements(), true, ) { r @ Ok(_) => r, @@ -856,8 +863,9 @@ impl Engine { } let this_ptr = this_ptr.as_deref_mut(); + let statements = branch.statements(); - self.eval_stmt_block(global, caches, scope, this_ptr, catch_block, true) + self.eval_stmt_block(global, caches, scope, this_ptr, statements, true) .map(|_| Dynamic::UNIT) .map_err(|result_err| match *result_err { // Re-throw exception diff --git a/src/eval/target.rs b/src/eval/target.rs index de8f57b5b..f4922a5c7 100644 --- a/src/eval/target.rs +++ b/src/eval/target.rs @@ -1,12 +1,9 @@ //! Type to hold a mutable reference to the target of an evaluation. use crate::{Dynamic, Position, RhaiResultOf}; +use std::borrow::{Borrow, BorrowMut}; #[cfg(feature = "no_std")] use std::prelude::v1::*; -use std::{ - borrow::Borrow, - ops::{Deref, DerefMut}, -}; /// Calculate an offset+len pair given an actual length of the underlying array. /// @@ -381,11 +378,9 @@ impl<'a> From<&'a mut Dynamic> for Target<'a> { } } -impl Deref for Target<'_> { - type Target = Dynamic; - +impl AsRef for Target<'_> { #[inline] - fn deref(&self) -> &Dynamic { + fn as_ref(&self) -> &Dynamic { match self { Self::RefMut(r) => r, #[cfg(not(feature = "no_closure"))] @@ -400,23 +395,16 @@ impl Deref for Target<'_> { } } -impl AsRef for Target<'_> { - #[inline(always)] - fn as_ref(&self) -> &Dynamic { - self - } -} - impl Borrow for Target<'_> { #[inline(always)] fn borrow(&self) -> &Dynamic { - self + self.as_ref() } } -impl DerefMut for Target<'_> { +impl AsMut for Target<'_> { #[inline] - fn deref_mut(&mut self) -> &mut Dynamic { + fn as_mut(&mut self) -> &mut Dynamic { match self { Self::RefMut(r) => r, #[cfg(not(feature = "no_closure"))] @@ -431,10 +419,10 @@ impl DerefMut for Target<'_> { } } -impl AsMut for Target<'_> { +impl BorrowMut for Target<'_> { #[inline(always)] - fn as_mut(&mut self) -> &mut Dynamic { - self + fn borrow_mut(&mut self) -> &mut Dynamic { + self.as_mut() } } diff --git a/src/func/call.rs b/src/func/call.rs index fcc34aa03..81103bdfb 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -734,8 +734,8 @@ impl Engine { ) -> RhaiResultOf<(Dynamic, bool)> { let (result, updated) = match fn_name { // Handle fn_ptr.call(...) - KEYWORD_FN_PTR_CALL if target.is_fnptr() => { - let fn_ptr = target.read_lock::().expect("`FnPtr`"); + KEYWORD_FN_PTR_CALL if target.as_ref().is_fnptr() => { + let fn_ptr = target.as_ref().read_lock::().expect("`FnPtr`"); // Arguments are passed as-is, adding the curried arguments let mut curry = fn_ptr.curry().iter().cloned().collect::>(); @@ -784,8 +784,10 @@ impl Engine { // Handle obj.call() KEYWORD_FN_PTR_CALL if call_args.is_empty() => { - return Err(self - .make_type_mismatch_err::(self.map_type_name(target.type_name()), pos)) + return Err(self.make_type_mismatch_err::( + self.map_type_name(target.as_ref().type_name()), + pos, + )) } // Handle obj.call(fn_ptr, ...) @@ -865,8 +867,9 @@ impl Engine { // Handle fn_ptr.curry(...) KEYWORD_FN_PTR_CURRY => { - let typ = target.type_name(); + let typ = target.as_ref().type_name(); let mut fn_ptr = target + .as_ref() .read_lock::() .ok_or_else(|| { self.make_type_mismatch_err::(self.map_type_name(typ), pos) @@ -895,7 +898,7 @@ impl Engine { // Check if it is a map method call in OOP style #[cfg(not(feature = "no_object"))] - if let Some(map) = target.read_lock::() { + if let Some(map) = target.as_ref().read_lock::() { if let Some(val) = map.get(fn_name) { if let Some(fn_ptr) = val.read_lock::() { // Remap the function name @@ -1340,7 +1343,7 @@ impl Engine { let mut target = self.search_namespace(global, caches, scope, this_ptr, first_expr)?; - if target.is_read_only() { + if target.as_ref().is_read_only() { target = target.into_owned(); } diff --git a/src/func/script.rs b/src/func/script.rs index b160e7101..3db62f482 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -122,7 +122,7 @@ impl Engine { caches, scope, this_ptr.as_deref_mut(), - &fn_def.body, + fn_def.body.statements(), rewind_scope, ) .or_else(|err| match *err { diff --git a/src/lib.rs b/src/lib.rs index d402214f0..88187e57e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,9 @@ //! //! # Features //! -#![cfg_attr(feature = "document-features", doc = document_features::document_features!(feature_label = "**`{feature}`**"))] +#![cfg_attr(feature = "document-features", doc = document_features::document_features!( + feature_label = "**`{feature}`**" +))] //! //! # On-Line Documentation //! @@ -225,7 +227,7 @@ pub use api::custom_syntax::Expression; #[cfg(not(feature = "no_std"))] #[cfg(any(not(target_family = "wasm"), not(target_os = "unknown")))] pub use api::files::{eval_file, run_file}; -pub use api::{eval::eval, events::VarDefInfo, run::run}; +pub use api::{eval::eval, run::run}; pub use ast::{FnAccess, AST}; use defer::Deferred; pub use engine::{Engine, OP_CONTAINS, OP_EQUALS}; @@ -241,7 +243,7 @@ pub use rhai_codegen::*; pub use types::Instant; pub use types::{ Dynamic, EvalAltResult, FnPtr, ImmutableString, LexError, ParseError, ParseErrorType, Position, - Scope, + Scope, VarDefInfo, }; /// _(debugging)_ Module containing types for debugging. @@ -329,7 +331,7 @@ pub use types::dynamic::{AccessMode, DynamicReadLock, DynamicWriteLock, Variant} pub use types::FloatWrapper; #[cfg(feature = "internals")] -pub use types::{Span, StringsInterner}; +pub use types::{CustomTypeInfo, Span, StringsInterner}; #[cfg(feature = "internals")] pub use tokenizer::{ diff --git a/src/module/mod.rs b/src/module/mod.rs index 3a3efb1cb..4656ff6d8 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -34,8 +34,11 @@ const FN_MAP_SIZE: usize = 16; /// A type representing the namespace of a function. #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "metadata", derive(serde::Serialize))] -#[cfg_attr(feature = "metadata", serde(rename_all = "camelCase"))] +#[cfg_attr( + feature = "metadata", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "camelCase") +)] #[non_exhaustive] pub enum FnNamespace { /// Module namespace only. @@ -486,7 +489,7 @@ impl Module { /// /// module.set_custom_type::("MyType"); /// - /// assert_eq!(module.get_custom_type(name), Some("MyType")); + /// assert_eq!(module.get_custom_type_display_by_name(name), Some("MyType")); /// ``` #[inline(always)] pub fn set_custom_type(&mut self, name: &str) -> &mut Self { @@ -526,15 +529,15 @@ impl Module { /// /// module.set_custom_type_raw(name, "MyType"); /// - /// assert_eq!(module.get_custom_type(name), Some("MyType")); + /// assert_eq!(module.get_custom_type_display_by_name(name), Some("MyType")); /// ``` #[inline(always)] pub fn set_custom_type_raw( &mut self, - type_path: impl Into, - name: impl Into, + type_name: impl Into, + display_name: impl Into, ) -> &mut Self { - self.custom_types.add(type_path, name); + self.custom_types.add(type_name, display_name); self } /// Map a custom type to a friendly display name. @@ -554,12 +557,12 @@ impl Module { #[inline(always)] pub fn set_custom_type_with_comments_raw>( &mut self, - type_path: impl Into, - name: impl Into, + type_name: impl Into, + display_name: impl Into, comments: impl IntoIterator, ) -> &mut Self { self.custom_types - .add_with_comments(type_path, name, comments); + .add_with_comments(type_name, display_name, comments); self } /// Get the display name of a registered custom type. @@ -577,13 +580,13 @@ impl Module { /// /// module.set_custom_type::("MyType"); /// - /// assert_eq!(module.get_custom_type(name), Some("MyType")); + /// assert_eq!(module.get_custom_type_display_by_name(name), Some("MyType")); /// ``` #[inline] #[must_use] - pub fn get_custom_type(&self, key: &str) -> Option<&str> { - self.get_custom_type_raw(key) - .map(|t| t.display_name.as_str()) + pub fn get_custom_type_display_by_name(&self, type_name: &str) -> Option<&str> { + self.get_custom_type_by_name_raw(type_name) + .map(|typ| typ.display_name.as_str()) } /// Get the display name of a registered custom type. /// @@ -600,18 +603,42 @@ impl Module { /// /// module.set_custom_type::("MyType"); /// - /// assert_eq!(module.get_custom_type_display_name::(), Some("MyType")); + /// assert_eq!(module.get_custom_type_display::(), Some("MyType")); /// ``` #[inline(always)] #[must_use] - pub fn get_custom_type_display_name(&self) -> Option<&str> { - self.get_custom_type(type_name::()) + pub fn get_custom_type_display(&self) -> Option<&str> { + self.get_custom_type_display_by_name(type_name::()) + } + /// _(internals)_ Get a registered custom type . + /// Exported under the `internals` feature only. + #[cfg(feature = "internals")] + #[inline(always)] + #[must_use] + pub fn get_custom_type_raw(&self) -> Option<&CustomTypeInfo> { + self.get_custom_type_by_name_raw(type_name::()) + } + /// Get a registered custom type . + #[cfg(not(feature = "internals"))] + #[inline(always)] + #[must_use] + pub fn get_custom_type_raw(&self) -> Option<&CustomTypeInfo> { + self.get_custom_type_by_name_raw(type_name::()) + } + /// _(internals)_ Get a registered custom type by its type name. + /// Exported under the `internals` feature only. + #[cfg(feature = "internals")] + #[inline(always)] + #[must_use] + pub fn get_custom_type_by_name_raw(&self, type_name: &str) -> Option<&CustomTypeInfo> { + self.custom_types.get(type_name) } /// Get a registered custom type by its type name. + #[cfg(not(feature = "internals"))] #[inline(always)] #[must_use] - pub fn get_custom_type_raw(&self, key: &str) -> Option<&CustomTypeInfo> { - self.custom_types.get(key) + fn get_custom_type_by_name_raw(&self, type_name: &str) -> Option<&CustomTypeInfo> { + self.custom_types.get(type_name) } /// Returns `true` if this [`Module`] contains no items. diff --git a/src/optimizer.rs b/src/optimizer.rs index e0a2144e0..e74dca840 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -171,10 +171,11 @@ fn optimize_stmt_block( |s| matches!(s, Stmt::Block(block, ..) if !block.iter().any(Stmt::is_block_dependent)), ) { let (first, second) = statements.split_at_mut(n); - let stmt = second[0].take(); - let mut stmts = match stmt { - Stmt::Block(block, ..) => block, - stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), + let mut stmt = second[0].take(); + let stmts = if let Stmt::Block(ref mut block, ..) = stmt { + block.statements_mut() + } else { + unreachable!("Stmt::Block expected but gets {:?}", stmt) }; statements = first .iter_mut() @@ -471,10 +472,15 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b Stmt::If(x, ..) => { let FlowControl { expr, body, branch } = &mut **x; optimize_expr(expr, state, false); - let statements = body.take_statements(); - **body = optimize_stmt_block(statements, state, preserve_result, true, false); - let statements = branch.take_statements(); - **branch = optimize_stmt_block(statements, state, preserve_result, true, false); + *body.statements_mut() = + optimize_stmt_block(body.take_statements(), state, preserve_result, true, false); + *branch.statements_mut() = optimize_stmt_block( + branch.take_statements(), + state, + preserve_result, + true, + false, + ); } // switch const { ... } @@ -721,17 +727,20 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if let Expr::BoolConstant(true, pos) = expr { *expr = Expr::Unit(*pos); } - **body = optimize_stmt_block(body.take_statements(), state, false, true, false); + *body.statements_mut() = + optimize_stmt_block(body.take_statements(), state, false, true, false); } // do { block } while|until expr Stmt::Do(x, ..) => { optimize_expr(&mut x.expr, state, false); - *x.body = optimize_stmt_block(x.body.take_statements(), state, false, true, false); + *x.body.statements_mut() = + optimize_stmt_block(x.body.take_statements(), state, false, true, false); } // for id in expr { block } Stmt::For(x, ..) => { optimize_expr(&mut x.2.expr, state, false); - *x.2.body = optimize_stmt_block(x.2.body.take_statements(), state, false, true, false); + *x.2.body.statements_mut() = + optimize_stmt_block(x.2.body.take_statements(), state, false, true, false); } // let id = expr; Stmt::Var(x, options, ..) if !options.contains(ASTFlags::CONSTANT) => { @@ -771,8 +780,10 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } // try { try_block } catch ( var ) { catch_block } Stmt::TryCatch(x, ..) => { - *x.body = optimize_stmt_block(x.body.take_statements(), state, false, true, false); - *x.branch = optimize_stmt_block(x.branch.take_statements(), state, false, true, false); + *x.body.statements_mut() = + optimize_stmt_block(x.body.take_statements(), state, false, true, false); + *x.branch.statements_mut() = + optimize_stmt_block(x.branch.take_statements(), state, false, true, false); } // expr(stmt) @@ -781,7 +792,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b match expr.as_mut() { Expr::Stmt(block) if !block.is_empty() => { let mut stmt_block = *mem::take(block); - *stmt_block = + *stmt_block.statements_mut() = optimize_stmt_block(stmt_block.take_statements(), state, true, true, false); *stmt = stmt_block.into(); } @@ -832,7 +843,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b let orig_len = x.len(); if state.propagate_constants { - x.retain(|(v, _)| state.find_literal_constant(v).is_none()); + x.retain(|(v, _)| state.find_literal_constant(v.as_str()).is_none()); if x.len() != orig_len { state.set_dirty(); @@ -869,10 +880,10 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { } // { stmt; ... } - do not count promotion as dirty because it gets turned back into an array Expr::Stmt(x) => { - ***x = optimize_stmt_block(x.take_statements(), state, true, true, false); + *x.statements_mut() = optimize_stmt_block(x.take_statements(), state, true, true, false); // { Stmt(Expr) } - promote - if let [ Stmt::Expr(e) ] = &mut ****x { state.set_dirty(); *expr = e.take(); } + if let [ Stmt::Expr(e) ] = x.statements_mut().as_mut() { state.set_dirty(); *expr = e.take(); } } // ()?.rhs #[cfg(not(feature = "no_object"))] @@ -1366,10 +1377,14 @@ impl Engine { for fn_def in functions { let mut fn_def = crate::func::shared_take_or_clone(fn_def); - // Optimize the function body - let body = fn_def.body.take_statements(); - *fn_def.body = self.optimize_top_level(body, scope, lib2, optimization_level); + // Optimize the function body + *fn_def.body.statements_mut() = self.optimize_top_level( + fn_def.body.take_statements(), + scope, + lib2, + optimization_level, + ); module.set_script_fn(fn_def); } diff --git a/src/parser.rs b/src/parser.rs index bf9dcdb96..e5e73203d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,5 @@ //! Main module defining the lexer and parser. -use crate::api::events::VarDefInfo; use crate::api::options::LangOptions; use crate::ast::{ ASTFlags, BinaryExpr, CaseBlocksList, ConditionalExpr, Expr, FlowControl, FnCallExpr, @@ -19,7 +18,7 @@ use crate::types::StringsInterner; use crate::{ calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ExclusiveRange, FnArgsVec, Identifier, ImmutableString, InclusiveRange, LexError, OptimizationLevel, ParseError, Position, - Scope, Shared, SmartString, StaticVec, AST, PERR, + Scope, Shared, SmartString, StaticVec, VarDefInfo, AST, PERR, }; use bitflags::bitflags; #[cfg(feature = "no_std")] @@ -671,9 +670,9 @@ impl Engine { ); } - _namespace.set_index(index); + _namespace.index = index; - calc_fn_hash(_namespace.iter().map(Ident::as_str), &id, 0) + calc_fn_hash(_namespace.path.iter().map(Ident::as_str), &id, 0) }; #[cfg(feature = "no_module")] let hash = calc_fn_hash(None, &id, 0); @@ -738,9 +737,9 @@ impl Engine { ); } - _namespace.set_index(index); + _namespace.index = index; - calc_fn_hash(_namespace.iter().map(Ident::as_str), &id, args.len()) + calc_fn_hash(_namespace.path.iter().map(Ident::as_str), &id, args.len()) }; #[cfg(feature = "no_module")] let hash = calc_fn_hash(None, &id, args.len()); @@ -1046,7 +1045,7 @@ impl Engine { return Err(PERR::PropertyExpected.into_err(pos)) } (Token::Identifier(s) | Token::StringConstant(s), pos) => { - if map.iter().any(|(p, ..)| **p == *s) { + if map.iter().any(|(p, ..)| p.as_str() == s.as_str()) { return Err(PERR::DuplicatedProperty(s.to_string()).into_err(pos)); } (*s, pos) @@ -1302,8 +1301,8 @@ impl Engine { cases .entry(hash) - .and_modify(|cases| cases.push(index)) - .or_insert_with(|| [index].into()); + .or_insert(CaseBlocksList::new_const()) + .push(index); } } @@ -1828,7 +1827,7 @@ impl Engine { let (.., mut namespace, _, name) = *x; let var_name_def = Ident { name, pos }; - namespace.push(var_name_def); + namespace.path.push(var_name_def); let var_name = state.get_interned_string(id2); @@ -1903,7 +1902,7 @@ impl Engine { #[cfg(not(feature = "no_module"))] if let Some((.., namespace, hash, name)) = namespaced_variable { if !namespace.is_empty() { - *hash = crate::calc_var_hash(namespace.iter().map(Ident::as_str), name); + *hash = crate::calc_var_hash(namespace.path.iter().map(Ident::as_str), name); #[cfg(not(feature = "no_module"))] { @@ -1926,7 +1925,7 @@ impl Engine { ); } - namespace.set_index(index); + namespace.index = index; } } } @@ -2917,12 +2916,7 @@ impl Engine { global.level = settings.level; let is_const = access == AccessMode::ReadOnly; - let info = VarDefInfo { - name: &name, - is_const, - nesting_level: settings.level, - will_shadow, - }; + let info = VarDefInfo::new(&name, is_const, settings.level, will_shadow); let caches = &mut Caches::new(); let context = EvalContext::new(self, global, caches, &mut state.stack, None); diff --git a/src/serde/metadata.rs b/src/serde/metadata.rs index c8927e4f4..8d8bfb0a4 100644 --- a/src/serde/metadata.rs +++ b/src/serde/metadata.rs @@ -5,28 +5,28 @@ use crate::api::formatting::format_type; use crate::module::{calc_native_fn_hash, FuncInfo, ModuleFlags}; use crate::types::custom_types::CustomTypeInfo; use crate::{calc_fn_hash, Engine, FnAccess, SmartString, AST}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap}; -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] enum FnType { Script, Native, } -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct FnParam<'a> { - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none")] pub name: Option<&'a str>, - #[serde(rename = "type", skip_serializing_if = "Option::is_none")] + #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")] pub typ: Option>, } -#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct CustomTypeMetadata<'a> { pub type_name: &'a str, @@ -54,13 +54,13 @@ impl<'a> From<(&'a str, &'a CustomTypeInfo)> for CustomTypeMetadata<'a> { fn from(value: (&'a str, &'a CustomTypeInfo)) -> Self { Self { type_name: value.0, - display_name: value.1.display_name.as_str(), + display_name: &value.1.display_name, doc_comments: value.1.comments.iter().map(<_>::as_ref).collect(), } } } -#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct FnMetadata<'a> { pub base_hash: u64, @@ -79,9 +79,6 @@ struct FnMetadata<'a> { pub num_params: usize, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub params: Vec>, - // No idea why the following is needed otherwise serde comes back with a lifetime error - #[serde(default, skip_serializing_if = "Option::is_none")] - pub _dummy: Option<&'a str>, #[serde(default, skip_serializing_if = "str::is_empty")] pub return_type: Cow<'a, str>, pub signature: SmartString, @@ -143,7 +140,6 @@ impl<'a> From<&'a FuncInfo> for FnMetadata<'a> { FnParam { name, typ } }) .collect(), - _dummy: None, return_type: format_type(&info.metadata.return_type, true), signature: info.gen_signature().into(), doc_comments: if info.func.is_script() { @@ -165,17 +161,17 @@ impl<'a> From<&'a FuncInfo> for FnMetadata<'a> { } } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct ModuleMetadata<'a> { - #[serde(skip_serializing_if = "str::is_empty")] - pub doc: &'a str, - #[serde(skip_serializing_if = "BTreeMap::is_empty")] + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub modules: BTreeMap<&'a str, Self>, - #[serde(skip_serializing_if = "Vec::is_empty")] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub custom_types: Vec>, - #[serde(skip_serializing_if = "Vec::is_empty")] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub functions: Vec>, + #[serde(default, skip_serializing_if = "str::is_empty")] + pub doc: &'a str, } impl ModuleMetadata<'_> { diff --git a/src/serde/ser.rs b/src/serde/ser.rs index c4030dbde..d76975368 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -15,9 +15,9 @@ use num_traits::FromPrimitive; /// Serializer for [`Dynamic`][crate::Dynamic]. pub struct DynamicSerializer { /// Buffer to hold a temporary key. - _key: Identifier, + key: Identifier, /// Buffer to hold a temporary value. - _value: Dynamic, + value: Dynamic, } impl DynamicSerializer { @@ -25,8 +25,8 @@ impl DynamicSerializer { #[must_use] pub const fn new(value: Dynamic) -> Self { Self { - _key: Identifier::new_const(), - _value: value, + key: Identifier::new_const(), + value, } } } @@ -464,7 +464,7 @@ impl SerializeSeq for DynamicSerializer { #[cfg(not(feature = "no_index"))] { let value = _value.serialize(&mut *self)?; - let arr = self._value.downcast_mut::().unwrap(); + let arr = self.value.downcast_mut::().unwrap(); arr.push(value); Ok(()) } @@ -481,7 +481,7 @@ impl SerializeSeq for DynamicSerializer { #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] - return Ok(self._value); + return Ok(self.value); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), @@ -500,7 +500,7 @@ impl SerializeTuple for DynamicSerializer { #[cfg(not(feature = "no_index"))] { let value = _value.serialize(&mut *self)?; - let arr = self._value.downcast_mut::().unwrap(); + let arr = self.value.downcast_mut::().unwrap(); arr.push(value); Ok(()) } @@ -516,7 +516,7 @@ impl SerializeTuple for DynamicSerializer { #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] - return Ok(self._value); + return Ok(self.value); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), @@ -535,7 +535,7 @@ impl SerializeTupleStruct for DynamicSerializer { #[cfg(not(feature = "no_index"))] { let value = _value.serialize(&mut *self)?; - let arr = self._value.downcast_mut::().unwrap(); + let arr = self.value.downcast_mut::().unwrap(); arr.push(value); Ok(()) } @@ -551,7 +551,7 @@ impl SerializeTupleStruct for DynamicSerializer { #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] - return Ok(self._value); + return Ok(self.value); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), @@ -570,7 +570,7 @@ impl SerializeMap for DynamicSerializer { #[cfg(not(feature = "no_object"))] { let key = _key.serialize(&mut *self)?; - self._key = key + self.key = key .into_immutable_string() .map_err(|typ| { ERR::ErrorMismatchDataType("string".into(), typ.into(), Position::NONE) @@ -590,9 +590,9 @@ impl SerializeMap for DynamicSerializer { fn serialize_value(&mut self, _value: &T) -> RhaiResultOf<()> { #[cfg(not(feature = "no_object"))] { - let key = std::mem::take(&mut self._key); + let key = std::mem::take(&mut self.key); let value = _value.serialize(&mut *self)?; - let map = self._value.downcast_mut::().unwrap(); + let map = self.value.downcast_mut::().unwrap(); map.insert(key, value); Ok(()) } @@ -617,7 +617,7 @@ impl SerializeMap for DynamicSerializer { ERR::ErrorMismatchDataType("string".into(), typ.into(), Position::NONE) })?; let value = _value.serialize(&mut *self)?; - let map = self._value.downcast_mut::().unwrap(); + let map = self.value.downcast_mut::().unwrap(); map.insert(key.into(), value); Ok(()) } @@ -633,7 +633,7 @@ impl SerializeMap for DynamicSerializer { #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_object"))] - return Ok(self._value); + return Ok(self.value); #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), @@ -656,7 +656,7 @@ impl SerializeStruct for DynamicSerializer { #[cfg(not(feature = "no_object"))] { let value = _value.serialize(&mut *self)?; - let map = self._value.downcast_mut::().unwrap(); + let map = self.value.downcast_mut::().unwrap(); map.insert(_key.into(), value); Ok(()) } @@ -672,7 +672,7 @@ impl SerializeStruct for DynamicSerializer { #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_object"))] - return Ok(self._value); + return Ok(self.value); #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), diff --git a/src/types/custom_types.rs b/src/types/custom_types.rs index 403d70879..3419fbb39 100644 --- a/src/types/custom_types.rs +++ b/src/types/custom_types.rs @@ -5,13 +5,26 @@ use crate::Identifier; use std::prelude::v1::*; use std::{any::type_name, collections::BTreeMap}; -/// _(internals)_ Information for a custom type. +/// _(internals)_ Information for a registered custom type. /// Exported under the `internals` feature only. -#[derive(Debug, Eq, PartialEq, Clone, Hash, Default)] +#[derive(Debug, Eq, PartialEq, Clone, Hash)] +#[non_exhaustive] pub struct CustomTypeInfo { + /// Rust name of the custom type. + pub type_name: Identifier, /// Friendly display name of the custom type. pub display_name: Identifier, /// Comments. + /// + /// Block doc-comments are kept in separate strings. + /// + /// Line doc-comments are merged, with line-breaks, into a single string without a final + /// termination line-break. + /// + /// Leading white-spaces are stripped, each string always starting with the corresponding + /// doc-comment leader: `///` or `/**`. + /// + /// Each line in non-block doc-comments starts with `///`. #[cfg(feature = "metadata")] pub comments: Box<[crate::SmartString]>, } @@ -42,14 +55,14 @@ impl CustomTypesCollection { /// Register a custom type. #[inline(always)] pub fn add(&mut self, type_name: impl Into, name: impl Into) { - self.add_raw( - type_name, - CustomTypeInfo { - display_name: name.into(), - #[cfg(feature = "metadata")] - comments: <_>::default(), - }, - ); + let type_name = type_name.into(); + let custom_type = CustomTypeInfo { + type_name: type_name.clone(), + display_name: name.into(), + #[cfg(feature = "metadata")] + comments: <_>::default(), + }; + self.add_raw(type_name, custom_type); } /// Register a custom type with doc-comments. /// Exported under the `metadata` feature only. @@ -61,13 +74,13 @@ impl CustomTypesCollection { name: impl Into, comments: impl IntoIterator, ) { - self.add_raw( - type_name, - CustomTypeInfo { - display_name: name.into(), - comments: comments.into_iter().map(Into::into).collect(), - }, - ); + let type_name = type_name.into(); + let custom_type = CustomTypeInfo { + type_name: type_name.clone(), + display_name: name.into(), + comments: comments.into_iter().map(Into::into).collect(), + }; + self.add_raw(type_name, custom_type); } /// Register a custom type. #[inline(always)] @@ -75,6 +88,7 @@ impl CustomTypesCollection { self.add_raw( type_name::(), CustomTypeInfo { + type_name: type_name::().into(), display_name: name.into(), #[cfg(feature = "metadata")] comments: <_>::default(), @@ -89,6 +103,7 @@ impl CustomTypesCollection { self.add_raw( type_name::(), CustomTypeInfo { + type_name: type_name::().into(), display_name: name.into(), #[cfg(feature = "metadata")] comments: comments.iter().map(|&s| s.into()).collect(), diff --git a/src/types/mod.rs b/src/types/mod.rs index 2e1f1ed3f..5cb3fe952 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -12,6 +12,7 @@ pub mod parse_error; pub mod position; pub mod position_none; pub mod scope; +pub mod var_def; pub mod variant; pub use bloom_filter::BloomFilterU64; @@ -26,6 +27,7 @@ pub use fn_ptr::FnPtr; pub use immutable_string::ImmutableString; pub use interner::StringsInterner; pub use parse_error::{LexError, ParseError, ParseErrorType}; +pub use var_def::VarDefInfo; #[cfg(not(feature = "no_position"))] pub use position::{Position, Span}; diff --git a/src/types/var_def.rs b/src/types/var_def.rs new file mode 100644 index 000000000..2c83bc715 --- /dev/null +++ b/src/types/var_def.rs @@ -0,0 +1,60 @@ +//! Variable definition information. + +#[cfg(feature = "no_std")] +use std::prelude::v1::*; + +/// Information on a variable definition. +#[derive(Debug, Clone, Hash)] +pub struct VarDefInfo<'a> { + /// Name of the variable to be defined. + name: &'a str, + /// `true` if the statement is `const`, otherwise it is `let`. + is_const: bool, + /// The current nesting level, with zero being the global level. + nesting_level: usize, + /// Will the variable _shadow_ an existing variable? + will_shadow: bool, +} + +impl<'a> VarDefInfo<'a> { + /// Create a new [`VarDefInfo`]. + #[inline(always)] + #[must_use] + pub(crate) const fn new( + name: &'a str, + is_const: bool, + nesting_level: usize, + will_shadow: bool, + ) -> Self { + Self { + name, + is_const, + nesting_level, + will_shadow, + } + } + /// Name of the variable to be defined. + #[inline(always)] + #[must_use] + pub const fn name(&self) -> &str { + self.name + } + /// `true` if the statement is `const`, otherwise it is `let`. + #[inline(always)] + #[must_use] + pub const fn is_const(&self) -> bool { + self.is_const + } + /// The current nesting level, with zero being the global level. + #[inline(always)] + #[must_use] + pub const fn nesting_level(&self) -> usize { + self.nesting_level + } + /// Will the variable _shadow_ an existing variable? + #[inline(always)] + #[must_use] + pub const fn will_shadow_other_variables(&self) -> bool { + self.will_shadow + } +} diff --git a/tests/arrays.rs b/tests/arrays.rs index 845d74d0d..0bc6eaccf 100644 --- a/tests/arrays.rs +++ b/tests/arrays.rs @@ -12,148 +12,33 @@ fn test_arrays() { assert_eq!(engine.eval::("let x = [1, 2, 3]; x[1]").unwrap(), 2); assert_eq!(engine.eval::("let x = [1, 2, 3,]; x[1]").unwrap(), 2); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y[1] = 5; y[1]") - .unwrap(), - 5 - ); - assert_eq!( - engine - .eval::(r#"let y = [1, [ 42, 88, "93" ], 3]; y[1][2][1]"#) - .unwrap(), - '3' - ); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y[1] = 5; y[1]").unwrap(), 5); + assert_eq!(engine.eval::(r#"let y = [1, [ 42, 88, "93" ], 3]; y[1][2][1]"#).unwrap(), '3'); assert_eq!(engine.eval::("let y = [1, 2, 3]; y[0]").unwrap(), 1); assert_eq!(engine.eval::("let y = [1, 2, 3]; y[-1]").unwrap(), 3); assert_eq!(engine.eval::("let y = [1, 2, 3]; y[-3]").unwrap(), 1); assert!(engine.eval::("let y = [1, 2, 3]; 2 in y").unwrap()); assert!(engine.eval::("let y = [1, 2, 3]; 42 !in y").unwrap()); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y += 4; y[3]") - .unwrap(), - 4 - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; pad(y, 5, 42); len(y)") - .unwrap(), - 5 - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; pad(y, 5, [42]); len(y)") - .unwrap(), - 5 - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; pad(y, 5, [42, 999, 123]); y[4][0]") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y[1] += 4; y") - .unwrap() - .into_typed_array::() - .unwrap(), - [1, 6, 3] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; extract(y, 1, 10)") - .unwrap() - .into_typed_array::() - .unwrap(), - vec![2, 3] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; extract(y, -3, 1)") - .unwrap() - .into_typed_array::() - .unwrap(), - vec![1] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; extract(y, -99, 2)") - .unwrap() - .into_typed_array::() - .unwrap(), - vec![1, 2] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; extract(y, 99, 1)") - .unwrap() - .into_typed_array::() - .unwrap(), - vec![] as Vec - ); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y += 4; y[3]").unwrap(), 4); + assert_eq!(engine.eval::("let y = [1, 2, 3]; pad(y, 5, 42); len(y)").unwrap(), 5); + assert_eq!(engine.eval::("let y = [1, 2, 3]; pad(y, 5, [42]); len(y)").unwrap(), 5); + assert_eq!(engine.eval::("let y = [1, 2, 3]; pad(y, 5, [42, 999, 123]); y[4][0]").unwrap(), 42); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y[1] += 4; y").unwrap().into_typed_array::().unwrap(), [1, 6, 3]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; extract(y, 1, 10)").unwrap().into_typed_array::().unwrap(), vec![2, 3]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; extract(y, -3, 1)").unwrap().into_typed_array::().unwrap(), vec![1]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; extract(y, -99, 2)").unwrap().into_typed_array::().unwrap(), vec![1, 2]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; extract(y, 99, 1)").unwrap().into_typed_array::().unwrap(), vec![] as Vec); #[cfg(not(feature = "no_object"))] { - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y.push(4); y") - .unwrap() - .into_typed_array::() - .unwrap(), - [1, 2, 3, 4] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y.insert(0, 4); y") - .unwrap() - .into_typed_array::() - .unwrap(), - [4, 1, 2, 3] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y.insert(999, 4); y") - .unwrap() - .into_typed_array::() - .unwrap(), - [1, 2, 3, 4] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y.insert(-2, 4); y") - .unwrap() - .into_typed_array::() - .unwrap(), - [1, 4, 2, 3] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; y.insert(-999, 4); y") - .unwrap() - .into_typed_array::() - .unwrap(), - [4, 1, 2, 3] - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; let z = [42]; y[z.len]") - .unwrap(), - 2 - ); - assert_eq!( - engine - .eval::("let y = [1, 2, [3, 4, 5, 6]]; let z = [42]; y[2][z.len]") - .unwrap(), - 4 - ); - assert_eq!( - engine - .eval::("let y = [1, 2, 3]; let z = [2]; y[z[0]]") - .unwrap(), - 3 - ); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y.push(4); y").unwrap().into_typed_array::().unwrap(), [1, 2, 3, 4]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y.insert(0, 4); y").unwrap().into_typed_array::().unwrap(), [4, 1, 2, 3]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y.insert(999, 4); y").unwrap().into_typed_array::().unwrap(), [1, 2, 3, 4]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y.insert(-2, 4); y").unwrap().into_typed_array::().unwrap(), [1, 4, 2, 3]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; y.insert(-999, 4); y").unwrap().into_typed_array::().unwrap(), [4, 1, 2, 3]); + assert_eq!(engine.eval::("let y = [1, 2, 3]; let z = [42]; y[z.len]").unwrap(), 2); + assert_eq!(engine.eval::("let y = [1, 2, [3, 4, 5, 6]]; let z = [42]; y[2][z.len]").unwrap(), 4); + assert_eq!(engine.eval::("let y = [1, 2, 3]; let z = [2]; y[z[0]]").unwrap(), 3); assert_eq!( engine @@ -238,12 +123,7 @@ fn test_arrays() { ) .unwrap()); - let value = vec![ - String::from("hello"), - String::from("world"), - String::from("foo"), - String::from("bar"), - ]; + let value = vec![String::from("hello"), String::from("world"), String::from("foo"), String::from("bar")]; let array: Dynamic = value.into(); @@ -277,37 +157,16 @@ fn test_array_index_types() { engine.compile("[1, 2, 3][0]['x']").unwrap(); - assert!(matches!( - engine.compile("[1, 2, 3]['x']").unwrap_err().err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); + assert!(matches!(engine.compile("[1, 2, 3]['x']").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); #[cfg(not(feature = "no_float"))] - assert!(matches!( - engine.compile("[1, 2, 3][123.456]").unwrap_err().err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); + assert!(matches!(engine.compile("[1, 2, 3][123.456]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); - assert!(matches!( - engine.compile("[1, 2, 3][()]").unwrap_err().err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); + assert!(matches!(engine.compile("[1, 2, 3][()]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); - assert!(matches!( - engine - .compile(r#"[1, 2, 3]["hello"]"#) - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); + assert!(matches!(engine.compile(r#"[1, 2, 3]["hello"]"#).unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); - assert!(matches!( - engine - .compile("[1, 2, 3][true && false]") - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); + assert!(matches!(engine.compile("[1, 2, 3][true && false]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); } #[test] @@ -370,12 +229,7 @@ fn test_arrays_map_reduce() { assert_eq!(engine.eval::("[1].map(|x| x + 41)[0]").unwrap(), 42); assert_eq!(engine.eval::("[1].map(|| this + 41)[0]").unwrap(), 42); - assert_eq!( - engine - .eval::("let x = [1, 2, 3]; x.for_each(|| this += 41); x[0]") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::("let x = [1, 2, 3]; x.for_each(|| this += 41); x[0]").unwrap(), 42); assert_eq!( engine .eval::( @@ -391,18 +245,8 @@ fn test_arrays_map_reduce() { 12 ); assert_eq!(engine.eval::("([1].map(|x| x + 41))[0]").unwrap(), 42); - assert_eq!( - engine - .eval::("let c = 40; let y = 1; [1].map(|x, i| c + x + y + i)[0]") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::("let x = [1, 2, 3]; x.for_each(|i| this += i); x[2]") - .unwrap(), - 5 - ); + assert_eq!(engine.eval::("let c = 40; let y = 1; [1].map(|x, i| c + x + y + i)[0]").unwrap(), 42); + assert_eq!(engine.eval::("let x = [1, 2, 3]; x.for_each(|i| this += i); x[2]").unwrap(), 5); assert_eq!( engine diff --git a/tests/assignments.rs b/tests/assignments.rs index 58f480327..c8803bb9a 100644 --- a/tests/assignments.rs +++ b/tests/assignments.rs @@ -8,66 +8,29 @@ fn test_assignments() { assert_eq!(engine.eval::("let x = 42; x += 123; x").unwrap(), 165); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::("let x = [42]; x[0] += 123; x[0]") - .unwrap(), - 165 - ); + assert_eq!(engine.eval::("let x = [42]; x[0] += 123; x[0]").unwrap(), 165); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("let x = #{a:42}; x.a += 123; x.a") - .unwrap(), - 165 - ); + assert_eq!(engine.eval::("let x = #{a:42}; x.a += 123; x.a").unwrap(), 165); } #[test] fn test_assignments_bad_lhs() { let engine = Engine::new(); - assert_eq!( - *engine.compile("(x+y) = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); - assert_eq!( - *engine.compile("foo(x) = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); - assert_eq!( - *engine.compile("true = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToConstant(String::new()) - ); - assert_eq!( - *engine.compile("123 = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToConstant(String::new()) - ); + assert_eq!(*engine.compile("(x+y) = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); + assert_eq!(*engine.compile("foo(x) = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); + assert_eq!(*engine.compile("true = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToConstant(String::new())); + assert_eq!(*engine.compile("123 = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToConstant(String::new())); #[cfg(not(feature = "no_object"))] { - assert_eq!( - *engine.compile("x.foo() = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); - assert_eq!( - *engine.compile("x.foo().x.y = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); - assert_eq!( - *engine.compile("x.y.z.foo() = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); + assert_eq!(*engine.compile("x.foo() = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); + assert_eq!(*engine.compile("x.foo().x.y = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); + assert_eq!(*engine.compile("x.y.z.foo() = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); #[cfg(not(feature = "no_index"))] - assert_eq!( - *engine.compile("x.foo()[0] = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); + assert_eq!(*engine.compile("x.foo()[0] = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); #[cfg(not(feature = "no_index"))] - assert_eq!( - *engine.compile("x[y].z.foo() = 42;").unwrap_err().err_type(), - ParseErrorType::AssignmentToInvalidLHS(String::new()) - ); + assert_eq!(*engine.compile("x[y].z.foo() = 42;").unwrap_err().err_type(), ParseErrorType::AssignmentToInvalidLHS(String::new())); } } diff --git a/tests/binary_ops.rs b/tests/binary_ops.rs index d8749f02f..e63bd78ec 100644 --- a/tests/binary_ops.rs +++ b/tests/binary_ops.rs @@ -76,61 +76,22 @@ fn test_binary_ops() { assert!(!engine.eval::("42.0 < 42").unwrap()); assert!(engine.eval::("42.0 <= 42").unwrap()); - assert_eq!( - engine.eval::("let x = 10.0; x += 4.0; x").unwrap(), - 14.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x -= 4.0; x").unwrap(), - 6.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x *= 4.0; x").unwrap(), - 40.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x /= 4.0; x").unwrap(), - 2.5 - ); - assert_eq!( - engine.eval::("let x = 10.0; x %= 4.0; x").unwrap(), - 2.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x **= 4.0; x").unwrap(), - 10000.0 - ); - - assert_eq!( - engine.eval::("let x = 10.0; x += 4; x").unwrap(), - 14.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x -= 4; x").unwrap(), - 6.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x *= 4; x").unwrap(), - 40.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x /= 4; x").unwrap(), - 2.5 - ); - assert_eq!( - engine.eval::("let x = 10.0; x %= 4; x").unwrap(), - 2.0 - ); - assert_eq!( - engine.eval::("let x = 10.0; x **= 4; x").unwrap(), - 10000.0 - ); + assert_eq!(engine.eval::("let x = 10.0; x += 4.0; x").unwrap(), 14.0); + assert_eq!(engine.eval::("let x = 10.0; x -= 4.0; x").unwrap(), 6.0); + assert_eq!(engine.eval::("let x = 10.0; x *= 4.0; x").unwrap(), 40.0); + assert_eq!(engine.eval::("let x = 10.0; x /= 4.0; x").unwrap(), 2.5); + assert_eq!(engine.eval::("let x = 10.0; x %= 4.0; x").unwrap(), 2.0); + assert_eq!(engine.eval::("let x = 10.0; x **= 4.0; x").unwrap(), 10000.0); + + assert_eq!(engine.eval::("let x = 10.0; x += 4; x").unwrap(), 14.0); + assert_eq!(engine.eval::("let x = 10.0; x -= 4; x").unwrap(), 6.0); + assert_eq!(engine.eval::("let x = 10.0; x *= 4; x").unwrap(), 40.0); + assert_eq!(engine.eval::("let x = 10.0; x /= 4; x").unwrap(), 2.5); + assert_eq!(engine.eval::("let x = 10.0; x %= 4; x").unwrap(), 2.0); + assert_eq!(engine.eval::("let x = 10.0; x **= 4; x").unwrap(), 10000.0); } - assert_eq!( - engine.eval::(r#""hello" + ", world""#).unwrap(), - "hello, world" - ); + assert_eq!(engine.eval::(r#""hello" + ", world""#).unwrap(), "hello, world"); assert_eq!(engine.eval::(r#""hello" + '!'"#).unwrap(), "hello!"); assert_eq!(engine.eval::(r#""hello" - "el""#).unwrap(), "hlo"); assert_eq!(engine.eval::(r#""hello" - 'l'"#).unwrap(), "heo"); diff --git a/tests/bit_fields.rs b/tests/bit_fields.rs index 247c39de6..4802c24b9 100644 --- a/tests/bit_fields.rs +++ b/tests/bit_fields.rs @@ -19,51 +19,20 @@ fn test_bit_fields() { assert!(!engine.eval::("let x = 10; x[0]").unwrap()); assert!(engine.eval::("let x = 10; x[1]").unwrap()); assert!(!engine.eval::("let x = 10; x[-1]").unwrap()); - assert_eq!( - engine - .eval::("let x = 10; x[0] = true; x[1] = false; x") - .unwrap(), - 9 - ); - assert_eq!( - engine.eval::("let x = 10; get_bits(x, 1, 3)").unwrap(), - 5 - ); + assert_eq!(engine.eval::("let x = 10; x[0] = true; x[1] = false; x").unwrap(), 9); + assert_eq!(engine.eval::("let x = 10; get_bits(x, 1, 3)").unwrap(), 5); assert_eq!(engine.eval::("let x = 10; x[1..=3]").unwrap(), 5); assert!(engine.eval::("let x = 10; x[1..99]").is_err()); assert!(engine.eval::("let x = 10; x[-1..3]").is_err()); - assert_eq!( - engine - .eval::("let x = 10; set_bits(x, 1, 3, 7); x") - .unwrap(), - 14 - ); + assert_eq!(engine.eval::("let x = 10; set_bits(x, 1, 3, 7); x").unwrap(), 14); #[cfg(target_pointer_width = "64")] #[cfg(not(feature = "only_i32"))] { - assert_eq!( - engine - .eval::("let x = 255; get_bits(x, -60, 2)") - .unwrap(), - 3 - ); - assert_eq!( - engine - .eval::("let x = 0; set_bits(x, -64, 1, 15); x") - .unwrap(), - 1 - ); - assert_eq!( - engine - .eval::("let x = 0; set_bits(x, -60, 2, 15); x") - .unwrap(), - 0b00110000 - ); + assert_eq!(engine.eval::("let x = 255; get_bits(x, -60, 2)").unwrap(), 3); + assert_eq!(engine.eval::("let x = 0; set_bits(x, -64, 1, 15); x").unwrap(), 1); + assert_eq!(engine.eval::("let x = 0; set_bits(x, -60, 2, 15); x").unwrap(), 0b00110000); } - assert_eq!( - engine.eval::("let x = 10; x[1..4] = 7; x").unwrap(), - 14 - ); + assert_eq!(engine.eval::("let x = 10; x[1..4] = 7; x").unwrap(), 14); assert_eq!( engine .eval::( diff --git a/tests/blobs.rs b/tests/blobs.rs index 2a54292bc..d739ad61b 100644 --- a/tests/blobs.rs +++ b/tests/blobs.rs @@ -10,99 +10,27 @@ fn test_blobs() { let mut scope = Scope::new(); scope.push("x", a); - assert_eq!( - engine.eval_with_scope::(&mut scope, "x[1]").unwrap(), - 2 - ); - assert_eq!( - engine.eval_with_scope::(&mut scope, "x[0]").unwrap(), - 1 - ); - assert_eq!( - engine.eval_with_scope::(&mut scope, "x[-1]").unwrap(), - 3 - ); - assert_eq!( - engine.eval_with_scope::(&mut scope, "x[-3]").unwrap(), - 1 - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x += 4; x[3]") - .unwrap(), - 4 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "x[1]").unwrap(), 2); + assert_eq!(engine.eval_with_scope::(&mut scope, "x[0]").unwrap(), 1); + assert_eq!(engine.eval_with_scope::(&mut scope, "x[-1]").unwrap(), 3); + assert_eq!(engine.eval_with_scope::(&mut scope, "x[-3]").unwrap(), 1); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x += 4; x[3]").unwrap(), 4); #[cfg(not(feature = "no_object"))] { - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x.push(4); x") - .unwrap(), - [1, 2, 3, 4] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x.insert(0, 4); x") - .unwrap(), - [4, 1, 2, 3] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x.insert(999, 4); x") - .unwrap(), - [1, 2, 3, 4] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x.insert(-2, 4); x") - .unwrap(), - [1, 4, 2, 3] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x.insert(-999, 4); x") - .unwrap(), - [4, 1, 2, 3] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "let z = [42]; x[z.len]") - .unwrap(), - 2 - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "let z = [2]; x[z[0]]") - .unwrap(), - 3 - ); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x.push(4); x").unwrap(), [1, 2, 3, 4]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x.insert(0, 4); x").unwrap(), [4, 1, 2, 3]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x.insert(999, 4); x").unwrap(), [1, 2, 3, 4]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x.insert(-2, 4); x").unwrap(), [1, 4, 2, 3]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x.insert(-999, 4); x").unwrap(), [4, 1, 2, 3]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "let z = [42]; x[z.len]").unwrap(), 2); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "let z = [2]; x[z[0]]").unwrap(), 3); } - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x += x; x") - .unwrap(), - [1, 2, 3, 1, 2, 3] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x + x") - .unwrap(), - [1, 2, 3, 1, 2, 3] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x += 999; x") - .unwrap(), - [1, 2, 3, 0xe7] - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope.clone(), "x[2] = 999; x") - .unwrap(), - [1, 2, 0xe7] - ); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x += x; x").unwrap(), [1, 2, 3, 1, 2, 3]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x + x").unwrap(), [1, 2, 3, 1, 2, 3]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x += 999; x").unwrap(), [1, 2, 3, 0xe7]); + assert_eq!(engine.eval_with_scope::(&mut scope.clone(), "x[2] = 999; x").unwrap(), [1, 2, 0xe7]); } #[cfg(not(feature = "only_i32"))] @@ -110,94 +38,37 @@ fn test_blobs() { fn test_blobs_parse() { let engine = Engine::new(); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,0)").unwrap(), 0); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,9)").unwrap(), 0x0908070605040302); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2..=11)").unwrap(), 0x0908070605040302); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2..11)").unwrap(), 0x0908070605040302); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_be_int(x,2,10)").unwrap(), 0x0203040506070809); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_be_int(x,2..12)").unwrap(), 0x0203040506070809); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,99)").unwrap(), 0x0f0e0d0c0b); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,2)").unwrap(), 0x0c0b); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-99,99)").unwrap(), 0x0706050403020100); assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,0)") - .unwrap(), - 0 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,9)") - .unwrap(), - 0x0908070605040302 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2..=11)") - .unwrap(), - 0x0908070605040302 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2..11)") - .unwrap(), - 0x0908070605040302 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_be_int(x,2,10)") + .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3, 3, -98765432); parse_be_int(x, 3, 3)") .unwrap(), - 0x0203040506070809 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_be_int(x,2..12)") - .unwrap(), - 0x0203040506070809 + 0xffffff0000000000_u64 as INT ); - assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,99)") + .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3..=5, -98765432); parse_be_int(x, 3..6)") .unwrap(), - 0x0f0e0d0c0b + 0xffffff0000000000_u64 as INT ); - assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,2)") + .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_le(x, 3, 3, -98765432); parse_le_int(x, 3, 3)") .unwrap(), - 0x0c0b + 0x1cf588 ); - assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-99,99)") + .eval::("let x = blob(16, 0); write_be(x, 0, 8, 0x1234567890abcdef); write_be(x, 8, 8, 0xabcdef1234567890); x") .unwrap(), - 0x0706050403020100 - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3, 3, -98765432); parse_be_int(x, 3, 3)" - ).unwrap(), - 0xffffff0000000000_u64 as INT - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3..=5, -98765432); parse_be_int(x, 3..6)" - ).unwrap(), - 0xffffff0000000000_u64 as INT - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_le(x, 3, 3, -98765432); parse_le_int(x, 3, 3)" - ).unwrap(), - 0x1cf588 - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); write_be(x, 0, 8, 0x1234567890abcdef); write_be(x, 8, 8, 0xabcdef1234567890); x" - ).unwrap(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90] ); } @@ -207,66 +78,28 @@ fn test_blobs_parse() { fn test_blobs_parse() { let engine = Engine::new(); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,0)").unwrap(), 0); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,9)").unwrap(), 0x05040302); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_be_int(x,2,10)").unwrap(), 0x02030405); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,99)").unwrap(), 0x0e0d0c0b); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,2)").unwrap(), 0x0c0b); + assert_eq!(engine.eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-99,99)").unwrap(), 0x03020100); assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,0)") - .unwrap(), - 0 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,2,9)") - .unwrap(), - 0x05040302 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_be_int(x,2,10)") - .unwrap(), - 0x02030405 - ); - - assert_eq!( - engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,99)") + .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3, 3, -98765432); parse_be_int(x, 3, 3)") .unwrap(), - 0x0e0d0c0b + 0xfa1cf500_u32 as INT ); - assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-5,2)") + .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3..=5, -98765432); parse_be_int(x, 3..6)") .unwrap(), - 0x0c0b + 0xfa1cf500_u32 as INT ); - assert_eq!( engine - .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } parse_le_int(x,-99,99)") + .eval::("let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_le(x, 3, 3, -98765432); parse_le_int(x, 3, 3)") .unwrap(), - 0x03020100 - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3, 3, -98765432); parse_be_int(x, 3, 3)" - ).unwrap(), - 0xfa1cf500_u32 as INT - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_be(x, 3..=5, -98765432); parse_be_int(x, 3..6)" - ).unwrap(), - 0xfa1cf500_u32 as INT - ); - - assert_eq!( - engine.eval::( - "let x = blob(16, 0); for n in 0..16 { x[n] = n; } write_le(x, 3, 3, -98765432); parse_le_int(x, 3, 3)" - ).unwrap(), 0x1cf588 ); } @@ -275,40 +108,9 @@ fn test_blobs_parse() { fn test_blobs_write_string() { let engine = Engine::new(); - assert_eq!( - engine - .eval::(r#"let x = blob(16, 0); write_ascii(x, 0, 14, "hello, world!"); x"#) - .unwrap(), - "hello, world!\0\0\0".as_bytes() - ); - - assert_eq!( - engine - .eval::(r#"let x = blob(10, 0); write_ascii(x, 3..8, "hello, world!"); x"#) - .unwrap(), - "\0\0\0hello\0\0".as_bytes() - ); - - assert_eq!( - engine - .eval::( - r#"let x = blob(10, 0); write_ascii(x, 0..9, "❤ hello, ❤ world! ❤❤❤"); x"# - ) - .unwrap(), - " hello, \0".as_bytes() - ); - - assert_eq!( - engine - .eval::(r#"let x = blob(10, 0); write_utf8(x, 3..9, "❤❤❤❤"); x"#) - .unwrap(), - "\0\0\0\u{2764}\u{2764}\0".as_bytes() - ); - - assert_eq!( - engine - .eval::(r#"let x = blob(10, 0); write_utf8(x, 3..7, "❤❤❤❤"); x"#) - .unwrap(), - vec![0, 0, 0, 226, 157, 164, 226, 0, 0, 0] - ); + assert_eq!(engine.eval::(r#"let x = blob(16, 0); write_ascii(x, 0, 14, "hello, world!"); x"#).unwrap(), "hello, world!\0\0\0".as_bytes()); + assert_eq!(engine.eval::(r#"let x = blob(10, 0); write_ascii(x, 3..8, "hello, world!"); x"#).unwrap(), "\0\0\0hello\0\0".as_bytes()); + assert_eq!(engine.eval::(r#"let x = blob(10, 0); write_ascii(x, 0..9, "❤ hello, ❤ world! ❤❤❤"); x"#).unwrap(), " hello, \0".as_bytes()); + assert_eq!(engine.eval::(r#"let x = blob(10, 0); write_utf8(x, 3..9, "❤❤❤❤"); x"#).unwrap(), "\0\0\0\u{2764}\u{2764}\0".as_bytes()); + assert_eq!(engine.eval::(r#"let x = blob(10, 0); write_utf8(x, 3..7, "❤❤❤❤"); x"#).unwrap(), vec![0, 0, 0, 226, 157, 164, 226, 0, 0, 0]); } diff --git a/tests/build_type.rs b/tests/build_type.rs index bd8505f46..550943d52 100644 --- a/tests/build_type.rs +++ b/tests/build_type.rs @@ -37,10 +37,7 @@ fn build_type() { 0 => Ok(self.x), 1 => Ok(self.y), 2 => Ok(self.z), - _ => Err(Box::new(EvalAltResult::ErrorIndexNotFound( - idx.into(), - Position::NONE, - ))), + _ => Err(Box::new(EvalAltResult::ErrorIndexNotFound(idx.into(), Position::NONE))), } } } diff --git a/tests/call_fn.rs b/tests/call_fn.rs index a1441a709..23273dcd0 100644 --- a/tests/call_fn.rs +++ b/tests/call_fn.rs @@ -31,48 +31,28 @@ fn test_call_fn() { ) .unwrap(); - let r = engine - .call_fn::(&mut scope, &ast, "hello", (42 as INT, 123 as INT)) - .unwrap(); + let r = engine.call_fn::(&mut scope, &ast, "hello", (42 as INT, 123 as INT)).unwrap(); assert_eq!(r, 165); - let r = engine - .call_fn::(&mut scope, &ast, "hello", (123 as INT,)) - .unwrap(); + let r = engine.call_fn::(&mut scope, &ast, "hello", (123 as INT,)).unwrap(); assert_eq!(r, 5166); - let r = engine - .call_fn::(&mut scope, &ast, "hello", ()) - .unwrap(); + let r = engine.call_fn::(&mut scope, &ast, "hello", ()).unwrap(); assert_eq!(r, 42); - assert_eq!( - scope - .get_value::("foo") - .expect("variable foo should exist"), - 1 - ); + assert_eq!(scope.get_value::("foo").expect("variable foo should exist"), 1); - let r = engine - .call_fn::(&mut scope, &ast, "define_var", (2 as INT,)) - .unwrap(); + let r = engine.call_fn::(&mut scope, &ast, "define_var", (2 as INT,)).unwrap(); assert_eq!(r, 42); assert!(!scope.contains("bar")); let options = CallFnOptions::new().eval_ast(false).rewind_scope(false); - let r = engine - .call_fn_with_options::(options, &mut scope, &ast, "define_var", (2 as INT,)) - .unwrap(); + let r = engine.call_fn_with_options::(options, &mut scope, &ast, "define_var", (2 as INT,)).unwrap(); assert_eq!(r, 42); - assert_eq!( - scope - .get_value::("bar") - .expect("variable bar should exist"), - 21 - ); + assert_eq!(scope.get_value::("bar").expect("variable bar should exist"), 21); assert!(!scope.contains("scale")); } @@ -98,13 +78,7 @@ fn test_call_fn_scope() { for _ in 0..50 { assert_eq!( engine - .call_fn_with_options::( - CallFnOptions::new().rewind_scope(false), - &mut scope, - &ast, - "foo", - [Dynamic::THREE], - ) + .call_fn_with_options::(CallFnOptions::new().rewind_scope(false), &mut scope, &ast, "foo", [Dynamic::THREE],) .unwrap(), 168 ); @@ -129,11 +103,7 @@ impl FuncArgs for Options { #[test] fn test_call_fn_args() { - let options = Options { - foo: false, - bar: "world".to_string(), - baz: 42, - }; + let options = Options { foo: false, bar: "world".to_string(), baz: 42 }; let engine = Engine::new(); let mut scope = Scope::new(); @@ -148,9 +118,7 @@ fn test_call_fn_args() { ) .unwrap(); - let result = engine - .call_fn::(&mut scope, &ast, "hello", options) - .unwrap(); + let result = engine.call_fn::(&mut scope, &ast, "hello", options).unwrap(); assert_eq!(result, "world42"); } @@ -162,16 +130,12 @@ fn test_call_fn_private() { let ast = engine.compile("fn add(x, n) { x + n }").unwrap(); - let r = engine - .call_fn::(&mut scope, &ast, "add", (40 as INT, 2 as INT)) - .unwrap(); + let r = engine.call_fn::(&mut scope, &ast, "add", (40 as INT, 2 as INT)).unwrap(); assert_eq!(r, 42); let ast = engine.compile("private fn add(x, n, ) { x + n }").unwrap(); - let r = engine - .call_fn::(&mut scope, &ast, "add", (40 as INT, 2 as INT)) - .unwrap(); + let r = engine.call_fn::(&mut scope, &ast, "add", (40 as INT, 2 as INT)).unwrap(); assert_eq!(r, 42); } @@ -182,21 +146,13 @@ fn test_fn_ptr_raw() { engine .register_fn("mul", |x: &mut INT, y: INT| *x *= y) - .register_raw_fn( - "bar", - [ - TypeId::of::(), - TypeId::of::(), - TypeId::of::(), - ], - move |context, args| { - let fp = args[1].take().cast::(); - let value = args[2].clone(); - let this_ptr = args.get_mut(0).unwrap(); - - fp.call_raw(&context, Some(this_ptr), [value]) - }, - ); + .register_raw_fn("bar", [TypeId::of::(), TypeId::of::(), TypeId::of::()], move |context, args| { + let fp = args[1].take().cast::(); + let value = args[2].clone(); + let this_ptr = args.get_mut(0).unwrap(); + + fp.call_raw(&context, Some(this_ptr), [value]) + }); assert_eq!( engine @@ -260,40 +216,16 @@ fn test_fn_ptr_raw() { #[test] fn test_anonymous_fn() { - let calc_func = Func::<(INT, INT, INT), INT>::create_from_script( - Engine::new(), - "fn calc(x, y, z,) { (x + y) * z }", - "calc", - ) - .unwrap(); - + let calc_func = Func::<(INT, INT, INT), INT>::create_from_script(Engine::new(), "fn calc(x, y, z,) { (x + y) * z }", "calc").unwrap(); assert_eq!(calc_func(42, 123, 9).unwrap(), 1485); - let calc_func = Func::<(INT, String, INT), INT>::create_from_script( - Engine::new(), - "fn calc(x, y, z) { (x + len(y)) * z }", - "calc", - ) - .unwrap(); - + let calc_func = Func::<(INT, String, INT), INT>::create_from_script(Engine::new(), "fn calc(x, y, z) { (x + len(y)) * z }", "calc").unwrap(); assert_eq!(calc_func(42, "hello".to_string(), 9).unwrap(), 423); - let calc_func = Func::<(INT, String, INT), INT>::create_from_script( - Engine::new(), - "private fn calc(x, y, z) { (x + len(y)) * z }", - "calc", - ) - .unwrap(); - + let calc_func = Func::<(INT, String, INT), INT>::create_from_script(Engine::new(), "private fn calc(x, y, z) { (x + len(y)) * z }", "calc").unwrap(); assert_eq!(calc_func(42, "hello".to_string(), 9).unwrap(), 423); - let calc_func = Func::<(INT, &str, INT), INT>::create_from_script( - Engine::new(), - "fn calc(x, y, z) { (x + len(y)) * z }", - "calc", - ) - .unwrap(); - + let calc_func = Func::<(INT, &str, INT), INT>::create_from_script(Engine::new(), "fn calc(x, y, z) { (x + len(y)) * z }", "calc").unwrap(); assert_eq!(calc_func(42, "hello", 9).unwrap(), 423); } @@ -356,9 +288,7 @@ fn test_call_fn_events() { "update" => engine .call_fn(scope, ast, "update", (event_data,)) .or_else(|err| match *err { - EvalAltResult::ErrorFunctionNotFound(fn_name, ..) - if fn_name.starts_with("update") => - { + EvalAltResult::ErrorFunctionNotFound(fn_name, ..) if fn_name.starts_with("update") => { // Default implementation of 'update' event handler self.scope.set_value("state", true); // Turn function-not-found into a success diff --git a/tests/chars.rs b/tests/chars.rs index 7adb76299..772a58d90 100644 --- a/tests/chars.rs +++ b/tests/chars.rs @@ -10,15 +10,9 @@ fn test_chars() { assert_eq!(engine.eval::(r"'\u2764'").unwrap(), '❤'); #[cfg(not(feature = "no_index"))] - { - assert_eq!(engine.eval::(r#"let x="hello"; x[2]"#).unwrap(), 'l'); - assert_eq!( - engine - .eval::(r#"let y="hello"; y[2]='$'; y"#) - .unwrap(), - "he$lo" - ); - } + assert_eq!(engine.eval::(r#"let x="hello"; x[2]"#).unwrap(), 'l'); + #[cfg(not(feature = "no_index"))] + assert_eq!(engine.eval::(r#"let y="hello"; y[2]='$'; y"#).unwrap(), "he$lo"); assert!(engine.eval::(r"'\uhello'").is_err()); assert!(engine.eval::("''").is_err()); diff --git a/tests/closures.rs b/tests/closures.rs index bcb095d15..89585d8ff 100644 --- a/tests/closures.rs +++ b/tests/closures.rs @@ -12,14 +12,10 @@ use rhai::Map; fn test_fn_ptr_curry_call() { let mut engine = Engine::new(); - engine.register_raw_fn( - "call_with_arg", - [TypeId::of::(), TypeId::of::()], - |context, args| { - let fn_ptr = args[0].take().cast::(); - fn_ptr.call_raw(&context, None, [args[1].take()]) - }, - ); + engine.register_raw_fn("call_with_arg", [TypeId::of::(), TypeId::of::()], |context, args| { + let fn_ptr = args[0].take().cast::(); + fn_ptr.call_raw(&context, None, [args[1].take()]) + }); #[cfg(not(feature = "no_object"))] assert_eq!( @@ -46,10 +42,7 @@ fn test_closures() { scope.push("x", 42 as INT); - assert!(matches!( - engine.compile_expression("|x| {}").unwrap_err().err_type(), - ParseErrorType::BadInput(..) - )); + assert!(matches!(engine.compile_expression("|x| {}").unwrap_err().err_type(), ParseErrorType::BadInput(..))); assert_eq!( engine @@ -178,15 +171,11 @@ fn test_closures() { 42 ); - engine.register_raw_fn( - "custom_call", - [TypeId::of::(), TypeId::of::()], - |context, args| { - let func = take(args[1]).cast::(); + engine.register_raw_fn("custom_call", [TypeId::of::(), TypeId::of::()], |context, args| { + let func = take(args[1]).cast::(); - func.call_raw(&context, None, []) - }, - ); + func.call_raw(&context, None, []) + }); assert_eq!( engine @@ -333,17 +322,9 @@ fn test_closures_shared_obj() { // Register API on TestStruct engine .register_type_with_name::("TestStruct") - .register_get_set( - "data", - |p: &mut TestStruct| *p.borrow(), - |p: &mut TestStruct, value: INT| *p.borrow_mut() = value, - ) - .register_fn("+=", |p1: &mut TestStruct, p2: TestStruct| { - *p1.borrow_mut() += *p2.borrow() - }) - .register_fn("-=", |p1: &mut TestStruct, p2: TestStruct| { - *p1.borrow_mut() -= *p2.borrow() - }); + .register_get_set("data", |p: &mut TestStruct| *p.borrow(), |p: &mut TestStruct, value: INT| *p.borrow_mut() = value) + .register_fn("+=", |p1: &mut TestStruct, p2: TestStruct| *p1.borrow_mut() += *p2.borrow()) + .register_fn("-=", |p1: &mut TestStruct, p2: TestStruct| *p1.borrow_mut() -= *p2.borrow()); let engine = engine; // Make engine immutable @@ -418,9 +399,7 @@ fn test_closures_callback() { } fn phaser(callback: impl Fn(INT) -> Result> + 'static) -> impl Node { - PhaserNode { - func: Box::new(callback), - } + PhaserNode { func: Box::new(callback) } } let mut engine = Engine::new(); diff --git a/tests/comments.rs b/tests/comments.rs index a44a9a2c3..3dcacc618 100644 --- a/tests/comments.rs +++ b/tests/comments.rs @@ -4,12 +4,7 @@ use rhai::{Engine, INT}; fn test_comments() { let engine = Engine::new(); - assert_eq!( - engine - .eval::("let x = 42; x // I am a single line comment, yay!") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::("let x = 42; x // I am a single line comment, yay!").unwrap(), 42); assert_eq!( engine @@ -45,10 +40,7 @@ fn test_comments_doc() { ) .unwrap(); - assert_eq!( - ast.iter_functions().next().unwrap().comments[0], - "/// Hello world" - ); + assert_eq!(ast.iter_functions().next().unwrap().comments[0], "/// Hello world"); assert!(engine .compile( @@ -84,15 +76,9 @@ fn test_comments_doc() { .unwrap(); #[cfg(not(feature = "no_position"))] - assert_eq!( - ast.iter_functions().next().unwrap().comments[0], - "/** Hello world\n** how are you?\n**/" - ); + assert_eq!(ast.iter_functions().next().unwrap().comments[0], "/** Hello world\n** how are you?\n**/"); #[cfg(feature = "no_position")] - assert_eq!( - ast.iter_functions().next().unwrap().comments[0], - "/** Hello world\n ** how are you?\n **/", - ); + assert_eq!(ast.iter_functions().next().unwrap().comments[0], "/** Hello world\n ** how are you?\n **/",); assert!(engine .compile( diff --git a/tests/constants.rs b/tests/constants.rs index 2bcf48731..cb8c810b2 100644 --- a/tests/constants.rs +++ b/tests/constants.rs @@ -7,9 +7,7 @@ fn test_constant() { assert_eq!(engine.eval::("const x = 123; x").unwrap(), 123); assert!(matches!( - *engine - .eval::("const x = 123; x = 42;") - .expect_err("expects error"), + *engine.eval::("const x = 123; x = 42;").expect_err("expects error"), EvalAltResult::ErrorParsing(ParseErrorType::AssignmentToConstant(x), ..) if x == "x" )); @@ -120,10 +118,5 @@ fn test_constant_mut() { 42 ); - assert!(matches!( - *engine - .run_with_scope(&mut scope, "MY_NUMBER.value = 42;") - .unwrap_err(), - EvalAltResult::ErrorNonPureMethodCallOnConstant(..) - )); + assert!(matches!(*engine.run_with_scope(&mut scope, "MY_NUMBER.value = 42;").unwrap_err(), EvalAltResult::ErrorNonPureMethodCallOnConstant(..))); } diff --git a/tests/custom_syntax.rs b/tests/custom_syntax.rs index c1aa3f616..42fc637ca 100644 --- a/tests/custom_syntax.rs +++ b/tests/custom_syntax.rs @@ -1,8 +1,6 @@ #![cfg(not(feature = "no_custom_syntax"))] -use rhai::{ - Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseErrorType, Position, Scope, INT, -}; +use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseErrorType, Position, Scope, INT}; #[test] fn test_custom_syntax() { @@ -12,30 +10,16 @@ fn test_custom_syntax() { // Disable 'while' and make sure it still works with custom syntax engine.disable_symbol("while"); - assert!(matches!( - engine.compile("while false {}").unwrap_err().err_type(), - ParseErrorType::Reserved(err) if err == "while" - )); - assert!(matches!( - engine.compile("let while = 0").unwrap_err().err_type(), - ParseErrorType::Reserved(err) if err == "while" - )); + assert!(matches!(engine.compile("while false {}").unwrap_err().err_type(), ParseErrorType::Reserved(err) if err == "while")); + assert!(matches!(engine.compile("let while = 0").unwrap_err().err_type(), ParseErrorType::Reserved(err) if err == "while")); // Implement ternary operator engine - .register_custom_syntax( - ["iff", "$expr$", "?", "$expr$", ":", "$expr$"], - false, - |context, inputs| match context.eval_expression_tree(&inputs[0]).unwrap().as_bool() { - Ok(true) => context.eval_expression_tree(&inputs[1]), - Ok(false) => context.eval_expression_tree(&inputs[2]), - Err(typ) => Err(Box::new(EvalAltResult::ErrorMismatchDataType( - "bool".to_string(), - typ.to_string(), - inputs[0].position(), - ))), - }, - ) + .register_custom_syntax(["iff", "$expr$", "?", "$expr$", ":", "$expr$"], false, |context, inputs| match context.eval_expression_tree(&inputs[0]).unwrap().as_bool() { + Ok(true) => context.eval_expression_tree(&inputs[1]), + Ok(false) => context.eval_expression_tree(&inputs[2]), + Err(typ) => Err(Box::new(EvalAltResult::ErrorMismatchDataType("bool".to_string(), typ.to_string(), inputs[0].position()))), + }) .unwrap(); assert_eq!( @@ -66,81 +50,61 @@ fn test_custom_syntax() { // Custom syntax engine - .register_custom_syntax( - [ - "exec", "[", "$ident$", "$symbol$", "$int$", "]", "->", "$block$", "while", - "$expr$", - ], - true, - |context, inputs| { - let var_name = inputs[0].get_string_value().unwrap(); - let op = inputs[1].get_literal_value::().unwrap(); - let max = inputs[2].get_literal_value::().unwrap(); - let stmt = &inputs[3]; - let condition = &inputs[4]; - - context.scope_mut().push(var_name.to_string(), 0 as INT); - - let mut count: INT = 0; - - loop { - let done = match op.as_str() { - "<" => count >= max, - "<=" => count > max, - ">" => count <= max, - ">=" => count < max, - "==" => count != max, - "!=" => count == max, - _ => return Err(format!("Unsupported operator: {op}").into()), - }; - - if done { - break; - } + .register_custom_syntax(["exec", "[", "$ident$", "$symbol$", "$int$", "]", "->", "$block$", "while", "$expr$"], true, |context, inputs| { + let var_name = inputs[0].get_string_value().unwrap(); + let op = inputs[1].get_literal_value::().unwrap(); + let max = inputs[2].get_literal_value::().unwrap(); + let stmt = &inputs[3]; + let condition = &inputs[4]; + + context.scope_mut().push(var_name.to_string(), 0 as INT); + + let mut count: INT = 0; + + loop { + let done = match op.as_str() { + "<" => count >= max, + "<=" => count > max, + ">" => count <= max, + ">=" => count < max, + "==" => count != max, + "!=" => count == max, + _ => return Err(format!("Unsupported operator: {op}").into()), + }; + + if done { + break; + } - // Do not rewind if the variable is upper-case - let _: Dynamic = if var_name.to_uppercase() == var_name { - #[allow(deprecated)] // not deprecated but unstable - context.eval_expression_tree_raw(stmt, false) - } else { - context.eval_expression_tree(stmt) - }?; - - count += 1; - - context - .scope_mut() - .push(format!("{var_name}{count}"), count); - - let stop = !context - .eval_expression_tree(condition) - .unwrap() - .as_bool() - .map_err(|err| { - Box::new(EvalAltResult::ErrorMismatchDataType( - "bool".to_string(), - err.to_string(), - condition.position(), - )) - }) - .unwrap(); - - if stop { - break; - } + // Do not rewind if the variable is upper-case + let _: Dynamic = if var_name.to_uppercase() == var_name { + #[allow(deprecated)] // not deprecated but unstable + context.eval_expression_tree_raw(stmt, false) + } else { + context.eval_expression_tree(stmt) + }?; + + count += 1; + + context.scope_mut().push(format!("{var_name}{count}"), count); + + let stop = !context + .eval_expression_tree(condition) + .unwrap() + .as_bool() + .map_err(|err| Box::new(EvalAltResult::ErrorMismatchDataType("bool".to_string(), err.to_string(), condition.position()))) + .unwrap(); + + if stop { + break; } + } - Ok(count.into()) - }, - ) + Ok(count.into()) + }) .unwrap(); - assert!(matches!( - *engine - .run("let foo = (exec [x<<15] -> { x += 2 } while x < 42) * 10;") - .unwrap_err(), - EvalAltResult::ErrorRuntime(..) - )); + assert!(matches!(*engine.run("let foo = (exec [x<<15] -> { x += 2 } while x < 42) * 10;").unwrap_err(), EvalAltResult::ErrorRuntime(..))); assert_eq!( engine @@ -216,14 +180,8 @@ fn test_custom_syntax() { // The first symbol must be an identifier assert_eq!( - *engine - .register_custom_syntax(["!"], false, |_, _| Ok(Dynamic::UNIT)) - .unwrap_err() - .err_type(), - ParseErrorType::BadInput(LexError::ImproperSymbol( - "!".to_string(), - "Improper symbol for custom syntax at position #1: '!'".to_string() - )) + *engine.register_custom_syntax(["!"], false, |_, _| Ok(Dynamic::UNIT)).unwrap_err().err_type(), + ParseErrorType::BadInput(LexError::ImproperSymbol("!".to_string(), "Improper symbol for custom syntax at position #1: '!'".to_string())) ); // Check self-termination @@ -241,42 +199,28 @@ fn test_custom_syntax() { // Register the custom syntax: var x = ??? engine - .register_custom_syntax( - ["var", "$ident$", "=", "$expr$"], - true, - |context, inputs| { - let var_name = inputs[0].get_string_value().unwrap(); - let expr = &inputs[1]; + .register_custom_syntax(["var", "$ident$", "=", "$expr$"], true, |context, inputs| { + let var_name = inputs[0].get_string_value().unwrap(); + let expr = &inputs[1]; - // Evaluate the expression - let value = context.eval_expression_tree(expr).unwrap(); + // Evaluate the expression + let value = context.eval_expression_tree(expr).unwrap(); - if !context.scope().is_constant(var_name).unwrap_or(false) { - context.scope_mut().set_value(var_name.to_string(), value); - Ok(Dynamic::UNIT) - } else { - Err(format!("variable {var_name} is constant").into()) - } - }, - ) + if !context.scope().is_constant(var_name).unwrap_or(false) { + context.scope_mut().set_value(var_name.to_string(), value); + Ok(Dynamic::UNIT) + } else { + Err(format!("variable {var_name} is constant").into()) + } + }) .unwrap(); let mut scope = Scope::new(); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "var foo = 42; foo") - .unwrap(), - 42 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "var foo = 42; foo").unwrap(), 42); assert_eq!(scope.get_value::("foo"), Some(42)); assert_eq!(scope.len(), 1); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "var foo = 123; foo") - .unwrap(), - 123 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "var foo = 123; foo").unwrap(), 123); assert_eq!(scope.get_value::("foo"), Some(123)); assert_eq!(scope.len(), 1); } @@ -286,50 +230,32 @@ fn test_custom_syntax_scope() { let mut engine = Engine::new(); engine - .register_custom_syntax( - [ - "with", "offset", "(", "$expr$", ",", "$expr$", ")", "$block$", - ], - true, - |context, inputs| { - let x = context - .eval_expression_tree(&inputs[0]) - .unwrap() - .as_int() - .map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchDataType( - "integer".to_string(), - typ.to_string(), - inputs[0].position(), - )) - }) - .unwrap(); + .register_custom_syntax(["with", "offset", "(", "$expr$", ",", "$expr$", ")", "$block$"], true, |context, inputs| { + let x = context + .eval_expression_tree(&inputs[0]) + .unwrap() + .as_int() + .map_err(|typ| Box::new(EvalAltResult::ErrorMismatchDataType("integer".to_string(), typ.to_string(), inputs[0].position()))) + .unwrap(); - let y = context - .eval_expression_tree(&inputs[1]) - .unwrap() - .as_int() - .map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchDataType( - "integer".to_string(), - typ.to_string(), - inputs[1].position(), - )) - }) - .unwrap(); + let y = context + .eval_expression_tree(&inputs[1]) + .unwrap() + .as_int() + .map_err(|typ| Box::new(EvalAltResult::ErrorMismatchDataType("integer".to_string(), typ.to_string(), inputs[1].position()))) + .unwrap(); - let orig_len = context.scope().len(); + let orig_len = context.scope().len(); - context.scope_mut().push_constant("x", x); - context.scope_mut().push_constant("y", y); + context.scope_mut().push_constant("x", x); + context.scope_mut().push_constant("y", y); - let result = context.eval_expression_tree(&inputs[2]); + let result = context.eval_expression_tree(&inputs[2]); - context.scope_mut().rewind(orig_len); + context.scope_mut().rewind(orig_len); - result - }, - ) + result + }) .unwrap(); assert_eq!( @@ -368,19 +294,9 @@ fn test_custom_syntax_matrix() { for x in 0..3 { let offset = y * 3 + x; - match context - .eval_expression_tree(&inputs[offset]) - .unwrap() - .as_int() - { + match context.eval_expression_tree(&inputs[offset]).unwrap().as_int() { Ok(v) => values[y][x] = v, - Err(typ) => { - return Err(Box::new(EvalAltResult::ErrorMismatchDataType( - "integer".to_string(), - typ.to_string(), - inputs[offset].position(), - ))) - } + Err(typ) => return Err(Box::new(EvalAltResult::ErrorMismatchDataType("integer".to_string(), typ.to_string(), inputs[offset].position()))), } } } @@ -424,18 +340,15 @@ fn test_custom_syntax_raw() { *state = Dynamic::FALSE; Ok(Some("$ident$".into())) } - 2 => { - match stream[1].as_str() { - "world" if state.as_bool().unwrap_or(false) => Ok(Some("$$world".into())), - "world" => Ok(Some("$$hello".into())), - "kitty" => { - *state = (42 as INT).into(); - Ok(None) - } - s => Err(LexError::ImproperSymbol(s.to_string(), String::new()) - .into_err(Position::NONE)), + 2 => match stream[1].as_str() { + "world" if state.as_bool().unwrap_or(false) => Ok(Some("$$world".into())), + "world" => Ok(Some("$$hello".into())), + "kitty" => { + *state = (42 as INT).into(); + Ok(None) } - } + s => Err(LexError::ImproperSymbol(s.to_string(), String::new()).into_err(Position::NONE)), + }, _ => unreachable!(), }, true, @@ -459,17 +372,9 @@ fn test_custom_syntax_raw() { assert_eq!(engine.eval::(r#"hello "world""#).unwrap(), 123456); assert_eq!(engine.eval::("hello world").unwrap(), 0); assert_eq!(engine.eval::("hello kitty").unwrap(), 42); - assert_eq!( - engine - .eval::("let foo = 0; (hello kitty) + foo") - .unwrap(), - 1041 - ); + assert_eq!(engine.eval::("let foo = 0; (hello kitty) + foo").unwrap(), 1041); assert_eq!(engine.eval::("(hello kitty) + foo").unwrap(), 1041); - assert_eq!( - *engine.compile("hello hey").unwrap_err().err_type(), - ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string(), String::new())) - ); + assert_eq!(*engine.compile("hello hey").unwrap_err().err_type(), ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string(), String::new()))); } #[test] @@ -488,11 +393,7 @@ fn test_custom_syntax_raw2() { }, false, move |_, inputs, _| { - let id = if inputs.len() == 2 { - -inputs[1].get_literal_value::().unwrap() - } else { - inputs[0].get_literal_value::().unwrap() - }; + let id = if inputs.len() == 2 { -inputs[1].get_literal_value::().unwrap() } else { inputs[0].get_literal_value::().unwrap() }; Ok(id.into()) }, ); diff --git a/tests/data_size.rs b/tests/data_size.rs index 4dd1ec945..a92e50612 100644 --- a/tests/data_size.rs +++ b/tests/data_size.rs @@ -12,21 +12,9 @@ fn test_max_string_size() { let mut engine = Engine::new(); engine.set_max_string_size(10); - assert_eq!( - *engine - .compile(r#"let x = "hello, world!";"#) - .unwrap_err() - .err_type(), - ParseErrorType::LiteralTooLarge("Length of string".to_string(), 10) - ); + assert_eq!(*engine.compile(r#"let x = "hello, world!";"#).unwrap_err().err_type(), ParseErrorType::LiteralTooLarge("Length of string".to_string(), 10)); - assert_eq!( - *engine - .compile(r#"let x = "朝に紅顔、暮に白骨";"#) - .unwrap_err() - .err_type(), - ParseErrorType::LiteralTooLarge("Length of string".to_string(), 10) - ); + assert_eq!(*engine.compile(r#"let x = "朝に紅顔、暮に白骨";"#).unwrap_err().err_type(), ParseErrorType::LiteralTooLarge("Length of string".to_string(), 10)); assert!(matches!( *engine @@ -80,13 +68,7 @@ fn test_max_array_size() { #[cfg(not(feature = "no_object"))] engine.set_max_map_size(10); - assert_eq!( - *engine - .compile("let x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];") - .unwrap_err() - .err_type(), - ParseErrorType::LiteralTooLarge("Size of array literal".to_string(), 10) - ); + assert_eq!(*engine.compile("let x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];").unwrap_err().err_type(), ParseErrorType::LiteralTooLarge("Size of array literal".to_string(), 10)); assert!(matches!( *engine @@ -267,16 +249,8 @@ fn test_max_map_size() { engine.set_max_array_size(10); assert_eq!( - *engine - .compile( - "let x = #{a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15};" - ) - .unwrap_err() - .err_type(), - ParseErrorType::LiteralTooLarge( - "Number of properties in object map literal".to_string(), - 10 - ) + *engine.compile("let x = #{a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15};").unwrap_err().err_type(), + ParseErrorType::LiteralTooLarge("Number of properties in object map literal".to_string(), 10) ); assert!(matches!( diff --git a/tests/debugging.rs b/tests/debugging.rs index 59b066a59..811666e8f 100644 --- a/tests/debugging.rs +++ b/tests/debugging.rs @@ -11,10 +11,7 @@ use rhai::Map; fn test_debugging() { let mut engine = Engine::new(); - engine.register_debugger( - |_, dbg| dbg, - |_, _, _, _, _| Ok(rhai::debugger::DebuggerCommand::Continue), - ); + engine.register_debugger(|_, dbg| dbg, |_, _, _, _, _| Ok(rhai::debugger::DebuggerCommand::Continue)); #[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_index"))] @@ -58,18 +55,10 @@ fn test_debugger_state() { }, |mut context, _, _, _, _| { // Print debugger state - which is an object map - println!( - "Current state = {}", - context.global_runtime_state().debugger().state() - ); + println!("Current state = {}", context.global_runtime_state().debugger().state()); // Modify state - let mut state = context - .global_runtime_state_mut() - .debugger_mut() - .state_mut() - .write_lock::() - .unwrap(); + let mut state = context.global_runtime_state_mut().debugger_mut().state_mut().write_lock::().unwrap(); let hello = state.get("hello").unwrap().as_int().unwrap(); state.insert("hello".into(), (hello + 1).into()); state.insert("foo".into(), true.into()); diff --git a/tests/decrement.rs b/tests/decrement.rs index 5e9d41c4d..7a3109967 100644 --- a/tests/decrement.rs +++ b/tests/decrement.rs @@ -5,11 +5,5 @@ fn test_decrement() { let engine = Engine::new(); assert_eq!(engine.eval::("let x = 10; x -= 7; x").unwrap(), 3); - - assert_eq!( - engine - .eval::(r#"let s = "test"; s -= 's'; s"#) - .unwrap(), - "tet" - ); + assert_eq!(engine.eval::(r#"let s = "test"; s -= 's'; s"#).unwrap(), "tet"); } diff --git a/tests/eval.rs b/tests/eval.rs index 62deb44a0..91e86ae97 100644 --- a/tests/eval.rs +++ b/tests/eval.rs @@ -148,20 +148,8 @@ fn test_eval_function() { 84 ); - assert_eq!( - scope - .get_value::("x") - .expect("variable x should exist"), - 10 - ); - - assert_eq!( - scope - .get_value::("y") - .expect("variable y should exist"), - 32 - ); - + assert_eq!(scope.get_value::("x").expect("variable x should exist"), 10); + assert_eq!(scope.get_value::("y").expect("variable y should exist"), 32); assert!(scope.contains("script")); assert_eq!(scope.len(), 3); } @@ -173,10 +161,7 @@ fn test_eval_disabled() { engine.disable_symbol("eval"); assert!(matches!( - engine - .compile(r#"eval("40 + 2")"#) - .unwrap_err() - .err_type(), + engine.compile(r#"eval("40 + 2")"#).unwrap_err().err_type(), ParseErrorType::BadInput(LexError::ImproperSymbol(err, ..)) if err == "eval" )); } diff --git a/tests/expressions.rs b/tests/expressions.rs index bbb95a46e..99c43875e 100644 --- a/tests/expressions.rs +++ b/tests/expressions.rs @@ -7,51 +7,21 @@ fn test_expressions() { scope.push("x", 10 as INT); - assert_eq!( - engine.eval_expression::("2 + (10 + 10) * 2").unwrap(), - 42 - ); - assert_eq!( - engine - .eval_expression_with_scope::(&mut scope, "2 + (x + 10) * 2") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else { 123 }") - .unwrap(), - 42 - ); + assert_eq!(engine.eval_expression::("2 + (10 + 10) * 2").unwrap(), 42); + assert_eq!(engine.eval_expression_with_scope::(&mut scope, "2 + (x + 10) * 2").unwrap(), 42); + assert_eq!(engine.eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else { 123 }").unwrap(), 42); #[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_function"))] { - assert_eq!( - engine - .eval_expression_with_scope::( - &mut scope, - "[1, 2, 3, 4].map(|x| x * x).reduce(|a, v| a + v, 0)" - ) - .unwrap(), - 30 - ); + assert_eq!(engine.eval_expression_with_scope::(&mut scope, "[1, 2, 3, 4].map(|x| x * x).reduce(|a, v| a + v, 0)").unwrap(), 30); assert!(engine - .eval_expression_with_scope::( - &mut scope, - "[1, 2, 3, 4].map(|x| { let r = 2; x * r }).reduce(|a, v| a + v, 0)" - ) + .eval_expression_with_scope::(&mut scope, "[1, 2, 3, 4].map(|x| { let r = 2; x * r }).reduce(|a, v| a + v, 0)") .is_err()); } - assert!(engine - .eval_expression_with_scope::(&mut scope, "if x > 0 { let y = 42; y } else { 123 }") - .is_err()); - assert!(engine - .eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else { let y = 123; y }") - .is_err()); - assert!(engine - .eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else {}") - .is_err()); + assert!(engine.eval_expression_with_scope::(&mut scope, "if x > 0 { let y = 42; y } else { 123 }").is_err()); + assert!(engine.eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else { let y = 123; y }").is_err()); + assert!(engine.eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else {}").is_err()); assert_eq!( engine @@ -88,9 +58,7 @@ fn test_expressions() { assert!(engine.compile_expression("40 + { 2 }").is_err()); assert!(engine.compile_expression("x = 42").is_err()); assert!(engine.compile_expression("let x = 42").is_err()); - assert!(engine - .compile_expression("do { break 42; } while true") - .is_err()); + assert!(engine.compile_expression("do { break 42; } while true").is_err()); engine.compile("40 + { let x = 2; x }").unwrap(); } @@ -116,10 +84,7 @@ fn test_expressions_eval() { } // This is your agent - let my_agent = AGENT { - gender: "male".into(), - age: 42, - }; + let my_agent = AGENT { gender: "male".into(), age: 42 }; // Create the engine let mut engine = Engine::new(); diff --git a/tests/float.rs b/tests/float.rs index 286510f6a..887ca46e3 100644 --- a/tests/float.rs +++ b/tests/float.rs @@ -7,15 +7,9 @@ const EPSILON: FLOAT = 0.000_000_000_1; fn test_float() { let engine = Engine::new(); - assert!(engine - .eval::("let x = 0.0; let y = 1.0; x < y") - .unwrap()); - assert!(!engine - .eval::("let x = 0.0; let y = 1.0; x > y") - .unwrap()); - assert!(!engine - .eval::("let x = 0.; let y = 1.; x > y") - .unwrap()); + assert!(engine.eval::("let x = 0.0; let y = 1.0; x < y").unwrap()); + assert!(!engine.eval::("let x = 0.0; let y = 1.0; x > y").unwrap()); + assert!(!engine.eval::("let x = 0.; let y = 1.; x > y").unwrap()); assert!((engine.eval::("let x = 9.9999; x").unwrap() - 9.9999 as FLOAT).abs() < EPSILON); } @@ -32,10 +26,7 @@ fn test_float_scientific() { fn test_float_parse() { let engine = Engine::new(); - assert!( - (engine.eval::(r#"parse_float("9.9999")"#).unwrap() - 9.9999 as FLOAT).abs() - < EPSILON - ); + assert!((engine.eval::(r#"parse_float("9.9999")"#).unwrap() - 9.9999 as FLOAT).abs() < EPSILON); } #[test] @@ -72,34 +63,15 @@ fn test_struct_with_float() { engine.register_fn("update", TestStruct::update); engine.register_fn("new_ts", TestStruct::new); - assert!( - (engine - .eval::("let ts = new_ts(); ts.update(); ts.x") - .unwrap() - - 6.789) - .abs() - < EPSILON - ); - assert!( - (engine - .eval::("let ts = new_ts(); ts.x = 10.1001; ts.x") - .unwrap() - - 10.1001) - .abs() - < EPSILON - ); + assert!((engine.eval::("let ts = new_ts(); ts.update(); ts.x").unwrap() - 6.789).abs() < EPSILON); + assert!((engine.eval::("let ts = new_ts(); ts.x = 10.1001; ts.x").unwrap() - 10.1001).abs() < EPSILON); } #[test] fn test_float_func() { let mut engine = Engine::new(); - engine.register_fn("sum", |x: FLOAT, y: FLOAT, z: FLOAT, w: FLOAT| { - x + y + z + w - }); + engine.register_fn("sum", |x: FLOAT, y: FLOAT, z: FLOAT, w: FLOAT| x + y + z + w); - assert_eq!( - engine.eval::("sum(1.0, 2.0, 3.0, 4.0)").unwrap(), - 10.0 - ); + assert_eq!(engine.eval::("sum(1.0, 2.0, 3.0, 4.0)").unwrap(), 10.0); } diff --git a/tests/fn_ptr.rs b/tests/fn_ptr.rs index 701e2d2f7..f18c63386 100644 --- a/tests/fn_ptr.rs +++ b/tests/fn_ptr.rs @@ -141,9 +141,7 @@ fn test_fn_ptr_curry() { fn test_fn_ptr_call() { let engine = Engine::new(); - let ast = engine - .compile("private fn foo(x, y) { len(x) + y }") - .unwrap(); + let ast = engine.compile("private fn foo(x, y) { len(x) + y }").unwrap(); let mut fn_ptr = FnPtr::new("foo").unwrap(); fn_ptr.set_curry(vec!["abc".into()]); diff --git a/tests/functions.rs b/tests/functions.rs index fec23025d..e79b76caf 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -31,14 +31,8 @@ fn test_functions_trait_object() { .register_fn("new_ts", || Shared::new(ABC(42)) as MySharedTestTrait) .register_fn("greet", |x: MySharedTestTrait| x.greet()); - assert_eq!( - engine.eval::("type_of(new_ts())").unwrap(), - "MySharedTestTrait" - ); - assert_eq!( - engine.eval::("let x = new_ts(); greet(x)").unwrap(), - 42 - ); + assert_eq!(engine.eval::("type_of(new_ts())").unwrap(), "MySharedTestTrait"); + assert_eq!(engine.eval::("let x = new_ts(); greet(x)").unwrap(), 42); } #[test] @@ -64,7 +58,6 @@ fn test_functions_namespaces() { engine.register_fn("test", || 42 as INT); assert_eq!(engine.eval::("fn test() { 123 } test()").unwrap(), 123); - assert_eq!(engine.eval::("test()").unwrap(), 42); } @@ -99,12 +92,7 @@ fn test_functions_global_module() { if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::ANSWER") )); - engine.register_fn( - "do_stuff", - |context: NativeCallContext, callback: rhai::FnPtr| -> Result { - callback.call_within_context(&context, ()) - }, - ); + engine.register_fn("do_stuff", |context: NativeCallContext, callback: rhai::FnPtr| -> Result { callback.call_within_context(&context, ()) }); #[cfg(not(feature = "no_closure"))] assert!(matches!(*engine.run( diff --git a/tests/get_set.rs b/tests/get_set.rs index 1ffb832a4..d5d7e591f 100644 --- a/tests/get_set.rs +++ b/tests/get_set.rs @@ -24,11 +24,7 @@ fn test_get_set() { } fn new() -> Self { - Self { - x: 1, - y: 0, - array: vec![1, 2, 3, 4, 5], - } + Self { x: 1, y: 0, array: vec![1, 2, 3, 4, 5] } } } @@ -41,51 +37,20 @@ fn test_get_set() { engine.register_fn("add", |value: &mut INT| *value += 41); engine.register_fn("new_ts", TestStruct::new); - assert_eq!( - engine - .eval::("let a = new_ts(); a.x = 500; a.x") - .unwrap(), - 500 - ); - assert_eq!( - engine - .eval::("let a = new_ts(); a.x.add(); a.x") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::("let a = new_ts(); a.y.add(); a.y") - .unwrap(), - 0 - ); + assert_eq!(engine.eval::("let a = new_ts(); a.x = 500; a.x").unwrap(), 500); + assert_eq!(engine.eval::("let a = new_ts(); a.x.add(); a.x").unwrap(), 42); + assert_eq!(engine.eval::("let a = new_ts(); a.y.add(); a.y").unwrap(), 0); - engine.register_indexer_get_set( - |value: &mut TestStruct, index: &str| value.array[index.len()], - |value: &mut TestStruct, index: &str, new_val: INT| value.array[index.len()] = new_val, - ); + engine.register_indexer_get_set(|value: &mut TestStruct, index: &str| value.array[index.len()], |value: &mut TestStruct, index: &str, new_val: INT| value.array[index.len()] = new_val); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine.eval::(r#"let a = new_ts(); a["abc"]"#).unwrap(), - 4 - ); + assert_eq!(engine.eval::(r#"let a = new_ts(); a["abc"]"#).unwrap(), 4); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::(r#"let a = new_ts(); a["abc"] = 42; a["abc"]"#) - .unwrap(), - 42 - ); + assert_eq!(engine.eval::(r#"let a = new_ts(); a["abc"] = 42; a["abc"]"#).unwrap(), 42); assert_eq!(engine.eval::(r"let a = new_ts(); a.abc").unwrap(), 4); - assert_eq!( - engine - .eval::(r"let a = new_ts(); a.abc = 42; a.abc") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::(r"let a = new_ts(); a.abc = 42; a.abc").unwrap(), 42); } #[test] @@ -124,9 +89,7 @@ fn test_get_set_chain_with_write_back() { } fn new() -> TestParent { - TestParent { - child: TestChild::new(), - } + TestParent { child: TestChild::new() } } } @@ -150,39 +113,13 @@ fn test_get_set_chain_with_write_back() { engine.register_fn("new_tp", TestParent::new); engine.register_fn("new_tc", TestChild::new); - assert_eq!( - engine.eval::("let a = new_tp(); a.child.x").unwrap(), - 1 - ); - assert_eq!( - engine - .eval::("let a = new_tp(); a.child.x = 42; a.child.x") - .unwrap(), - 42 - ); - - assert_eq!( - engine - .eval::("let a = new_tp(); type_of(a)") - .unwrap(), - "TestParent" - ); - + assert_eq!(engine.eval::("let a = new_tp(); a.child.x").unwrap(), 1); + assert_eq!(engine.eval::("let a = new_tp(); a.child.x = 42; a.child.x").unwrap(), 42); + assert_eq!(engine.eval::("let a = new_tp(); type_of(a)").unwrap(), "TestParent"); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::("let a = new_tp(); let c = new_tc(); c.x = 123; a[2] = c; a.child.x") - .unwrap(), - 246 - ); - + assert_eq!(engine.eval::("let a = new_tp(); let c = new_tc(); c.x = 123; a[2] = c; a.child.x").unwrap(), 246); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::("let a = new_tp(); a[2].x = 42; a.child.x") - .unwrap(), - 84 - ); + assert_eq!(engine.eval::("let a = new_tp(); a[2].x = 42; a.child.x").unwrap(), 84); } #[test] @@ -201,21 +138,10 @@ fn test_get_set_op_assignment() { let mut engine = Engine::new(); - engine - .register_type::() - .register_fn("new_ts", || Num(40)) - .register_get_set("v", Num::get, Num::set); + engine.register_type::().register_fn("new_ts", || Num(40)).register_get_set("v", Num::get, Num::set); - assert_eq!( - engine - .eval::("let a = new_ts(); a.v = a.v + 2; a") - .unwrap(), - Num(42) - ); - assert_eq!( - engine.eval::("let a = new_ts(); a.v += 2; a").unwrap(), - Num(42) - ); + assert_eq!(engine.eval::("let a = new_ts(); a.v = a.v + 2; a").unwrap(), Num(42)); + assert_eq!(engine.eval::("let a = new_ts(); a.v += 2; a").unwrap(), Num(42)); } #[test] @@ -233,62 +159,26 @@ fn test_get_set_chain_without_write_back() { let mut engine = Engine::new(); let mut scope = Scope::new(); - scope.push( - "outer", - Outer { - inner: Inner { value: 42 }, - }, - ); + scope.push("outer", Outer { inner: Inner { value: 42 } }); engine .register_type::() - .register_get_set( - "value", - |t: &mut Inner| t.value, - |_: NativeCallContext, _: &mut Inner, new: INT| { - panic!("Inner::value setter called with {}", new) - }, - ) + .register_get_set("value", |t: &mut Inner| t.value, |_: NativeCallContext, _: &mut Inner, new: INT| panic!("Inner::value setter called with {}", new)) .register_type::() - .register_get_set( - "inner", - |_: NativeCallContext, t: &mut Outer| t.inner.clone(), - |_: &mut Outer, new: Inner| panic!("Outer::inner setter called with {:?}", new), - ); + .register_get_set("inner", |_: NativeCallContext, t: &mut Outer| t.inner.clone(), |_: &mut Outer, new: Inner| panic!("Outer::inner setter called with {:?}", new)); #[cfg(not(feature = "no_index"))] - engine.register_indexer_get_set( - |t: &mut Outer, n: INT| Inner { - value: t.inner.value * n, - }, - |_: &mut Outer, n: INT, new: Inner| { - panic!("Outer::inner index setter called with {} and {:?}", n, new) - }, - ); + engine.register_indexer_get_set(|t: &mut Outer, n: INT| Inner { value: t.inner.value * n }, |_: &mut Outer, n: INT, new: Inner| panic!("Outer::inner index setter called with {} and {:?}", n, new)); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "outer.inner.value") - .unwrap(), - 42 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "outer.inner.value").unwrap(), 42); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval_with_scope::(&mut scope, "outer[2].value") - .unwrap(), - 84 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "outer[2].value").unwrap(), 84); - engine - .run_with_scope(&mut scope, "print(outer.inner.value)") - .unwrap(); + engine.run_with_scope(&mut scope, "print(outer.inner.value)").unwrap(); #[cfg(not(feature = "no_index"))] - engine - .run_with_scope(&mut scope, "print(outer[0].value)") - .unwrap(); + engine.run_with_scope(&mut scope, "print(outer[0].value)").unwrap(); } #[test] @@ -349,13 +239,7 @@ fn test_get_set_indexer() { engine .register_type_with_name::("MyMap") .register_fn("new_map", MyMap::new) - .register_indexer_get( - |map: &mut MyMap, index: &str| -> Result<_, Box> { - map.get(index).cloned().ok_or_else(|| { - EvalAltResult::ErrorIndexNotFound(index.into(), rhai::Position::NONE).into() - }) - }, - ) + .register_indexer_get(|map: &mut MyMap, index: &str| -> Result<_, Box> { map.get(index).cloned().ok_or_else(|| EvalAltResult::ErrorIndexNotFound(index.into(), rhai::Position::NONE).into()) }) .register_indexer_set(|map: &mut MyMap, index: &str, value: INT| { map.insert(index.to_string(), value); }); @@ -441,11 +325,6 @@ fn test_get_set_elvis() { engine.eval::<()>("let x = (); x?.foo.bar.baz").unwrap(); engine.eval::<()>("let x = (); x?.foo(1,2,3)").unwrap(); - engine - .eval::<()>("let x = #{a:()}; x.a?.foo.bar.baz") - .unwrap(); - assert_eq!( - engine.eval::("let x = 'x'; x?.type_of()").unwrap(), - "char" - ); + engine.eval::<()>("let x = #{a:()}; x.a?.foo.bar.baz").unwrap(); + assert_eq!(engine.eval::("let x = 'x'; x?.type_of()").unwrap(), "char"); } diff --git a/tests/if_block.rs b/tests/if_block.rs index 2745ba84f..754bc1adf 100644 --- a/tests/if_block.rs +++ b/tests/if_block.rs @@ -5,20 +5,9 @@ fn test_if() { let engine = Engine::new(); assert_eq!(engine.eval::("if true { 55 }").unwrap(), 55); - assert_eq!( - engine.eval::("if false { 55 } else { 44 }").unwrap(), - 44 - ); - assert_eq!( - engine.eval::("if true { 55 } else { 44 }").unwrap(), - 55 - ); - assert_eq!( - engine - .eval::("if false { 55 } else if true { 33 } else { 44 }") - .unwrap(), - 33 - ); + assert_eq!(engine.eval::("if false { 55 } else { 44 }").unwrap(), 44); + assert_eq!(engine.eval::("if true { 55 } else { 44 }").unwrap(), 55); + assert_eq!(engine.eval::("if false { 55 } else if true { 33 } else { 44 }").unwrap(), 33); assert_eq!( engine .eval::( diff --git a/tests/increment.rs b/tests/increment.rs index 98efa949f..4dee82aea 100644 --- a/tests/increment.rs +++ b/tests/increment.rs @@ -5,11 +5,5 @@ fn test_increment() { let engine = Engine::new(); assert_eq!(engine.eval::("let x = 1; x += 2; x").unwrap(), 3); - - assert_eq!( - engine - .eval::(r#"let s = "test"; s += "ing"; s"#) - .unwrap(), - "testing" - ); + assert_eq!(engine.eval::(r#"let s = "test"; s += "ing"; s"#).unwrap(), "testing"); } diff --git a/tests/internal_fn.rs b/tests/internal_fn.rs index d14dd2e0f..87b35f56a 100644 --- a/tests/internal_fn.rs +++ b/tests/internal_fn.rs @@ -5,91 +5,22 @@ use rhai::{Engine, EvalAltResult, ParseErrorType, INT}; fn test_internal_fn() { let engine = Engine::new(); - assert_eq!( - engine - .eval::("fn add_me(a, b) { a+b } add_me(3, 4)") - .unwrap(), - 7 - ); - - assert_eq!( - engine - .eval::("fn add_me(a, b,) { a+b } add_me(3, 4,)") - .unwrap(), - 7 - ); - - assert_eq!( - engine - .eval::("fn bob() { return 4; 5 } bob()") - .unwrap(), - 4 - ); - - assert_eq!( - engine - .eval::("fn add(x, n) { x + n } add(40, 2)") - .unwrap(), - 42 - ); - - assert_eq!( - engine - .eval::("fn add(x, n,) { x + n } add(40, 2,)") - .unwrap(), - 42 - ); - - assert_eq!( - engine - .eval::("fn add(x, n) { x + n } let a = 40; add(a, 2); a") - .unwrap(), - 40 - ); - + assert_eq!(engine.eval::("fn add_me(a, b) { a+b } add_me(3, 4)").unwrap(), 7); + assert_eq!(engine.eval::("fn add_me(a, b,) { a+b } add_me(3, 4,)").unwrap(), 7); + assert_eq!(engine.eval::("fn bob() { return 4; 5 } bob()").unwrap(), 4); + assert_eq!(engine.eval::("fn add(x, n) { x + n } add(40, 2)").unwrap(), 42); + assert_eq!(engine.eval::("fn add(x, n,) { x + n } add(40, 2,)").unwrap(), 42); + assert_eq!(engine.eval::("fn add(x, n) { x + n } let a = 40; add(a, 2); a").unwrap(), 40); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("fn add(n) { this + n } let x = 40; x.add(2)") - .unwrap(), - 42 - ); - + assert_eq!(engine.eval::("fn add(n) { this + n } let x = 40; x.add(2)").unwrap(), 42); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("fn add(n) { this += n; } let x = 40; x.add(2); x") - .unwrap(), - 42 - ); - - assert_eq!( - engine.eval::("fn mul2(x) { x * 2 } mul2(21)").unwrap(), - 42 - ); - - assert_eq!( - engine - .eval::("fn mul2(x) { x *= 2 } let a = 21; mul2(a); a") - .unwrap(), - 21 - ); - + assert_eq!(engine.eval::("fn add(n) { this += n; } let x = 40; x.add(2); x").unwrap(), 42); + assert_eq!(engine.eval::("fn mul2(x) { x * 2 } mul2(21)").unwrap(), 42); + assert_eq!(engine.eval::("fn mul2(x) { x *= 2 } let a = 21; mul2(a); a").unwrap(), 21); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("fn mul2() { this * 2 } let x = 21; x.mul2()") - .unwrap(), - 42 - ); - + assert_eq!(engine.eval::("fn mul2() { this * 2 } let x = 21; x.mul2()").unwrap(), 42); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("fn mul2() { this *= 2; } let x = 21; x.mul2(); x") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::("fn mul2() { this *= 2; } let x = 21; x.mul2(); x").unwrap(), 42); } #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Default)] @@ -105,9 +36,7 @@ impl Clone for TestStruct { fn test_internal_fn_take() { let mut engine = Engine::new(); - engine - .register_type_with_name::("TestStruct") - .register_fn("new_ts", |x: INT| TestStruct(x)); + engine.register_type_with_name::("TestStruct").register_fn("new_ts", |x: INT| TestStruct(x)); assert_eq!( engine @@ -194,23 +123,16 @@ fn test_internal_fn_params() { let engine = Engine::new(); // Expect duplicated parameters error - assert_eq!( - *engine - .compile("fn hello(x, x) { x }") - .unwrap_err() - .err_type(), - ParseErrorType::FnDuplicatedParam("hello".to_string(), "x".to_string()) - ); + assert!(matches!( + engine.compile("fn hello(x, x) { x }").unwrap_err().err_type(), + ParseErrorType::FnDuplicatedParam(a, b) if a == "hello" && b == "x")); } #[test] fn test_function_pointers() { let engine = Engine::new(); - assert_eq!( - engine.eval::(r#"type_of(Fn("abc"))"#).unwrap(), - "Fn" - ); + assert_eq!(engine.eval::(r#"type_of(Fn("abc"))"#).unwrap(), "Fn"); assert_eq!( engine diff --git a/tests/looping.rs b/tests/looping.rs index 05ca32e53..dc142ee8d 100644 --- a/tests/looping.rs +++ b/tests/looping.rs @@ -28,27 +28,12 @@ fn test_loop() { 21 ); - assert_eq!( - *engine.compile("let x = 0; break;").unwrap_err().err_type(), - ParseErrorType::LoopBreak - ); + assert_eq!(*engine.compile("let x = 0; break;").unwrap_err().err_type(), ParseErrorType::LoopBreak); #[cfg(not(feature = "no_function"))] - assert_eq!( - *engine - .compile("loop { let f = || { break; } }") - .unwrap_err() - .err_type(), - ParseErrorType::LoopBreak - ); + assert_eq!(*engine.compile("loop { let f = || { break; } }").unwrap_err().err_type(), ParseErrorType::LoopBreak); - assert_eq!( - *engine - .compile("let x = 0; if x > 0 { continue; }") - .unwrap_err() - .err_type(), - ParseErrorType::LoopBreak - ); + assert_eq!(*engine.compile("let x = 0; if x > 0 { continue; }").unwrap_err().err_type(), ParseErrorType::LoopBreak); } #[test] diff --git a/tests/maps.rs b/tests/maps.rs index 48e8e3095..c3d6c4bb7 100644 --- a/tests/maps.rs +++ b/tests/maps.rs @@ -7,18 +7,8 @@ fn test_map_indexing() { #[cfg(not(feature = "no_index"))] { - assert_eq!( - engine - .eval::(r#"let x = #{a: 1, b: 2, c: 3}; x["b"]"#) - .unwrap(), - 2 - ); - assert_eq!( - engine - .eval::(r#"let x = #{a: 1, b: 2, c: 3,}; x["b"]"#) - .unwrap(), - 2 - ); + assert_eq!(engine.eval::(r#"let x = #{a: 1, b: 2, c: 3}; x["b"]"#).unwrap(), 2); + assert_eq!(engine.eval::(r#"let x = #{a: 1, b: 2, c: 3,}; x["b"]"#).unwrap(), 2); assert_eq!( engine .eval::( @@ -30,20 +20,10 @@ fn test_map_indexing() { .unwrap(), 'o' ); - assert_eq!( - engine - .eval::(r#"let a = [#{s:"hello"}]; a[0].s[2] = 'X'; a[0].s"#) - .unwrap(), - "heXlo" - ); + assert_eq!(engine.eval::(r#"let a = [#{s:"hello"}]; a[0].s[2] = 'X'; a[0].s"#).unwrap(), "heXlo"); } - assert_eq!( - engine - .eval::("let y = #{a: 1, b: 2, c: 3}; y.a = 5; y.a") - .unwrap(), - 5 - ); + assert_eq!(engine.eval::("let y = #{a: 1, b: 2, c: 3}; y.a = 5; y.a").unwrap(), 5); engine.run("let y = #{a: 1, b: 2, c: 3}; y.z").unwrap(); @@ -61,22 +41,11 @@ b`: 1}; 1 ); - assert!(matches!( - *engine - .eval::("let y = #{`a${1}`: 1}; y.a1") - .unwrap_err(), - EvalAltResult::ErrorParsing(ParseErrorType::PropertyExpected, ..) - )); + assert!(matches!(*engine.eval::("let y = #{`a${1}`: 1}; y.a1").unwrap_err(), EvalAltResult::ErrorParsing(ParseErrorType::PropertyExpected, ..))); - assert!(engine - .eval::(r#"let y = #{a: 1, b: 2, c: 3}; "c" in y"#) - .unwrap()); - assert!(engine - .eval::(r#"let y = #{a: 1, b: 2, c: 3}; "b" in y"#) - .unwrap()); - assert!(!engine - .eval::(r#"let y = #{a: 1, b: 2, c: 3}; "z" in y"#) - .unwrap()); + assert!(engine.eval::(r#"let y = #{a: 1, b: 2, c: 3}; "c" in y"#).unwrap()); + assert!(engine.eval::(r#"let y = #{a: 1, b: 2, c: 3}; "b" in y"#).unwrap()); + assert!(!engine.eval::(r#"let y = #{a: 1, b: 2, c: 3}; "z" in y"#).unwrap()); assert_eq!( engine @@ -138,11 +107,10 @@ fn test_map_prop() { engine.set_fail_on_invalid_map_property(true); - assert!( - matches!(*engine.eval::<()>("let x = #{a: 42}; x.b").unwrap_err(), - EvalAltResult::ErrorPropertyNotFound(prop, _) if prop == "b" - ) - ); + assert!(matches!( + *engine.eval::<()>("let x = #{a: 42}; x.b").unwrap_err(), + EvalAltResult::ErrorPropertyNotFound(prop, _) if prop == "b" + )); } #[cfg(not(feature = "no_index"))] @@ -152,55 +120,19 @@ fn test_map_index_types() { engine.compile(r#"#{a:1, b:2, c:3}["a"]['x']"#).unwrap(); - assert!(matches!( - engine - .compile("#{a:1, b:2, c:3}['x']") - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); - - assert!(matches!( - engine - .compile("#{a:1, b:2, c:3}[1]") - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); - + assert!(matches!(engine.compile("#{a:1, b:2, c:3}['x']").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); + assert!(matches!(engine.compile("#{a:1, b:2, c:3}[1]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); #[cfg(not(feature = "no_float"))] - assert!(matches!( - engine - .compile("#{a:1, b:2, c:3}[123.456]") - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); - - assert!(matches!( - engine - .compile("#{a:1, b:2, c:3}[()]") - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); - - assert!(matches!( - engine - .compile("#{a:1, b:2, c:3}[true && false]") - .unwrap_err() - .err_type(), - ParseErrorType::MalformedIndexExpr(..) - )); + assert!(matches!(engine.compile("#{a:1, b:2, c:3}[123.456]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); + assert!(matches!(engine.compile("#{a:1, b:2, c:3}[()]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); + assert!(matches!(engine.compile("#{a:1, b:2, c:3}[true && false]").unwrap_err().err_type(), ParseErrorType::MalformedIndexExpr(..))); } #[test] fn test_map_assign() { let engine = Engine::new(); - let x = engine - .eval::(r#"let x = #{a: 1, b: true, "c$": "hello"}; x"#) - .unwrap(); + let x = engine.eval::(r#"let x = #{a: 1, b: true, "c$": "hello"}; x"#).unwrap(); assert_eq!(x["a"].as_int().unwrap(), 1); assert!(x["b"].as_bool().unwrap()); @@ -211,9 +143,7 @@ fn test_map_assign() { fn test_map_return() { let engine = Engine::new(); - let x = engine - .eval::(r#"#{a: 1, b: true, "c$": "hello"}"#) - .unwrap(); + let x = engine.eval::(r#"#{a: 1, b: true, "c$": "hello"}"#).unwrap(); assert_eq!(x["a"].as_int().unwrap(), 1); assert!(x["b"].as_bool().unwrap()); @@ -290,35 +220,12 @@ fn test_map_json() { engine.parse_json(json, true).unwrap(); - assert!(matches!( - *engine.parse_json("123", true).unwrap_err(), - EvalAltResult::ErrorMismatchOutputType(..) - )); - - assert!(matches!( - *engine.parse_json("{a:42}", true).unwrap_err(), - EvalAltResult::ErrorParsing(..) - )); - - assert!(matches!( - *engine.parse_json("#{a:123}", true).unwrap_err(), - EvalAltResult::ErrorParsing(..) - )); - - assert!(matches!( - *engine.parse_json("{a:()}", true).unwrap_err(), - EvalAltResult::ErrorParsing(..) - )); - - assert!(matches!( - *engine.parse_json("#{a:123+456}", true).unwrap_err(), - EvalAltResult::ErrorParsing(..) - )); - - assert!(matches!( - *engine.parse_json("{a:`hello${world}`}", true).unwrap_err(), - EvalAltResult::ErrorParsing(..) - )); + assert!(matches!(*engine.parse_json("123", true).unwrap_err(), EvalAltResult::ErrorMismatchOutputType(..))); + assert!(matches!(*engine.parse_json("{a:42}", true).unwrap_err(), EvalAltResult::ErrorParsing(..))); + assert!(matches!(*engine.parse_json("#{a:123}", true).unwrap_err(), EvalAltResult::ErrorParsing(..))); + assert!(matches!(*engine.parse_json("{a:()}", true).unwrap_err(), EvalAltResult::ErrorParsing(..))); + assert!(matches!(*engine.parse_json("#{a:123+456}", true).unwrap_err(), EvalAltResult::ErrorParsing(..))); + assert!(matches!(*engine.parse_json("{a:`hello${world}`}", true).unwrap_err(), EvalAltResult::ErrorParsing(..))); } #[test] diff --git a/tests/math.rs b/tests/math.rs index 8f9dd5424..a1f1b155a 100644 --- a/tests/math.rs +++ b/tests/math.rs @@ -20,10 +20,7 @@ fn test_math() { assert!(engine.eval::("cos(PI()/2.0)").unwrap().abs() < 0.001); #[cfg(not(feature = "only_i32"))] - assert_eq!( - engine.eval::("abs(-9223372036854775807)").unwrap(), - 9_223_372_036_854_775_807 - ); + assert_eq!(engine.eval::("abs(-9223372036854775807)").unwrap(), 9_223_372_036_854_775_807); #[cfg(feature = "only_i32")] assert_eq!(engine.eval::("abs(-2147483647)").unwrap(), 2147483647); @@ -33,76 +30,21 @@ fn test_math() { { #[cfg(not(feature = "only_i32"))] { - assert!(matches!( - *engine - .eval::("abs(-9223372036854775808)") - .expect_err("expects negation overflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("9223372036854775807 + 1") - .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("-9223372036854775808 - 1") - .expect_err("expects underflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("9223372036854775807 * 9223372036854775807") - .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("9223372036854775807 / 0") - .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("9223372036854775807 % 0") - .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(..) - )); + assert!(matches!(*engine.eval::("abs(-9223372036854775808)").expect_err("expects negation overflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("9223372036854775807 + 1").expect_err("expects overflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("-9223372036854775808 - 1").expect_err("expects underflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("9223372036854775807 * 9223372036854775807").expect_err("expects overflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("9223372036854775807 / 0").expect_err("expects division by zero"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("9223372036854775807 % 0").expect_err("expects division by zero"), EvalAltResult::ErrorArithmetic(..))); } #[cfg(feature = "only_i32")] { - assert!(matches!( - *engine - .eval::("2147483647 + 1") - .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("-2147483648 - 1") - .expect_err("expects underflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("2147483647 * 2147483647") - .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("2147483647 / 0") - .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(..) - )); - assert!(matches!( - *engine - .eval::("2147483647 % 0") - .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(..) - )); + assert!(matches!(*engine.eval::("2147483647 + 1").expect_err("expects overflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("-2147483648 - 1").expect_err("expects underflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("2147483647 * 2147483647").expect_err("expects overflow"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("2147483647 / 0").expect_err("expects division by zero"), EvalAltResult::ErrorArithmetic(..))); + assert!(matches!(*engine.eval::("2147483647 % 0").expect_err("expects division by zero"), EvalAltResult::ErrorArithmetic(..))); } } } @@ -113,8 +55,5 @@ fn test_math_parse() { assert_eq!(engine.eval::(r#"parse_int("42")"#).unwrap(), 42); assert_eq!(engine.eval::(r#"parse_int("42", 16)"#).unwrap(), 0x42); - assert_eq!( - engine.eval::(r#"parse_int("abcdef", 16)"#).unwrap(), - 0xabcdef - ); + assert_eq!(engine.eval::(r#"parse_int("abcdef", 16)"#).unwrap(), 0xabcdef); } diff --git a/tests/method_call.rs b/tests/method_call.rs index d51c578ec..46013a919 100644 --- a/tests/method_call.rs +++ b/tests/method_call.rs @@ -20,34 +20,17 @@ impl TestStruct { fn test_method_call() { let mut engine = Engine::new(); - engine - .register_type::() - .register_fn("update", TestStruct::update) - .register_fn("new_ts", TestStruct::new); - - assert_eq!( - engine - .eval::("let x = new_ts(); x.update(1000); x") - .unwrap(), - TestStruct { x: 1001 } - ); + engine.register_type::().register_fn("update", TestStruct::update).register_fn("new_ts", TestStruct::new); - assert_eq!( - engine - .eval::("let x = new_ts(); update(x, 1000); x") - .unwrap(), - TestStruct { x: 1001 } - ); + assert_eq!(engine.eval::("let x = new_ts(); x.update(1000); x").unwrap(), TestStruct { x: 1001 }); + assert_eq!(engine.eval::("let x = new_ts(); update(x, 1000); x").unwrap(), TestStruct { x: 1001 }); } #[test] fn test_method_call_style() { let engine = Engine::new(); - assert_eq!( - engine.eval::("let x = -123; x.abs(); x").unwrap(), - -123 - ); + assert_eq!(engine.eval::("let x = -123; x.abs(); x").unwrap(), -123); } #[cfg(not(feature = "no_optimize"))] @@ -60,9 +43,7 @@ fn test_method_call_with_full_optimization() { engine .register_fn("new_ts", TestStruct::new) .register_fn("ymd", |_: INT, _: INT, _: INT| 42 as INT) - .register_fn("range", |_: &mut TestStruct, _: INT, _: INT| { - TestStruct::new() - }); + .register_fn("range", |_: &mut TestStruct, _: INT, _: INT| TestStruct::new()); assert_eq!( engine diff --git a/tests/mismatched_op.rs b/tests/mismatched_op.rs index 2b2b271f1..6a692613e 100644 --- a/tests/mismatched_op.rs +++ b/tests/mismatched_op.rs @@ -42,9 +42,7 @@ fn test_mismatched_op_custom_type() { let mut engine = Engine::new(); - engine - .register_type_with_name::("TestStruct") - .register_fn("new_ts", TestStruct::new); + engine.register_type_with_name::("TestStruct").register_fn("new_ts", TestStruct::new); assert!(!engine.eval::("new_ts() == 42").unwrap()); diff --git a/tests/modules.rs b/tests/modules.rs index d0eee05f4..34855a95c 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -1,8 +1,7 @@ #![cfg(not(feature = "no_module"))] use rhai::{ module_resolvers::{DummyModuleResolver, StaticModuleResolver}, - Dynamic, Engine, EvalAltResult, FnNamespace, ImmutableString, Module, ParseError, - ParseErrorType, Scope, INT, + Dynamic, Engine, EvalAltResult, FnNamespace, ImmutableString, Module, ParseError, ParseErrorType, Scope, INT, }; // #[cfg(all(not(feature = "no_function"), feature = "internals"))] @@ -72,47 +71,15 @@ fn test_module_sub_module() { assert_eq!(engine.eval::("question::MYSTIC_NUMBER").unwrap(), 42); assert!(engine.eval::("MYSTIC_NUMBER").is_err()); - assert_eq!( - engine - .eval::("question::life::universe::answer") - .unwrap(), - 41 - ); - assert_eq!( - engine - .eval::("question::life::universe::answer + 1") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::("question::life::universe::inc(question::life::universe::answer)") - .unwrap(), - 42 - ); - assert!(engine - .eval::("inc(question::life::universe::answer)") - .is_err()); + assert_eq!(engine.eval::("question::life::universe::answer").unwrap(), 41); + assert_eq!(engine.eval::("question::life::universe::answer + 1").unwrap(), 42); + assert_eq!(engine.eval::("question::life::universe::inc(question::life::universe::answer)").unwrap(), 42); + assert!(engine.eval::("inc(question::life::universe::answer)").is_err()); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("question::MYSTIC_NUMBER.doubled") - .unwrap(), - 84 - ); + assert_eq!(engine.eval::("question::MYSTIC_NUMBER.doubled").unwrap(), 84); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::("question::life::universe::answer.doubled") - .unwrap(), - 82 - ); - assert_eq!( - engine - .eval::("super_inc(question::life::universe::answer)") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::("question::life::universe::answer.doubled").unwrap(), 82); + assert_eq!(engine.eval::("super_inc(question::life::universe::answer)").unwrap(), 42); } #[test] @@ -130,13 +97,10 @@ fn test_module_resolver() { module.update_fn_namespace(double_hash, FnNamespace::Global); #[cfg(not(feature = "no_float"))] - module.set_native_fn( - "sum_of_three_args", - |target: &mut INT, a: INT, b: INT, c: rhai::FLOAT| { - *target = a + b + c as INT; - Ok(()) - }, - ); + module.set_native_fn("sum_of_three_args", |target: &mut INT, a: INT, b: INT, c: rhai::FLOAT| { + *target = a + b + c as INT; + Ok(()) + }); resolver.insert("hello", module); @@ -319,9 +283,7 @@ fn test_module_resolver() { assert!(engine.eval::(script).is_err()); - let result = engine - .call_fn::(&mut Scope::new(), &ast, "foo", (2 as INT,)) - .unwrap(); + let result = engine.call_fn::(&mut Scope::new(), &ast, "foo", (2 as INT,)).unwrap(); assert_eq!(result, 84); @@ -338,9 +300,7 @@ fn test_module_resolver() { assert_eq!(ast2.resolver().unwrap().len(), len); } - let result = engine - .call_fn::(&mut Scope::new(), &ast2, "foo", (2 as INT,)) - .unwrap(); + let result = engine.call_fn::(&mut Scope::new(), &ast2, "foo", (2 as INT,)).unwrap(); assert_eq!(result, 84); } @@ -401,57 +361,15 @@ fn test_module_from_ast() { resolver2.insert("testing", module); engine.set_module_resolver(resolver2); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::abc"#) - .unwrap(), - 123 - ); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::x"#) - .unwrap(), - 123 - ); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::xxx"#) - .unwrap(), - 123 - ); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::foo"#) - .unwrap(), - 42 - ); - assert!(engine - .eval::(r#"import "testing" as ttt; ttt::extra::foo"#) - .unwrap()); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::hello"#) - .unwrap(), - "hello, 42 worlds!" - ); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::calc(999)"#) - .unwrap(), - 1000 - ); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::cross_call(999)"#) - .unwrap(), - 1000 - ); - assert_eq!( - engine - .eval::(r#"import "testing" as ttt; ttt::add_len(ttt::foo, ttt::hello)"#) - .unwrap(), - 59 - ); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::abc"#).unwrap(), 123); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::x"#).unwrap(), 123); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::xxx"#).unwrap(), 123); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::foo"#).unwrap(), 42); + assert!(engine.eval::(r#"import "testing" as ttt; ttt::extra::foo"#).unwrap()); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::hello"#).unwrap(), "hello, 42 worlds!"); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::calc(999)"#).unwrap(), 1000); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::cross_call(999)"#).unwrap(), 1000); + assert_eq!(engine.eval::(r#"import "testing" as ttt; ttt::add_len(ttt::foo, ttt::hello)"#).unwrap(), 59); assert!(matches!( *engine .run(r#"import "testing" as ttt; ttt::hidden()"#) @@ -498,24 +416,9 @@ fn test_module_str() { static_modules.insert("test", module); engine.set_module_resolver(static_modules); - assert_eq!( - engine - .eval::(r#"import "test" as test; test::test("test");"#) - .unwrap(), - 4 - ); - assert_eq!( - engine - .eval::(r#"import "test" as test; test::test2("test");"#) - .unwrap(), - 4 - ); - assert_eq!( - engine - .eval::(r#"import "test" as test; test::test3("test");"#) - .unwrap(), - 4 - ); + assert_eq!(engine.eval::(r#"import "test" as test; test::test("test");"#).unwrap(), 4); + assert_eq!(engine.eval::(r#"import "test" as test; test::test2("test");"#).unwrap(), 4); + assert_eq!(engine.eval::(r#"import "test" as test; test::test3("test");"#).unwrap(), 4); } #[cfg(not(feature = "no_function"))] @@ -536,30 +439,10 @@ fn test_module_ast_namespace() { resolver.insert("testing", module); engine.set_module_resolver(resolver); - assert_eq!( - engine - .eval::(r#"import "testing" as t; t::foo(41)"#) - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::(r#"import "testing" as t; t::bar(41)"#) - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::(r#"fn foo(x) { x - 1 } import "testing" as t; t::foo(41)"#) - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::(r#"fn foo(x) { x - 1 } import "testing" as t; t::bar(41)"#) - .unwrap(), - 42 - ); + assert_eq!(engine.eval::(r#"import "testing" as t; t::foo(41)"#).unwrap(), 42); + assert_eq!(engine.eval::(r#"import "testing" as t; t::bar(41)"#).unwrap(), 42); + assert_eq!(engine.eval::(r#"fn foo(x) { x - 1 } import "testing" as t; t::foo(41)"#).unwrap(), 42); + assert_eq!(engine.eval::(r#"fn foo(x) { x - 1 } import "testing" as t; t::bar(41)"#).unwrap(), 42); } #[cfg(not(feature = "no_function"))] @@ -608,27 +491,19 @@ fn test_module_context() { resolver.insert("testing", module); engine.set_module_resolver(resolver); - engine.register_fn( - "calc", - |context: NativeCallContext, fp: FnPtr| -> Result> { - let engine = context.engine(); + engine.register_fn("calc", |context: NativeCallContext, fp: FnPtr| -> Result> { + let engine = context.engine(); - // Store context for later use - requires the 'internals' feature - let context_data = context.store_data(); + // Store context for later use - requires the 'internals' feature + let context_data = context.store_data(); - // Recreate the 'NativeCallContext' - let new_context = context_data.create_context(engine); + // Recreate the 'NativeCallContext' + let new_context = context_data.create_context(engine); - fp.call_within_context(&new_context, (41 as INT,)) - }, - ); + fp.call_within_context(&new_context, (41 as INT,)) + }); - assert_eq!( - engine - .eval::(r#"import "testing" as t; t::bar()"#) - .unwrap(), - 42 - ); + assert_eq!(engine.eval::(r#"import "testing" as t; t::bar()"#).unwrap(), 42); } #[test] @@ -709,10 +584,5 @@ fn test_module_dynamic() { assert_eq!(engine.eval::(r#"test2("test", 38);"#).unwrap(), 42); - assert_eq!( - engine - .eval::(r#"import "test" as test; test::test("test", 38);"#) - .unwrap(), - 42 - ); + assert_eq!(engine.eval::(r#"import "test" as test; test::test("test", 38);"#).unwrap(), 42); } diff --git a/tests/native.rs b/tests/native.rs index 23f95bce1..e2579482c 100644 --- a/tests/native.rs +++ b/tests/native.rs @@ -8,19 +8,14 @@ fn test_native_context() { let mut engine = Engine::new(); engine.set_max_modules(40); - engine.register_fn("test", |context: NativeCallContext, x: INT| { - context.engine().max_modules() as INT + x - }); + engine.register_fn("test", |context: NativeCallContext, x: INT| context.engine().max_modules() as INT + x); assert_eq!(engine.eval::("test(2)").unwrap(), 42); } #[test] fn test_native_context_fn_name() { - fn add_double( - context: NativeCallContext, - args: &mut [&mut Dynamic], - ) -> Result> { + fn add_double(context: NativeCallContext, args: &mut [&mut Dynamic]) -> Result> { let x = args[0].as_int().unwrap(); let y = args[1].as_int().unwrap(); Ok(format!("{}_{}", context.fn_name(), x + 2 * y).into()) @@ -29,83 +24,32 @@ fn test_native_context_fn_name() { let mut engine = Engine::new(); engine - .register_raw_fn( - "add_double", - [TypeId::of::(), TypeId::of::()], - add_double, - ) - .register_raw_fn( - "append_x2", - [TypeId::of::(), TypeId::of::()], - add_double, - ); + .register_raw_fn("add_double", [TypeId::of::(), TypeId::of::()], add_double) + .register_raw_fn("append_x2", [TypeId::of::(), TypeId::of::()], add_double); - assert_eq!( - engine.eval::("add_double(40, 1)").unwrap(), - "add_double_42" - ); + assert_eq!(engine.eval::("add_double(40, 1)").unwrap(), "add_double_42"); - assert_eq!( - engine.eval::("append_x2(40, 1)").unwrap(), - "append_x2_42" - ); + assert_eq!(engine.eval::("append_x2(40, 1)").unwrap(), "append_x2_42"); } #[test] fn test_native_overload() { let mut engine = Engine::new(); - assert_eq!( - engine - .eval::(r#"let x = "hello, "; let y = "world"; x + y"#) - .unwrap(), - "hello, world" - ); - assert_eq!( - engine - .eval::(r#"let x = "hello"; let y = (); x + y"#) - .unwrap(), - "hello" - ); + assert_eq!(engine.eval::(r#"let x = "hello, "; let y = "world"; x + y"#).unwrap(), "hello, world"); + assert_eq!(engine.eval::(r#"let x = "hello"; let y = (); x + y"#).unwrap(), "hello"); // Overload the `+` operator for strings engine - .register_fn( - "+", - |s1: ImmutableString, s2: ImmutableString| -> ImmutableString { - format!("{s1}***{s2}").into() - }, - ) - .register_fn("+", |s1: ImmutableString, _: ()| -> ImmutableString { - format!("{s1} Foo!").into() - }); + .register_fn("+", |s1: ImmutableString, s2: ImmutableString| -> ImmutableString { format!("{s1}***{s2}").into() }) + .register_fn("+", |s1: ImmutableString, _: ()| -> ImmutableString { format!("{s1} Foo!").into() }); - assert_eq!( - engine - .eval::(r#"let x = "hello"; let y = "world"; x + y"#) - .unwrap(), - "helloworld" - ); - assert_eq!( - engine - .eval::(r#"let x = "hello"; let y = (); x + y"#) - .unwrap(), - "hello" - ); + assert_eq!(engine.eval::(r#"let x = "hello"; let y = "world"; x + y"#).unwrap(), "helloworld"); + assert_eq!(engine.eval::(r#"let x = "hello"; let y = (); x + y"#).unwrap(), "hello"); engine.set_fast_operators(false); - assert_eq!( - engine - .eval::(r#"let x = "hello"; let y = "world"; x + y"#) - .unwrap(), - "hello***world" - ); - assert_eq!( - engine - .eval::(r#"let x = "hello"; let y = (); x + y"#) - .unwrap(), - "hello Foo!" - ); + assert_eq!(engine.eval::(r#"let x = "hello"; let y = "world"; x + y"#).unwrap(), "hello***world"); + assert_eq!(engine.eval::(r#"let x = "hello"; let y = (); x + y"#).unwrap(), "hello Foo!"); } diff --git a/tests/not.rs b/tests/not.rs index 01bf36c9d..2eb299d2f 100644 --- a/tests/not.rs +++ b/tests/not.rs @@ -4,9 +4,7 @@ use rhai::Engine; fn test_not() { let engine = Engine::new(); - assert!(!engine - .eval::("let not_true = !true; not_true") - .unwrap()); + assert!(!engine.eval::("let not_true = !true; not_true").unwrap()); #[cfg(not(feature = "no_function"))] assert!(engine.eval::("fn not(x) { !x } not(false)").unwrap()); diff --git a/tests/number_literals.rs b/tests/number_literals.rs index c57dd4d25..8d575847e 100644 --- a/tests/number_literals.rs +++ b/tests/number_literals.rs @@ -7,14 +7,7 @@ fn test_number_literal() { assert_eq!(engine.eval::("42").unwrap(), 42); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine.eval::("42.type_of()").unwrap(), - if cfg!(feature = "only_i32") { - "i32" - } else { - "i64" - } - ); + assert_eq!(engine.eval::("42.type_of()").unwrap(), if cfg!(feature = "only_i32") { "i32" } else { "i64" }); } #[test] @@ -26,10 +19,7 @@ fn test_hex_literal() { assert_eq!(engine.eval::("let x = 0xff; x").unwrap(), 255); #[cfg(not(feature = "only_i32"))] - assert_eq!( - engine.eval::("let x = 0xffffffffffffffff; x").unwrap(), - -1 - ); + assert_eq!(engine.eval::("let x = 0xffffffffffffffff; x").unwrap(), -1); #[cfg(feature = "only_i32")] assert_eq!(engine.eval::("let x = 0xffffffff; x").unwrap(), -1); } @@ -49,24 +39,10 @@ fn test_binary_literal() { assert_eq!(engine.eval::("let x = 0b1111; x").unwrap(), 15); assert_eq!(engine.eval::("let x = 0B1111; x").unwrap(), 15); - assert_eq!( - engine - .eval::("let x = 0b0011_1100_1010_0101; x") - .unwrap(), - 15525 - ); + assert_eq!(engine.eval::("let x = 0b0011_1100_1010_0101; x").unwrap(), 15525); + #[cfg(not(feature = "only_i32"))] - assert_eq!( - engine.eval::( - "let x = 0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111; x" - ).unwrap(), - -1 - ); + assert_eq!(engine.eval::("let x = 0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111; x").unwrap(), -1); #[cfg(feature = "only_i32")] - assert_eq!( - engine - .eval::("let x = 0b11111111_11111111_11111111_11111111; x") - .unwrap(), - -1 - ); + assert_eq!(engine.eval::("let x = 0b11111111_11111111_11111111_11111111; x").unwrap(), -1); } diff --git a/tests/operations.rs b/tests/operations.rs index af3547f4a..2657b9a1c 100644 --- a/tests/operations.rs +++ b/tests/operations.rs @@ -17,10 +17,7 @@ fn test_max_operations() { engine.run("let x = 0; while x < 20 { x += 1; }").unwrap(); - assert!(matches!( - *engine.run("for x in 0..500 {}").unwrap_err(), - EvalAltResult::ErrorTooManyOperations(..) - )); + assert!(matches!(*engine.run("for x in 0..500 {}").unwrap_err(), EvalAltResult::ErrorTooManyOperations(..))); engine.set_max_operations(0); @@ -38,21 +35,13 @@ fn test_max_operations_literal() { engine.run("[1, 2, 3, 4, 5, 6, 7]").unwrap(); #[cfg(not(feature = "no_index"))] - assert!(matches!( - *engine.run("[1, 2, 3, 4, 5, 6, 7, 8, 9]").unwrap_err(), - EvalAltResult::ErrorTooManyOperations(..) - )); + assert!(matches!(*engine.run("[1, 2, 3, 4, 5, 6, 7, 8, 9]").unwrap_err(), EvalAltResult::ErrorTooManyOperations(..))); #[cfg(not(feature = "no_object"))] engine.run("#{a:1, b:2, c:3, d:4, e:5, f:6, g:7}").unwrap(); #[cfg(not(feature = "no_object"))] - assert!(matches!( - *engine - .run("#{a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9}") - .unwrap_err(), - EvalAltResult::ErrorTooManyOperations(..) - )); + assert!(matches!(*engine.run("#{a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9}").unwrap_err(), EvalAltResult::ErrorTooManyOperations(..))); } #[test] @@ -145,18 +134,9 @@ fn test_max_operations_progress() { engine.set_optimization_level(rhai::OptimizationLevel::None); engine.set_max_operations(500); - engine.on_progress(|count| { - if count < 100 { - None - } else { - Some((42 as INT).into()) - } - }); + engine.on_progress(|count| if count < 100 { None } else { Some((42 as INT).into()) }); assert!(matches!( - *engine - .run("for x in 0..500 {}") - .unwrap_err(), - EvalAltResult::ErrorTerminated(x, ..) if x.as_int().unwrap() == 42 - )); + *engine.run("for x in 0..500 {}").unwrap_err(), + EvalAltResult::ErrorTerminated(x, ..) if x.as_int().unwrap() == 42)); } diff --git a/tests/ops.rs b/tests/ops.rs index 510815b54..af0d6dafe 100644 --- a/tests/ops.rs +++ b/tests/ops.rs @@ -7,12 +7,7 @@ fn test_ops() { assert_eq!(engine.eval::("60 + 5").unwrap(), 65); assert_eq!(engine.eval::("(1 + 2) * (6 - 4) / 2").unwrap(), 3); assert_eq!(engine.eval::("let x = 41; x = x + 1; x").unwrap(), 42); - assert_eq!( - engine - .eval::(r#"let s = "hello"; s = s + 42; s"#) - .unwrap(), - "hello42" - ); + assert_eq!(engine.eval::(r#"let s = "hello"; s = s + 42; s"#).unwrap(), "hello42"); } #[cfg(not(feature = "only_i32"))] @@ -35,9 +30,7 @@ fn test_ops_other_number_types() { EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("== (u16,") )); - assert!(!engine - .eval_with_scope::(&mut scope, r#"x == "hello""#) - .unwrap()); + assert!(!engine.eval_with_scope::(&mut scope, r#"x == "hello""#).unwrap()); } #[test] @@ -54,12 +47,7 @@ fn test_ops_strings() { fn test_ops_precedence() { let engine = Engine::new(); - assert_eq!( - engine - .eval::("let x = 0; if x == 10 || true { x = 1} x") - .unwrap(), - 1 - ); + assert_eq!(engine.eval::("let x = 0; if x == 10 || true { x = 1} x").unwrap(), 1); } #[test] @@ -78,15 +66,8 @@ fn test_ops_custom_types() { .register_fn("new_ts2", || Test2) .register_fn("==", |_: Test1, _: Test2| true); - assert!(engine - .eval::("let x = new_ts1(); let y = new_ts2(); x == y") - .unwrap()); - - assert!(engine - .eval::("let x = new_ts1(); let y = new_ts2(); x != y") - .unwrap()); - + assert!(engine.eval::("let x = new_ts1(); let y = new_ts2(); x == y").unwrap()); + assert!(engine.eval::("let x = new_ts1(); let y = new_ts2(); x != y").unwrap()); assert!(!engine.eval::("let x = new_ts1(); x == ()").unwrap()); - assert!(engine.eval::("let x = new_ts1(); x != ()").unwrap()); } diff --git a/tests/optimizer.rs b/tests/optimizer.rs index 3ae425b08..7559608be 100644 --- a/tests/optimizer.rs +++ b/tests/optimizer.rs @@ -23,22 +23,9 @@ fn test_optimizer() { #[test] fn test_optimizer_run() { fn run_test(engine: &mut Engine) { - assert_eq!( - engine.eval::("if true { 42 } else { 123 }").unwrap(), - 42 - ); - assert_eq!( - engine - .eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval::(r#"const abc = "hello"; if abc < "foo" { 42 } else { 123 }"#) - .unwrap(), - 123 - ); + assert_eq!(engine.eval::("if true { 42 } else { 123 }").unwrap(), 42); + assert_eq!(engine.eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }").unwrap(), 42); + assert_eq!(engine.eval::(r#"const abc = "hello"; if abc < "foo" { 42 } else { 123 }"#).unwrap(), 123); } let mut engine = Engine::new(); @@ -57,30 +44,15 @@ fn test_optimizer_run() { engine.set_optimization_level(OptimizationLevel::Simple); - assert_eq!( - engine - .eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }").unwrap(), 42); engine.set_fast_operators(false); - assert_eq!( - engine - .eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }") - .unwrap(), - 123 - ); + assert_eq!(engine.eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }").unwrap(), 123); engine.set_optimization_level(OptimizationLevel::Full); - assert_eq!( - engine - .eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }") - .unwrap(), - 123 - ); + assert_eq!(engine.eval::("if 1 == 1 || 2 > 3 { 42 } else { 123 }").unwrap(), 123); } #[cfg(feature = "metadata")] @@ -93,46 +65,27 @@ fn test_optimizer_parse() { engine.set_optimization_level(OptimizationLevel::Simple); - let ast = engine - .compile("{ const DECISION = false; if DECISION { 42 } else { 123 } }") - .unwrap(); + let ast = engine.compile("{ const DECISION = false; if DECISION { 42 } else { 123 } }").unwrap(); - assert_eq!( - format!("{ast:?}"), - r#"AST { source: None, doc: None, resolver: None, body: [Expr(123 @ 1:53)] }"# - ); + assert_eq!(format!("{ast:?}"), r#"AST { source: None, doc: "", resolver: None, body: [Expr(123 @ 1:53)] }"#); - let ast = engine - .compile("const DECISION = false; if DECISION { 42 } else { 123 }") - .unwrap(); + let ast = engine.compile("const DECISION = false; if DECISION { 42 } else { 123 }").unwrap(); - assert_eq!( - format!("{ast:?}"), - r#"AST { source: None, doc: None, resolver: None, body: [Var(("DECISION" @ 1:7, false @ 1:18, None), CONSTANT, 1:1), Expr(123 @ 1:51)] }"# - ); + assert_eq!(format!("{ast:?}"), r#"AST { source: None, doc: "", resolver: None, body: [Var(("DECISION" @ 1:7, false @ 1:18, None), CONSTANT, 1:1), Expr(123 @ 1:51)] }"#); let ast = engine.compile("if 1 == 2 { 42 }").unwrap(); - assert_eq!( - format!("{ast:?}"), - r#"AST { source: None, doc: None, resolver: None, body: [] }"# - ); + assert_eq!(format!("{ast:?}"), r#"AST { source: None, doc: "", resolver: None, body: [] }"#); engine.set_optimization_level(OptimizationLevel::Full); let ast = engine.compile("abs(-42)").unwrap(); - assert_eq!( - format!("{ast:?}"), - r#"AST { source: None, doc: None, resolver: None, body: [Expr(42 @ 1:1)] }"# - ); + assert_eq!(format!("{ast:?}"), r#"AST { source: None, doc: "", resolver: None, body: [Expr(42 @ 1:1)] }"#); let ast = engine.compile("NUMBER").unwrap(); - assert_eq!( - format!("{ast:?}"), - r#"AST { source: None, doc: None, resolver: None, body: [Expr(Variable(NUMBER) @ 1:1)] }"# - ); + assert_eq!(format!("{ast:?}"), r#"AST { source: None, doc: "", resolver: None, body: [Expr(Variable(NUMBER) @ 1:1)] }"#); let mut module = Module::new(); module.set_var("NUMBER", 42 as INT); @@ -141,10 +94,7 @@ fn test_optimizer_parse() { let ast = engine.compile("NUMBER").unwrap(); - assert_eq!( - format!("{ast:?}"), - r#"AST { source: None, doc: None, resolver: None, body: [Expr(42 @ 1:1)] }"# - ); + assert_eq!(format!("{ast:?}"), r#"AST { source: None, doc: "", resolver: None, body: [Expr(42 @ 1:1)] }"#); } #[cfg(not(feature = "no_function"))] @@ -165,10 +115,7 @@ fn test_optimizer_scope() { scope.push("FOO", 123 as INT); assert_eq!(engine.eval_ast::(&ast).unwrap(), 42); - assert_eq!( - engine.eval_ast_with_scope::(&mut scope, &ast).unwrap(), - 42 - ); + assert_eq!(engine.eval_ast_with_scope::(&mut scope, &ast).unwrap(), 42); let ast = engine.compile_with_scope(&scope, SCRIPT).unwrap(); @@ -226,9 +173,7 @@ fn test_optimizer_full() { .register_type_with_name::("TestStruct") .register_fn("ts", |n: INT| TestStruct(n)) .register_fn("value", |ts: &mut TestStruct| ts.0) - .register_fn("+", |ts1: &mut TestStruct, ts2: TestStruct| { - TestStruct(ts1.0 + ts2.0) - }); + .register_fn("+", |ts1: &mut TestStruct, ts2: TestStruct| TestStruct(ts1.0 + ts2.0)); let ast = engine .compile( @@ -242,10 +187,7 @@ fn test_optimizer_full() { #[cfg(feature = "internals")] assert_eq!(ast.statements().len(), 2); - assert_eq!( - engine.eval_ast_with_scope::(&mut scope, &ast).unwrap(), - 42 - ); + assert_eq!(engine.eval_ast_with_scope::(&mut scope, &ast).unwrap(), 42); assert_eq!(scope.len(), 1); diff --git a/tests/options.rs b/tests/options.rs index 7967bd230..fe330574c 100644 --- a/tests/options.rs +++ b/tests/options.rs @@ -25,17 +25,13 @@ fn test_options_allow() { assert!(engine.compile("let x = || 42;").is_err()); } - let ast = engine - .compile("let x = 0; while x < 10 { x += 1; }") - .unwrap(); + let ast = engine.compile("let x = 0; while x < 10 { x += 1; }").unwrap(); engine.set_allow_looping(false); engine.run_ast(&ast).unwrap(); - assert!(engine - .compile("let x = 0; while x < 10 { x += 1; }") - .is_err()); + assert!(engine.compile("let x = 0; while x < 10 { x += 1; }").is_err()); engine.compile("let x = 42; let x = 123;").unwrap(); @@ -83,18 +79,11 @@ fn test_options_strict_var() { assert!(engine.compile("let x = if y { z } else { w };").is_err()); #[cfg(not(feature = "no_object"))] - engine - .compile_with_scope(&scope, "if x.abs() { y } else { x + y.len };") - .unwrap(); + engine.compile_with_scope(&scope, "if x.abs() { y } else { x + y.len };").unwrap(); engine.compile("let y = 42; let x = y;").unwrap(); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "{ let y = 42; x * y }") - .unwrap(), - 42 * 42 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "{ let y = 42; x * y }").unwrap(), 42 * 42); #[cfg(not(feature = "no_function"))] assert!(engine.compile("fn foo(x) { x + y }").is_err()); @@ -105,38 +94,22 @@ fn test_options_strict_var() { assert!(engine.compile("print(h::y::z);").is_err()); assert!(engine.compile("fn foo() { h::y::z }").is_err()); assert!(engine.compile("fn foo() { h::y::foo() }").is_err()); - engine - .compile(r#"import "hello" as h; fn foo() { h::a::b::c } print(h::y::z);"#) - .unwrap(); + engine.compile(r#"import "hello" as h; fn foo() { h::a::b::c } print(h::y::z);"#).unwrap(); assert!(engine.compile("let x = h::y::foo();").is_err()); - engine - .compile(r#"import "hello" as h; fn foo() { h::a::b::c() } let x = h::y::foo();"#) - .unwrap(); + engine.compile(r#"import "hello" as h; fn foo() { h::a::b::c() } let x = h::y::foo();"#).unwrap(); } #[cfg(not(feature = "no_function"))] { - assert_eq!( - engine - .eval_with_scope::(&mut scope, "fn foo(z) { z } let f = foo; call(f, x)") - .unwrap(), - 42 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "fn foo(z) { z } let f = foo; call(f, x)").unwrap(), 42); assert!(engine.compile("let f = |y| x * y;").is_err()); #[cfg(not(feature = "no_closure"))] { engine.compile("let x = 42; let f = |y| x * y;").unwrap(); - engine - .compile("let x = 42; let f = |y| { || x + y };") - .unwrap(); + engine.compile("let x = 42; let f = |y| { || x + y };").unwrap(); assert!(engine.compile("fn foo() { |y| { || x + y } }").is_err()); } #[cfg(not(feature = "no_optimize"))] - assert_eq!( - engine - .eval_with_scope::(&mut scope, "fn foo(z) { y + z } foo(x)") - .unwrap(), - 42 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "fn foo(z) { y + z } foo(x)").unwrap(), 42); } } diff --git a/tests/packages.rs b/tests/packages.rs index 3afb3d8ec..99055164d 100644 --- a/tests/packages.rs +++ b/tests/packages.rs @@ -44,9 +44,7 @@ fn test_packages() { #[test] fn test_packages_with_script() { let mut engine = Engine::new(); - let ast = engine - .compile("fn foo(x) { x + 1 } fn bar(x) { foo(x) + 1 }") - .unwrap(); + let ast = engine.compile("fn foo(x) { x + 1 } fn bar(x) { foo(x) + 1 }").unwrap(); let module = Module::eval_ast_as_new(Scope::new(), &ast, &engine).unwrap(); engine.register_global_module(module.into()); diff --git a/tests/plugins.rs b/tests/plugins.rs index 5081d8a7b..2ba8d2f51 100644 --- a/tests/plugins.rs +++ b/tests/plugins.rs @@ -114,36 +114,19 @@ fn test_plugins_package() { { assert_eq!(engine.eval::("let a = [1, 2, 3]; a.foo").unwrap(), 1); engine.run("const A = [1, 2, 3]; A.no_effect(42);").unwrap(); - engine - .run("const A = [1, 2, 3]; A.no_effect = 42;") - .unwrap(); + engine.run("const A = [1, 2, 3]; A.no_effect = 42;").unwrap(); - assert!( - matches!(*engine.run("const A = [1, 2, 3]; A.test(42);").unwrap_err(), - EvalAltResult::ErrorNonPureMethodCallOnConstant(x, ..) if x == "test") - ) + assert!(matches!( + *engine.run("const A = [1, 2, 3]; A.test(42);").unwrap_err(), + EvalAltResult::ErrorNonPureMethodCallOnConstant(x, ..) if x == "test")); } assert_eq!(engine.eval::(r#"hash("hello")"#).unwrap(), 42); assert_eq!(engine.eval::(r#"hash2("hello")"#).unwrap(), 42); - assert_eq!( - engine.eval::("let a = [1, 2, 3]; test(a, 2)").unwrap(), - 6 - ); - assert_eq!( - engine.eval::("let a = [1, 2, 3]; hi(a, 2)").unwrap(), - 6 - ); - assert_eq!( - engine.eval::("let a = [1, 2, 3]; test(a, 2)").unwrap(), - 6 - ); - assert_eq!( - engine - .eval::("let a = [1, 2, 3]; greet(test(a, 2))") - .unwrap(), - "6 kitties" - ); + assert_eq!(engine.eval::("let a = [1, 2, 3]; test(a, 2)").unwrap(), 6); + assert_eq!(engine.eval::("let a = [1, 2, 3]; hi(a, 2)").unwrap(), 6); + assert_eq!(engine.eval::("let a = [1, 2, 3]; test(a, 2)").unwrap(), 6); + assert_eq!(engine.eval::("let a = [1, 2, 3]; greet(test(a, 2))").unwrap(), "6 kitties"); assert_eq!(engine.eval::("2 + 2").unwrap(), 4); engine.set_fast_operators(false); @@ -229,11 +212,6 @@ mod handle { scope.push("world", WorldHandle::from(world)); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval_with_scope::(&mut scope, "world.len") - .unwrap(), - 1 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "world.len").unwrap(), 1); } } diff --git a/tests/power_of.rs b/tests/power_of.rs index af621d1be..2d80b0778 100644 --- a/tests/power_of.rs +++ b/tests/power_of.rs @@ -4,7 +4,7 @@ use rhai::{Engine, INT}; use rhai::FLOAT; #[cfg(not(feature = "no_float"))] -const EPSILON: FLOAT = 0.000_001; +const EPSILON: FLOAT = FLOAT::EPSILON; #[test] fn test_power_of() { @@ -16,10 +16,7 @@ fn test_power_of() { #[cfg(not(feature = "no_float"))] { - assert!( - (engine.eval::("2.2 ** 3.3").unwrap() - 13.489_468_760_533_386 as FLOAT).abs() - <= EPSILON - ); + assert!((engine.eval::("2.2 ** 3.3").unwrap() - (2.2 as FLOAT).powf(3.3)).abs() <= EPSILON); assert!((engine.eval::("2.0**-2.0").unwrap() - 0.25 as FLOAT).abs() < EPSILON); assert!((engine.eval::("(-2.0**-2.0)").unwrap() - 0.25 as FLOAT).abs() < EPSILON); assert!((engine.eval::("(-2.0**-2)").unwrap() - 0.25 as FLOAT).abs() < EPSILON); @@ -36,24 +33,10 @@ fn test_power_of_equals() { #[cfg(not(feature = "no_float"))] { - assert!( - (engine.eval::("let x = 2.2; x **= 3.3; x").unwrap() - - 13.489_468_760_533_386 as FLOAT) - .abs() - <= EPSILON - ); - assert!( - (engine.eval::("let x = 2.0; x **= -2.0; x").unwrap() - 0.25 as FLOAT).abs() - < EPSILON - ); - assert!( - (engine.eval::("let x = -2.0; x **= -2.0; x").unwrap() - 0.25 as FLOAT).abs() - < EPSILON - ); - assert!( - (engine.eval::("let x = -2.0; x **= -2; x").unwrap() - 0.25 as FLOAT).abs() - < EPSILON - ); + assert!((engine.eval::("let x = 2.2; x **= 3.3; x").unwrap() - (2.2 as FLOAT).powf(3.3)).abs() <= EPSILON); + assert!((engine.eval::("let x = 2.0; x **= -2.0; x").unwrap() - 0.25 as FLOAT).abs() < EPSILON); + assert!((engine.eval::("let x = -2.0; x **= -2.0; x").unwrap() - 0.25 as FLOAT).abs() < EPSILON); + assert!((engine.eval::("let x = -2.0; x **= -2; x").unwrap() - 0.25 as FLOAT).abs() < EPSILON); assert_eq!(engine.eval::("let x =4; x **= 3; x").unwrap(), 64); } } diff --git a/tests/print.rs b/tests/print.rs index 470cbc7d0..21657ab31 100644 --- a/tests/print.rs +++ b/tests/print.rs @@ -12,24 +12,9 @@ fn test_to_string() { scope.push("y", 42_i32); scope.push("z", 42_i16); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "to_string(x)") - .unwrap(), - "42" - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "to_string(x)") - .unwrap(), - "42" - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "to_string(x)") - .unwrap(), - "42" - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "to_string(x)").unwrap(), "42"); + assert_eq!(engine.eval_with_scope::(&mut scope, "to_string(x)").unwrap(), "42"); + assert_eq!(engine.eval_with_scope::(&mut scope, "to_string(x)").unwrap(), "42"); } #[test] @@ -42,14 +27,10 @@ fn test_print_debug() { let mut engine = Engine::new(); - engine - .on_print(move |s| log1.write().unwrap().push(format!("entry: {s}"))) - .on_debug(move |s, src, pos| { - let src = src.unwrap_or("unknown"); - log2.write() - .unwrap() - .push(format!("DEBUG of {src} at {pos:?}: {s}")) - }); + engine.on_print(move |s| log1.write().unwrap().push(format!("entry: {s}"))).on_debug(move |s, src, pos| { + let src = src.unwrap_or("unknown"); + log2.write().unwrap().push(format!("DEBUG of {src} at {pos:?}: {s}")) + }); // Evaluate script engine.run("print(40 + 2)").unwrap(); @@ -60,14 +41,7 @@ fn test_print_debug() { // 'logbook' captures all the 'print' and 'debug' output assert_eq!(logbook.read().unwrap().len(), 2); assert_eq!(logbook.read().unwrap()[0], "entry: 42"); - assert_eq!( - logbook.read().unwrap()[1], - if cfg!(not(feature = "no_position")) { - r#"DEBUG of world at 1:19: "hello!""# - } else { - r#"DEBUG of world at none: "hello!""# - } - ); + assert_eq!(logbook.read().unwrap()[1], if cfg!(not(feature = "no_position")) { r#"DEBUG of world at 1:19: "hello!""# } else { r#"DEBUG of world at none: "hello!""# }); for entry in logbook.read().unwrap().iter() { println!("{entry}"); diff --git a/tests/rustfmt.toml b/tests/rustfmt.toml new file mode 100644 index 000000000..40ea3ca54 --- /dev/null +++ b/tests/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 288 +chain_width = 120 diff --git a/tests/serde.rs b/tests/serde.rs index a6289898b..66ba67c22 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -25,17 +25,18 @@ fn test_serde_ser_primary_types() { assert!(to_dynamic(()).unwrap().is_unit()); #[cfg(not(feature = "no_float"))] - { - assert!(to_dynamic(123.456_f64).unwrap().is::()); - assert!(to_dynamic(123.456_f32).unwrap().is::()); - } + assert!(to_dynamic(123.456_f64).unwrap().is::()); + + #[cfg(not(feature = "no_float"))] + assert!(to_dynamic(123.456_f32).unwrap().is::()); #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] - { - assert!(to_dynamic(123.456_f64).unwrap().is::()); - assert!(to_dynamic(123.456_f32).unwrap().is::()); - } + assert!(to_dynamic(123.456_f64).unwrap().is::()); + + #[cfg(feature = "no_float")] + #[cfg(feature = "decimal")] + assert!(to_dynamic(123.456_f32).unwrap().is::()); assert!(to_dynamic("hello".to_string()).unwrap().is::()); } @@ -134,38 +135,25 @@ fn test_serde_ser_externally_tagged_enum() { } { - assert_eq!( - "VariantUnit", - to_dynamic(MyEnum::VariantUnit) - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + assert_eq!("VariantUnit", to_dynamic(MyEnum::VariantUnit).unwrap().into_immutable_string().unwrap().as_str()); } #[cfg(not(feature = "no_index"))] { - let mut map = to_dynamic(MyEnum::VariantUnitTuple()) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantUnitTuple()).unwrap().cast::(); let content = map.remove("VariantUnitTuple").unwrap().cast::(); assert!(map.is_empty()); assert!(content.is_empty()); } - let mut map = to_dynamic(MyEnum::VariantNewtype(123)) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantNewtype(123)).unwrap().cast::(); let content = map.remove("VariantNewtype").unwrap(); assert!(map.is_empty()); assert_eq!(Ok(123), content.as_int()); #[cfg(not(feature = "no_index"))] { - let mut map = to_dynamic(MyEnum::VariantTuple(123, 456)) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantTuple(123, 456)).unwrap().cast::(); let content = map.remove("VariantTuple").unwrap().cast::(); assert!(map.is_empty()); assert_eq!(2, content.len()); @@ -173,16 +161,12 @@ fn test_serde_ser_externally_tagged_enum() { assert_eq!(Ok(456), content[1].as_int()); } - let mut map = to_dynamic(MyEnum::VariantEmptyStruct {}) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantEmptyStruct {}).unwrap().cast::(); let map_inner = map.remove("VariantEmptyStruct").unwrap().cast::(); assert!(map.is_empty()); assert!(map_inner.is_empty()); - let mut map = to_dynamic(MyEnum::VariantStruct { a: 123 }) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantStruct { a: 123 }).unwrap().cast::(); let mut map_inner = map.remove("VariantStruct").unwrap().cast::(); assert!(map.is_empty()); assert_eq!(Ok(123), map_inner.remove("a").unwrap().as_int()); @@ -199,30 +183,12 @@ fn test_serde_ser_internally_tagged_enum() { VariantStruct { a: i32 }, } - let mut map = to_dynamic(MyEnum::VariantEmptyStruct {}) - .unwrap() - .cast::(); - assert_eq!( - "VariantEmptyStruct", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + let mut map = to_dynamic(MyEnum::VariantEmptyStruct {}).unwrap().cast::(); + assert_eq!("VariantEmptyStruct", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); assert!(map.is_empty()); - let mut map = to_dynamic(MyEnum::VariantStruct { a: 123 }) - .unwrap() - .cast::(); - assert_eq!( - "VariantStruct", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + let mut map = to_dynamic(MyEnum::VariantStruct { a: 123 }).unwrap().cast::(); + assert_eq!("VariantStruct", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); assert_eq!(Ok(123), map.remove("a").unwrap().as_int()); assert!(map.is_empty()); } @@ -247,62 +213,28 @@ fn test_serde_ser_adjacently_tagged_enum() { } let mut map = to_dynamic(MyEnum::VariantUnit).unwrap().cast::(); - assert_eq!( - "VariantUnit", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + assert_eq!("VariantUnit", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); assert!(map.is_empty()); #[cfg(not(feature = "no_index"))] { - let mut map = to_dynamic(MyEnum::VariantUnitTuple()) - .unwrap() - .cast::(); - assert_eq!( - "VariantUnitTuple", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + let mut map = to_dynamic(MyEnum::VariantUnitTuple()).unwrap().cast::(); + assert_eq!("VariantUnitTuple", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); let content = map.remove("content").unwrap().cast::(); assert!(map.is_empty()); assert!(content.is_empty()); } - let mut map = to_dynamic(MyEnum::VariantNewtype(123)) - .unwrap() - .cast::(); - assert_eq!( - "VariantNewtype", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + let mut map = to_dynamic(MyEnum::VariantNewtype(123)).unwrap().cast::(); + assert_eq!("VariantNewtype", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); let content = map.remove("content").unwrap(); assert!(map.is_empty()); assert_eq!(Ok(123), content.as_int()); #[cfg(not(feature = "no_index"))] { - let mut map = to_dynamic(MyEnum::VariantTuple(123, 456)) - .unwrap() - .cast::(); - assert_eq!( - "VariantTuple", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + let mut map = to_dynamic(MyEnum::VariantTuple(123, 456)).unwrap().cast::(); + assert_eq!("VariantTuple", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); let content = map.remove("content").unwrap().cast::(); assert!(map.is_empty()); assert_eq!(2, content.len()); @@ -310,28 +242,14 @@ fn test_serde_ser_adjacently_tagged_enum() { assert_eq!(Ok(456), content[1].as_int()); } - let mut map = to_dynamic(MyEnum::VariantEmptyStruct {}) - .unwrap() - .cast::(); - assert_eq!( - "VariantEmptyStruct", - map.remove("tag") - .unwrap() - .into_immutable_string() - .unwrap() - .as_str() - ); + let mut map = to_dynamic(MyEnum::VariantEmptyStruct {}).unwrap().cast::(); + assert_eq!("VariantEmptyStruct", map.remove("tag").unwrap().into_immutable_string().unwrap().as_str()); let map_inner = map.remove("content").unwrap().cast::(); assert!(map.is_empty()); assert!(map_inner.is_empty()); - let mut map = to_dynamic(MyEnum::VariantStruct { a: 123 }) - .unwrap() - .cast::(); - assert_eq!( - "VariantStruct", - map.remove("tag").unwrap().into_string().unwrap() - ); + let mut map = to_dynamic(MyEnum::VariantStruct { a: 123 }).unwrap().cast::(); + assert_eq!("VariantStruct", map.remove("tag").unwrap().into_string().unwrap()); let mut map_inner = map.remove("content").unwrap().cast::(); assert!(map.is_empty()); assert_eq!(Ok(123), map_inner.remove("a").unwrap().as_int()); @@ -349,20 +267,14 @@ fn test_serde_ser_untagged_enum() { VariantStruct2 { b: i32 }, } - let map = to_dynamic(MyEnum::VariantEmptyStruct {}) - .unwrap() - .cast::(); + let map = to_dynamic(MyEnum::VariantEmptyStruct {}).unwrap().cast::(); assert!(map.is_empty()); - let mut map = to_dynamic(MyEnum::VariantStruct1 { a: 123 }) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantStruct1 { a: 123 }).unwrap().cast::(); assert_eq!(Ok(123), map.remove("a").unwrap().as_int()); assert!(map.is_empty()); - let mut map = to_dynamic(MyEnum::VariantStruct2 { b: 123 }) - .unwrap() - .cast::(); + let mut map = to_dynamic(MyEnum::VariantStruct2 { b: 123 }).unwrap().cast::(); assert_eq!(Ok(123), map.remove("b").unwrap().as_int()); assert!(map.is_empty()); } @@ -375,13 +287,10 @@ fn test_serde_de_primary_types() { let _: () = from_dynamic::<()>(&().into()).unwrap(); #[cfg(not(feature = "no_float"))] - { - assert_eq!(123.456, from_dynamic::(&123.456.into()).unwrap()); - assert_eq!( - 123.456, - from_dynamic::(&Dynamic::from(123.456_f32)).unwrap() - ); - } + assert_eq!(123.456, from_dynamic::(&123.456.into()).unwrap()); + + #[cfg(not(feature = "no_float"))] + assert_eq!(123.456, from_dynamic::(&Dynamic::from(123.456_f32)).unwrap()); #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] @@ -392,10 +301,7 @@ fn test_serde_de_primary_types() { assert_eq!(123.456, from_dynamic::(&d).unwrap()); } - assert_eq!( - "hello", - from_dynamic::(&"hello".to_string().into()).unwrap() - ); + assert_eq!("hello", from_dynamic::(&"hello".to_string().into()).unwrap()); } #[cfg(not(feature = "no_object"))] @@ -413,9 +319,7 @@ fn test_serde_de_variants() { fn deserialize_foo<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { let value = ::deserialize(deserializer).unwrap(); - value - .try_cast::>() - .ok_or_else(|| serde::de::Error::custom("type error")) + value.try_cast::>().ok_or_else(|| serde::de::Error::custom("type error")) } let value = Arc::new(Foo); @@ -565,46 +469,31 @@ fn test_serde_de_externally_tagged_enum() { let array: Array = vec![]; let mut map_outer = Map::new(); map_outer.insert("VariantUnitTuple".into(), array.into()); - assert_eq!( - MyEnum::VariantUnitTuple(), - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantUnitTuple(), from_dynamic(&map_outer.into()).unwrap()); } let mut map_outer = Map::new(); map_outer.insert("VariantNewtype".into(), (123 as INT).into()); - assert_eq!( - MyEnum::VariantNewtype(123), - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantNewtype(123), from_dynamic(&map_outer.into()).unwrap()); #[cfg(not(feature = "no_index"))] { let array: Array = vec![(123 as INT).into(), (456 as INT).into()]; let mut map_outer = Map::new(); map_outer.insert("VariantTuple".into(), array.into()); - assert_eq!( - MyEnum::VariantTuple(123, 456), - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantTuple(123, 456), from_dynamic(&map_outer.into()).unwrap()); } let map_inner = Map::new(); let mut map_outer = Map::new(); map_outer.insert("VariantEmptyStruct".into(), map_inner.into()); - assert_eq!( - MyEnum::VariantEmptyStruct {}, - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantEmptyStruct {}, from_dynamic(&map_outer.into()).unwrap()); let mut map_inner = Map::new(); map_inner.insert("a".into(), (123 as INT).into()); let mut map_outer = Map::new(); map_outer.insert("VariantStruct".into(), map_inner.into()); - assert_eq!( - MyEnum::VariantStruct { a: 123 }, - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantStruct { a: 123 }, from_dynamic(&map_outer.into()).unwrap()); } #[test] @@ -620,17 +509,11 @@ fn test_serde_de_internally_tagged_enum() { let mut map = Map::new(); map.insert("tag".into(), "VariantStruct".into()); map.insert("a".into(), (123 as INT).into()); - assert_eq!( - MyEnum::VariantStruct { a: 123 }, - from_dynamic(&map.into()).unwrap() - ); + assert_eq!(MyEnum::VariantStruct { a: 123 }, from_dynamic(&map.into()).unwrap()); let mut map = Map::new(); map.insert("tag".into(), "VariantEmptyStruct".into()); - assert_eq!( - MyEnum::VariantEmptyStruct {}, - from_dynamic(&map.into()).unwrap() - ); + assert_eq!(MyEnum::VariantEmptyStruct {}, from_dynamic(&map.into()).unwrap()); } #[test] @@ -654,10 +537,7 @@ fn test_serde_de_adjacently_tagged_enum() { let mut map_outer = Map::new(); map_outer.insert("tag".into(), "VariantUnit".into()); - assert_eq!( - MyEnum::VariantUnit, - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantUnit, from_dynamic(&map_outer.into()).unwrap()); #[cfg(not(feature = "no_index"))] { @@ -665,19 +545,13 @@ fn test_serde_de_adjacently_tagged_enum() { let mut map_outer = Map::new(); map_outer.insert("tag".into(), "VariantUnitTuple".into()); map_outer.insert("content".into(), array.into()); - assert_eq!( - MyEnum::VariantUnitTuple(), - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantUnitTuple(), from_dynamic(&map_outer.into()).unwrap()); } let mut map_outer = Map::new(); map_outer.insert("tag".into(), "VariantNewtype".into()); map_outer.insert("content".into(), (123 as INT).into()); - assert_eq!( - MyEnum::VariantNewtype(123), - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantNewtype(123), from_dynamic(&map_outer.into()).unwrap()); #[cfg(not(feature = "no_index"))] { @@ -685,30 +559,21 @@ fn test_serde_de_adjacently_tagged_enum() { let mut map_outer = Map::new(); map_outer.insert("tag".into(), "VariantTuple".into()); map_outer.insert("content".into(), array.into()); - assert_eq!( - MyEnum::VariantTuple(123, 456), - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantTuple(123, 456), from_dynamic(&map_outer.into()).unwrap()); } let map_inner = Map::new(); let mut map_outer = Map::new(); map_outer.insert("tag".into(), "VariantEmptyStruct".into()); map_outer.insert("content".into(), map_inner.into()); - assert_eq!( - MyEnum::VariantEmptyStruct {}, - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantEmptyStruct {}, from_dynamic(&map_outer.into()).unwrap()); let mut map_inner = Map::new(); map_inner.insert("a".into(), (123 as INT).into()); let mut map_outer = Map::new(); map_outer.insert("tag".into(), "VariantStruct".into()); map_outer.insert("content".into(), map_inner.into()); - assert_eq!( - MyEnum::VariantStruct { a: 123 }, - from_dynamic(&map_outer.into()).unwrap() - ); + assert_eq!(MyEnum::VariantStruct { a: 123 }, from_dynamic(&map_outer.into()).unwrap()); } #[test] @@ -723,24 +588,15 @@ fn test_serde_de_untagged_enum() { } let map = Map::new(); - assert_eq!( - MyEnum::VariantEmptyStruct {}, - from_dynamic(&map.into()).unwrap() - ); + assert_eq!(MyEnum::VariantEmptyStruct {}, from_dynamic(&map.into()).unwrap()); let mut map = Map::new(); map.insert("a".into(), (123 as INT).into()); - assert_eq!( - MyEnum::VariantStruct1 { a: 123 }, - from_dynamic(&map.into()).unwrap() - ); + assert_eq!(MyEnum::VariantStruct1 { a: 123 }, from_dynamic(&map.into()).unwrap()); let mut map = Map::new(); map.insert("b".into(), (123 as INT).into()); - assert_eq!( - MyEnum::VariantStruct2 { b: 123 }, - from_dynamic(&map.into()).unwrap() - ); + assert_eq!(MyEnum::VariantStruct2 { b: 123 }, from_dynamic(&map.into()).unwrap()); } #[test] @@ -795,10 +651,7 @@ fn test_serde_json_numbers() -> serde_json::Result<()> { let d: Dynamic = serde_json::from_str("10000000000000000000").unwrap(); assert!(d.is::()); - assert_eq!( - d.as_decimal().unwrap(), - Decimal::from_str("10000000000000000000").unwrap() - ); + assert_eq!(d.as_decimal().unwrap(), Decimal::from_str("10000000000000000000").unwrap()); let d: Dynamic = serde_json::from_str("10000000000000000000000000").unwrap(); assert!(d.is::()); @@ -819,41 +672,23 @@ fn test_serde_optional() { engine.register_type_with_name::("TestStruct"); let r = engine.eval::("#{ foo: 'a' }").unwrap(); - - assert_eq!( - from_dynamic::(&r).unwrap(), - TestStruct { foo: Some('a') } - ); + assert_eq!(from_dynamic::(&r).unwrap(), TestStruct { foo: Some('a') }); let r = engine.eval::("#{ foo: () }").unwrap(); - - assert_eq!( - from_dynamic::(&r).unwrap(), - TestStruct { foo: None } - ); + assert_eq!(from_dynamic::(&r).unwrap(), TestStruct { foo: None }); let r = engine.eval::("#{ }").unwrap(); - - assert_eq!( - from_dynamic::(&r).unwrap(), - TestStruct { foo: None } - ); + assert_eq!(from_dynamic::(&r).unwrap(), TestStruct { foo: None }); let ts = TestStruct { foo: Some('a') }; - let r = to_dynamic(&ts).unwrap(); - let map = r.cast::(); - assert_eq!(map.len(), 1); assert_eq!(map.get("foo").unwrap().as_char().unwrap(), 'a'); let ts = TestStruct { foo: None }; - let r = to_dynamic(&ts).unwrap(); - let map = r.cast::(); - assert_eq!(map.len(), 1); let _: () = map.get("foo").unwrap().as_unit().unwrap(); } @@ -912,18 +747,12 @@ fn test_serde_scope() { let json = serde_json::to_string(&scope).unwrap(); - assert_eq!( - json, - r#"[{"name":"x","value":42},{"name":"y","value":true,"is_constant":true},{"name":"z","value":"serde::test_serde_scope::TestStruct"}]"# - ); + assert_eq!(json, r#"[{"name":"x","value":42},{"name":"y","value":true,"is_constant":true},{"name":"z","value":"serde::test_serde_scope::TestStruct"}]"#); scope = serde_json::from_str(&json).unwrap(); assert_eq!(scope.len(), 3); assert_eq!(scope.get_value::("x").unwrap(), 42); assert!(scope.get_value::("y").unwrap()); - assert_eq!( - scope.get_value::("z").unwrap(), - "serde::test_serde_scope::TestStruct" - ); + assert_eq!(scope.get_value::("z").unwrap(), "serde::test_serde_scope::TestStruct"); } diff --git a/tests/string.rs b/tests/string.rs index 7fbf5516a..76e987e92 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -4,74 +4,25 @@ use rhai::{Engine, EvalAltResult, ImmutableString, Scope, INT}; fn test_string() { let engine = Engine::new(); + assert_eq!(engine.eval::(r#""Test string: \u2764""#).unwrap(), "Test string: ❤"); + assert_eq!(engine.eval::(r#""Test string: ""\u2764""""#).unwrap(), r#"Test string: "❤""#); + assert_eq!(engine.eval::("\"Test\rstring: \\u2764\"").unwrap(), "Test\rstring: ❤"); assert_eq!( - engine.eval::(r#""Test string: \u2764""#).unwrap(), - "Test string: ❤" - ); - assert_eq!( - engine - .eval::(r#""Test string: ""\u2764""""#) - .unwrap(), - r#"Test string: "❤""# - ); - assert_eq!( - engine.eval::("\"Test\rstring: \\u2764\"").unwrap(), - "Test\rstring: ❤" - ); - assert_eq!( - engine - .eval::(" \"Test string: \\u2764\\\n hello, world!\"") - .unwrap(), - if cfg!(not(feature = "no_position")) { - "Test string: ❤ hello, world!" - } else { - "Test string: ❤ hello, world!" - } - ); - assert_eq!( - engine - .eval::(" `Test string: \\u2764\nhello,\\nworld!`") - .unwrap(), - "Test string: \\u2764\nhello,\\nworld!" - ); - assert_eq!( - engine - .eval::(r#" `Test string: \\u2764\n``hello``,\\n"world"!`"#) - .unwrap(), - r#"Test string: \\u2764\n`hello`,\\n"world"!"# - ); - assert_eq!( - engine - .eval::(" `\nTest string: \\u2764\nhello,\\nworld!`") - .unwrap(), - "Test string: \\u2764\nhello,\\nworld!" - ); - assert_eq!( - engine - .eval::(" `\r\nTest string: \\u2764\nhello,\\nworld!`") - .unwrap(), - "Test string: \\u2764\nhello,\\nworld!" - ); - assert_eq!( - engine.eval::(r#""Test string: \x58""#).unwrap(), - "Test string: X" - ); - assert_eq!( - engine.eval::(r#""\"hello\"""#).unwrap(), - r#""hello""# + engine.eval::(" \"Test string: \\u2764\\\n hello, world!\"").unwrap(), + if cfg!(not(feature = "no_position")) { "Test string: ❤ hello, world!" } else { "Test string: ❤ hello, world!" } ); + assert_eq!(engine.eval::(" `Test string: \\u2764\nhello,\\nworld!`").unwrap(), "Test string: \\u2764\nhello,\\nworld!"); + assert_eq!(engine.eval::(r#" `Test string: \\u2764\n``hello``,\\n"world"!`"#).unwrap(), r#"Test string: \\u2764\n`hello`,\\n"world"!"#); + assert_eq!(engine.eval::(" `\nTest string: \\u2764\nhello,\\nworld!`").unwrap(), "Test string: \\u2764\nhello,\\nworld!"); + assert_eq!(engine.eval::(" `\r\nTest string: \\u2764\nhello,\\nworld!`").unwrap(), "Test string: \\u2764\nhello,\\nworld!"); + assert_eq!(engine.eval::(r#""Test string: \x58""#).unwrap(), "Test string: X"); + assert_eq!(engine.eval::(r#""\"hello\"""#).unwrap(), r#""hello""#); assert_eq!(engine.eval::(r#""foo" + "bar""#).unwrap(), "foobar"); - assert!(engine - .eval::(r#"let y = "hello, world!"; "world" in y"#) - .unwrap()); - assert!(engine - .eval::(r#"let y = "hello, world!"; 'w' in y"#) - .unwrap()); - assert!(!engine - .eval::(r#"let y = "hello, world!"; "hey" in y"#) - .unwrap()); + assert!(engine.eval::(r#"let y = "hello, world!"; "world" in y"#).unwrap()); + assert!(engine.eval::(r#"let y = "hello, world!"; 'w' in y"#).unwrap()); + assert!(!engine.eval::(r#"let y = "hello, world!"; "hey" in y"#).unwrap()); assert_eq!(engine.eval::(r#""foo" + 123"#).unwrap(), "foo123"); @@ -79,48 +30,28 @@ fn test_string() { assert_eq!(engine.eval::("to_string(42)").unwrap(), "42"); #[cfg(not(feature = "no_index"))] - { - assert_eq!( - engine.eval::(r#"let y = "hello"; y[1]"#).unwrap(), - 'e' - ); - assert_eq!( - engine.eval::(r#"let y = "hello"; y[-1]"#).unwrap(), - 'o' - ); - assert_eq!( - engine.eval::(r#"let y = "hello"; y[-4]"#).unwrap(), - 'e' - ); - } + assert_eq!(engine.eval::(r#"let y = "hello"; y[1]"#).unwrap(), 'e'); + + #[cfg(not(feature = "no_index"))] + assert_eq!(engine.eval::(r#"let y = "hello"; y[-1]"#).unwrap(), 'o'); + + #[cfg(not(feature = "no_index"))] + assert_eq!(engine.eval::(r#"let y = "hello"; y[-4]"#).unwrap(), 'e'); #[cfg(not(feature = "no_object"))] assert_eq!(engine.eval::(r#"let y = "hello"; y.len"#).unwrap(), 5); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::(r#"let y = "hello"; y.clear(); y.len"#) - .unwrap(), - 0 - ); + assert_eq!(engine.eval::(r#"let y = "hello"; y.clear(); y.len"#).unwrap(), 0); assert_eq!(engine.eval::(r#"let y = "hello"; len(y)"#).unwrap(), 5); #[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::(r#"let y = "hello"; y[y.len-1]"#) - .unwrap(), - 'o' - ); + assert_eq!(engine.eval::(r#"let y = "hello"; y[y.len-1]"#).unwrap(), 'o'); #[cfg(not(feature = "no_float"))] - assert_eq!( - engine.eval::(r#""foo" + 123.4556"#).unwrap(), - "foo123.4556" - ); + assert_eq!(engine.eval::(r#""foo" + 123.4556"#).unwrap(), "foo123.4556"); } #[test] @@ -131,15 +62,9 @@ fn test_string_dynamic() { scope.push("y", "foo"); scope.push("z", "foo"); - assert!(engine - .eval_with_scope::(&mut scope, r#"x == "foo""#) - .unwrap()); - assert!(engine - .eval_with_scope::(&mut scope, r#"y == "foo""#) - .unwrap()); - assert!(engine - .eval_with_scope::(&mut scope, r#"z == "foo""#) - .unwrap()); + assert!(engine.eval_with_scope::(&mut scope, r#"x == "foo""#).unwrap()); + assert!(engine.eval_with_scope::(&mut scope, r#"y == "foo""#).unwrap()); + assert!(engine.eval_with_scope::(&mut scope, r#"z == "foo""#).unwrap()); } #[test] @@ -152,19 +77,15 @@ fn test_string_mut() { assert_eq!(engine.eval::(r#"pop("hello")"#).unwrap(), 'o'); assert_eq!(engine.eval::(r#"pop("hello", 3)"#).unwrap(), "llo"); - assert_eq!( - engine.eval::(r#"pop("hello", 10)"#).unwrap(), - "hello" - ); + assert_eq!(engine.eval::(r#"pop("hello", 10)"#).unwrap(), "hello"); assert_eq!(engine.eval::(r#"pop("hello", -42)"#).unwrap(), ""); assert_eq!(engine.eval::(r#"foo("hello")"#).unwrap(), 5); assert_eq!(engine.eval::(r#"bar("hello")"#).unwrap(), 5); - assert!( - matches!(*engine.eval::(r#"baz("hello")"#).unwrap_err(), - EvalAltResult::ErrorFunctionNotFound(f, ..) if f == "baz (&str | ImmutableString | String)" - ) - ); + assert!(matches!( + *engine.eval::(r#"baz("hello")"#).unwrap_err(), + EvalAltResult::ErrorFunctionNotFound(f, ..) if f == "baz (&str | ImmutableString | String)" + )); } #[cfg(not(feature = "no_object"))] @@ -172,142 +93,22 @@ fn test_string_mut() { fn test_string_substring() { let engine = Engine::new(); - assert_eq!( - engine - .eval::(r#"let x = "hello! \u2764\u2764\u2764"; x.sub_string(-2, 2)"#) - .unwrap(), - "❤❤" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1, 5)"# - ) - .unwrap(), - "❤❤ he" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1)"# - ) - .unwrap(), - "❤❤ hello! ❤❤❤" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(99)"# - ) - .unwrap(), - "" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1, -1)"# - ) - .unwrap(), - "" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1, 999)"# - ) - .unwrap(), - "❤❤ hello! ❤❤❤" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.crop(1, -1); x"# - ) - .unwrap(), - "" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.crop(4, 6); x"# - ) - .unwrap(), - "hello!" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.crop(1, 999); x"# - ) - .unwrap(), - "❤❤ hello! ❤❤❤" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x -= 'l'; x"# - ) - .unwrap(), - "❤❤❤ heo! ❤❤❤" - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x -= "\u2764\u2764"; x"# - ) - .unwrap(), - "❤ hello! ❤" - ); - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764')"# - ) - .unwrap(), - 0 - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764', 5)"# - ) - .unwrap(), - 11 - ); - - assert_eq!( - engine.eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764', -6)"# - ).unwrap(), - 11 - ); - - assert_eq!( - engine.eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764', 999)"# - ).unwrap(), - -1 - ); - - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('x')"# - ) - .unwrap(), - -1 - ); + assert_eq!(engine.eval::(r#"let x = "hello! \u2764\u2764\u2764"; x.sub_string(-2, 2)"#).unwrap(), "❤❤"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1, 5)"#).unwrap(), "❤❤ he"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1)"#).unwrap(), "❤❤ hello! ❤❤❤"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(99)"#).unwrap(), ""); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1, -1)"#).unwrap(), ""); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.sub_string(1, 999)"#).unwrap(), "❤❤ hello! ❤❤❤"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.crop(1, -1); x"#).unwrap(), ""); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.crop(4, 6); x"#).unwrap(), "hello!"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.crop(1, 999); x"#).unwrap(), "❤❤ hello! ❤❤❤"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x -= 'l'; x"#).unwrap(), "❤❤❤ heo! ❤❤❤"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x -= "\u2764\u2764"; x"#).unwrap(), "❤ hello! ❤"); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764')"#).unwrap(), 0); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764', 5)"#).unwrap(), 11); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764', -6)"#).unwrap(), 11); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('\u2764', 999)"#).unwrap(), -1); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.index_of('x')"#).unwrap(), -1); } #[cfg(not(feature = "no_object"))] @@ -324,29 +125,12 @@ fn test_string_format() { .register_type_with_name::("TestStruct") .register_fn("new_ts", || TestStruct { field: 42 }) .register_fn("to_string", |ts: TestStruct| format!("TS={}", ts.field)) - .register_fn("to_debug", |ts: TestStruct| { - format!("!!!TS={}!!!", ts.field) - }); + .register_fn("to_debug", |ts: TestStruct| format!("!!!TS={}!!!", ts.field)); - assert_eq!( - engine - .eval::(r#"let x = new_ts(); "foo" + x"#) - .unwrap(), - "fooTS=42" - ); - assert_eq!( - engine - .eval::(r#"let x = new_ts(); x + "foo""#) - .unwrap(), - "TS=42foo" - ); + assert_eq!(engine.eval::(r#"let x = new_ts(); "foo" + x"#).unwrap(), "fooTS=42"); + assert_eq!(engine.eval::(r#"let x = new_ts(); x + "foo""#).unwrap(), "TS=42foo"); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::(r#"let x = [new_ts()]; "foo" + x"#) - .unwrap(), - "foo[!!!TS=42!!!]" - ); + assert_eq!(engine.eval::(r#"let x = [new_ts()]; "foo" + x"#).unwrap(), "foo[!!!TS=42!!!]"); } #[test] @@ -357,19 +141,9 @@ fn test_string_fn() { #[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::(r#"let x="foo"; x[0].set_to_x(); x"#) - .unwrap(), - "Xoo" - ); + assert_eq!(engine.eval::(r#"let x="foo"; x[0].set_to_x(); x"#).unwrap(), "Xoo"); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::(r#"let x="foo"; set_to_x(x[0]); x"#) - .unwrap(), - "foo" - ); + assert_eq!(engine.eval::(r#"let x="foo"; set_to_x(x[0]); x"#).unwrap(), "foo"); engine .register_fn("foo1", |s: &str| s.len() as INT) @@ -389,22 +163,8 @@ fn test_string_fn() { fn test_string_split() { let engine = Engine::new(); - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.split(' ').len"# - ) - .unwrap(), - 3 - ); - assert_eq!( - engine - .eval::( - r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.split("hello").len"# - ) - .unwrap(), - 2 - ); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.split(' ').len"#).unwrap(), 3); + assert_eq!(engine.eval::(r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.split("hello").len"#).unwrap(), 2); } #[test] @@ -450,10 +210,7 @@ fn test_string_interpolated() { "hello 42 worlds!" ); - assert_eq!( - engine.eval::("`hello ${}world!`").unwrap(), - "hello world!" - ); + assert_eq!(engine.eval::("`hello ${}world!`").unwrap(), "hello world!"); assert_eq!( engine diff --git a/tests/switch.rs b/tests/switch.rs index 3f21b1c36..e9be2bb62 100644 --- a/tests/switch.rs +++ b/tests/switch.rs @@ -6,73 +6,18 @@ fn test_switch() { let mut scope = Scope::new(); scope.push("x", 42 as INT); - assert_eq!( - engine - .eval::("switch 2 { 1 => (), 2 => 'a', 42 => true }") - .unwrap(), - 'a' - ); - engine - .run("switch 3 { 1 => (), 2 => 'a', 42 => true }") - .unwrap(); - assert_eq!( - engine - .eval::("switch 3 { 1 => (), 2 => 'a', 42 => true, _ => 123 }") - .unwrap(), - 123 - ); - assert_eq!( - engine - .eval_with_scope::( - &mut scope, - "switch 2 { 1 => (), 2 if x < 40 => 'a', 42 => true, _ => 123 }" - ) - .unwrap(), - 123 - ); - assert_eq!( - engine - .eval_with_scope::( - &mut scope, - "switch 2 { 1 => (), 2 if x > 40 => 'a', 42 => true, _ => 123 }" - ) - .unwrap(), - 'a' - ); - assert!(engine - .eval_with_scope::(&mut scope, "switch x { 1 => (), 2 => 'a', 42 => true }") - .unwrap()); - assert!(engine - .eval_with_scope::(&mut scope, "switch x { 1 => (), 2 => 'a', _ => true }") - .unwrap()); - let _: () = engine - .eval_with_scope::<()>(&mut scope, "switch x { 1 => 123, 2 => 'a' }") - .unwrap(); + assert_eq!(engine.eval::("switch 2 { 1 => (), 2 => 'a', 42 => true }").unwrap(), 'a'); + engine.run("switch 3 { 1 => (), 2 => 'a', 42 => true }").unwrap(); + assert_eq!(engine.eval::("switch 3 { 1 => (), 2 => 'a', 42 => true, _ => 123 }").unwrap(), 123); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch 2 { 1 => (), 2 if x < 40 => 'a', 42 => true, _ => 123 }").unwrap(), 123); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch 2 { 1 => (), 2 if x > 40 => 'a', 42 => true, _ => 123 }").unwrap(), 'a'); + assert!(engine.eval_with_scope::(&mut scope, "switch x { 1 => (), 2 => 'a', 42 => true }").unwrap()); + assert!(engine.eval_with_scope::(&mut scope, "switch x { 1 => (), 2 => 'a', _ => true }").unwrap()); + let _: () = engine.eval_with_scope::<()>(&mut scope, "switch x { 1 => 123, 2 => 'a' }").unwrap(); - assert_eq!( - engine - .eval_with_scope::( - &mut scope, - "switch x { 1 | 2 | 3 | 5..50 | 'x' | true => 123, 'z' => 'a' }" - ) - .unwrap(), - 123 - ); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "switch x { 424242 => 123, _ => 42 }") - .unwrap(), - 42 - ); - assert_eq!( - engine - .eval_with_scope::( - &mut scope, - "switch x { 1 => 123, 42 => { x / 2 }, _ => 999 }" - ) - .unwrap(), - 21 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch x { 1 | 2 | 3 | 5..50 | 'x' | true => 123, 'z' => 'a' }").unwrap(), 123); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch x { 424242 => 123, _ => 42 }").unwrap(), 42); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch x { 1 => 123, 42 => { x / 2 }, _ => 999 }").unwrap(), 21); #[cfg(not(feature = "no_index"))] assert_eq!( engine @@ -112,32 +57,16 @@ fn test_switch() { 3 ); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "switch 42 { 42 => 123, 42 => 999 }") - .unwrap(), - 123 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch 42 { 42 => 123, 42 => 999 }").unwrap(), 123); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "switch x { 42 => 123, 42 => 999 }") - .unwrap(), - 123 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "switch x { 42 => 123, 42 => 999 }").unwrap(), 123); } #[test] fn test_switch_errors() { let engine = Engine::new(); - assert!(matches!( - engine - .compile("switch x { _ => 123, 1 => 42 }") - .unwrap_err() - .err_type(), - ParseErrorType::WrongSwitchDefaultCase - )); + assert!(matches!(engine.compile("switch x { _ => 123, 1 => 42 }").unwrap_err().err_type(), ParseErrorType::WrongSwitchDefaultCase)); } #[test] @@ -199,13 +128,7 @@ fn test_switch_condition() { 7 ); - assert!(matches!( - engine - .compile("switch x { 1 => 123, _ if true => 42 }") - .unwrap_err() - .err_type(), - ParseErrorType::WrongSwitchCaseCondition - )); + assert!(matches!(engine.compile("switch x { 1 => 123, _ if true => 42 }").unwrap_err().err_type(), ParseErrorType::WrongSwitchCaseCondition)); } #[cfg(not(feature = "no_index"))] @@ -226,9 +149,7 @@ mod test_switch_enum { match self { Self::Foo => vec!["Foo".into()] as Array, Self::Bar(num) => vec!["Bar".into(), (*num).into()] as Array, - Self::Baz(name, option) => { - vec!["Baz".into(), name.clone().into(), (*option).into()] as Array - } + Self::Baz(name, option) => vec!["Baz".into(), name.clone().into(), (*option).into()] as Array, } } } @@ -237,9 +158,7 @@ mod test_switch_enum { fn test_switch_enum() { let mut engine = Engine::new(); - engine - .register_type_with_name::("MyEnum") - .register_get("get_data", MyEnum::get_enum_data); + engine.register_type_with_name::("MyEnum").register_get("get_data", MyEnum::get_enum_data); let mut scope = Scope::new(); scope.push("x", MyEnum::Baz("hello".to_string(), true)); @@ -273,38 +192,35 @@ fn test_switch_ranges() { assert_eq!( engine - .eval_with_scope::( - &mut scope, - "switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 30..100 => true }" - ) + .eval_with_scope::(&mut scope, "switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 30..100 => true }") .unwrap(), 'a' ); assert_eq!( - engine.eval_with_scope::( - &mut scope, - "switch x { 10..20 => (), 20..=42 if x < 40 => 'a', 25..45 => 'z', 30..100 => true }" - ).unwrap(), + engine + .eval_with_scope::(&mut scope, "switch x { 10..20 => (), 20..=42 if x < 40 => 'a', 25..45 => 'z', 30..100 => true }") + .unwrap(), 'z' ); assert_eq!( - engine.eval_with_scope::( - &mut scope, - "switch x { 42 => 'x', 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 30..100 => true, 'w' => true }" - ).unwrap(), + engine + .eval_with_scope::(&mut scope, "switch x { 42 => 'x', 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 30..100 => true, 'w' => true }") + .unwrap(), 'x' ); assert!(matches!( - engine.compile( - "switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 42 => 'x', 30..100 => true }" - ).unwrap_err().err_type(), + engine + .compile("switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 42 => 'x', 30..100 => true }") + .unwrap_err() + .err_type(), ParseErrorType::WrongSwitchIntegerCase )); #[cfg(not(feature = "no_float"))] assert!(matches!( - engine.compile( - "switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 42.0 => 'x', 30..100 => true }" - ).unwrap_err().err_type(), + engine + .compile("switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 42.0 => 'x', 30..100 => true }") + .unwrap_err() + .err_type(), ParseErrorType::WrongSwitchIntegerCase )); assert_eq!( diff --git a/tests/throw.rs b/tests/throw.rs index 41001a770..1580eee51 100644 --- a/tests/throw.rs +++ b/tests/throw.rs @@ -19,27 +19,12 @@ fn test_throw() { fn test_try_catch() { let engine = Engine::new(); - assert_eq!( - engine - .eval::("try { throw 42; } catch (x) { return x; }") - .unwrap(), - 42 - ); + assert_eq!(engine.eval::("try { throw 42; } catch (x) { return x; }").unwrap(), 42); - assert_eq!( - engine - .eval::("try { throw 42; } catch { return 123; }") - .unwrap(), - 123 - ); + assert_eq!(engine.eval::("try { throw 42; } catch { return 123; }").unwrap(), 123); #[cfg(not(feature = "unchecked"))] - assert_eq!( - engine - .eval::("let x = 42; try { let y = 123; print(x/0); } catch { x = 0 } x") - .unwrap(), - 0 - ); + assert_eq!(engine.eval::("let x = 42; try { let y = 123; print(x/0); } catch { x = 0 } x").unwrap(), 0); #[cfg(not(feature = "no_function"))] assert_eq!( @@ -108,10 +93,5 @@ fn test_try_catch() { ); #[cfg(not(feature = "unchecked"))] - assert!(matches!( - *engine - .run("try { 42/0; } catch { throw; }") - .expect_err("expects error"), - EvalAltResult::ErrorArithmetic(..) - )); + assert!(matches!(*engine.run("try { 42/0; } catch { throw; }").expect_err("expects error"), EvalAltResult::ErrorArithmetic(..))); } diff --git a/tests/time.rs b/tests/time.rs index 723ef5c9a..c2269417b 100644 --- a/tests/time.rs +++ b/tests/time.rs @@ -11,10 +11,7 @@ use rhai::INT; fn test_timestamp() { let engine = Engine::new(); - assert_eq!( - engine.eval::("type_of(timestamp())").unwrap(), - "timestamp" - ); + assert_eq!(engine.eval::("type_of(timestamp())").unwrap(), "timestamp"); #[cfg(not(feature = "no_float"))] assert!( diff --git a/tests/tokens.rs b/tests/tokens.rs index 8d74ab1a3..5c74fb239 100644 --- a/tests/tokens.rs +++ b/tests/tokens.rs @@ -16,18 +16,9 @@ fn test_tokens_disabled() { engine.disable_symbol("+="); // disable the '+=' operator - assert_eq!( - *engine - .compile("let x = 40 + 2; x += 1;") - .unwrap_err() - .err_type(), - ParseErrorType::UnknownOperator("+=".to_string()) - ); + assert_eq!(*engine.compile("let x = 40 + 2; x += 1;").unwrap_err().err_type(), ParseErrorType::UnknownOperator("+=".to_string())); - assert!(matches!( - engine.compile("let x = += 0;").unwrap_err().err_type(), - ParseErrorType::Reserved(err) if err == "+=" - )); + assert!(matches!(engine.compile("let x = += 0;").unwrap_err().err_type(), ParseErrorType::Reserved(err) if err == "+=")); } #[cfg(not(feature = "no_custom_syntax"))] @@ -42,12 +33,7 @@ fn test_tokens_custom_operator_identifiers() { // Register a binary function named `foo` engine.register_fn("foo", |x: INT, y: INT| (x * y) - (x + y)); - assert_eq!( - engine - .eval_expression::("1 + 2 * 3 foo 4 - 5 / 6") - .unwrap(), - 15 - ); + assert_eq!(engine.eval_expression::("1 + 2 * 3 foo 4 - 5 / 6").unwrap(), 15); #[cfg(not(feature = "no_function"))] assert_eq!( @@ -75,24 +61,14 @@ fn test_tokens_custom_operator_symbol() { // Register a binary function named `#` engine.register_fn("#", |x: INT, y: INT| (x * y) - (x + y)); - assert_eq!( - engine - .eval_expression::("1 + 2 * 3 # 4 - 5 / 6") - .unwrap(), - 15 - ); + assert_eq!(engine.eval_expression::("1 + 2 * 3 # 4 - 5 / 6").unwrap(), 15); // Register a custom operator named `=>` assert!(engine.register_custom_operator("=>", 160).is_err()); engine.disable_symbol("=>"); engine.register_custom_operator("=>", 160).unwrap(); engine.register_fn("=>", |x: INT, y: INT| (x * y) - (x + y)); - assert_eq!( - engine - .eval_expression::("1 + 2 * 3 => 4 - 5 / 6") - .unwrap(), - 15 - ); + assert_eq!(engine.eval_expression::("1 + 2 * 3 => 4 - 5 / 6").unwrap(), 15); } #[test] diff --git a/tests/types.rs b/tests/types.rs index 03c68fe78..820f2eb19 100644 --- a/tests/types.rs +++ b/tests/types.rs @@ -17,58 +17,33 @@ fn test_type_of() { assert_eq!(engine.eval::("type_of(60 + 5)").unwrap(), "i32"); #[cfg(not(feature = "no_float"))] - { - #[cfg(not(feature = "f32_float"))] - assert_eq!(engine.eval::("type_of(1.0 + 2.0)").unwrap(), "f64"); + #[cfg(not(feature = "f32_float"))] + assert_eq!(engine.eval::("type_of(1.0 + 2.0)").unwrap(), "f64"); - #[cfg(feature = "f32_float")] - assert_eq!(engine.eval::("type_of(1.0 + 2.0)").unwrap(), "f32"); - } + #[cfg(not(feature = "no_float"))] + #[cfg(feature = "f32_float")] + assert_eq!(engine.eval::("type_of(1.0 + 2.0)").unwrap(), "f32"); #[cfg(not(feature = "no_index"))] - assert_eq!( - engine - .eval::(r#"type_of([true, 2, "hello"])"#) - .unwrap(), - "array" - ); + assert_eq!(engine.eval::(r#"type_of([true, 2, "hello"])"#).unwrap(), "array"); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine - .eval::(r#"type_of(#{a:true, "":2, "z":"hello"})"#) - .unwrap(), - "map" - ); + assert_eq!(engine.eval::(r#"type_of(#{a:true, "":2, "z":"hello"})"#).unwrap(), "map"); #[cfg(not(feature = "no_object"))] { - engine.register_type_with_name::("Hello"); - engine.register_fn("new_ts", || TestStruct { x: 1 }); - + engine.register_type_with_name::("Hello").register_fn("new_ts", || TestStruct { x: 1 }); assert_eq!(engine.eval::("type_of(new_ts())").unwrap(), "Hello"); } - assert_eq!( - engine.eval::(r#"type_of("hello")"#).unwrap(), - "string" - ); + assert_eq!(engine.eval::(r#"type_of("hello")"#).unwrap(), "string"); #[cfg(not(feature = "no_object"))] - assert_eq!( - engine.eval::(r#""hello".type_of()"#).unwrap(), - "string" - ); + assert_eq!(engine.eval::(r#""hello".type_of()"#).unwrap(), "string"); #[cfg(not(feature = "only_i32"))] - assert_eq!( - engine.eval::("let x = 123; type_of(x)").unwrap(), - "i64" - ); + assert_eq!(engine.eval::("let x = 123; type_of(x)").unwrap(), "i64"); #[cfg(feature = "only_i32")] - assert_eq!( - engine.eval::("let x = 123; type_of(x)").unwrap(), - "i32" - ); + assert_eq!(engine.eval::("let x = 123; type_of(x)").unwrap(), "i32"); } diff --git a/tests/unit.rs b/tests/unit.rs index 6536d9905..aafb64243 100644 --- a/tests/unit.rs +++ b/tests/unit.rs @@ -9,9 +9,7 @@ fn test_unit() { #[test] fn test_unit_eq() { let engine = Engine::new(); - assert!(engine - .eval::("let x = (); let y = (); x == y") - .unwrap()); + assert!(engine.eval::("let x = (); let y = (); x == y").unwrap()); } #[test] diff --git a/tests/var_scope.rs b/tests/var_scope.rs index 2a0232eb7..e798e2438 100644 --- a/tests/var_scope.rs +++ b/tests/var_scope.rs @@ -7,9 +7,7 @@ fn test_var_scope() { engine.run_with_scope(&mut scope, "let x = 4 + 5").unwrap(); assert_eq!(engine.eval_with_scope::(&mut scope, "x").unwrap(), 9); - engine - .run_with_scope(&mut scope, "x += 1; x += 2;") - .unwrap(); + engine.run_with_scope(&mut scope, "x += 1; x += 2;").unwrap(); assert_eq!(engine.eval_with_scope::(&mut scope, "x").unwrap(), 12); scope.set_value("x", 42 as INT); @@ -18,68 +16,44 @@ fn test_var_scope() { engine.run_with_scope(&mut scope, "{ let x = 3 }").unwrap(); assert_eq!(engine.eval_with_scope::(&mut scope, "x").unwrap(), 42); - #[cfg(not(feature = "no_optimize"))] - if engine.optimization_level() != rhai::OptimizationLevel::None { - scope.clear(); - engine - .run_with_scope(&mut scope, "let x = 3; let x = 42; let x = 123;") - .unwrap(); - assert_eq!(scope.len(), 1); - assert_eq!(scope.get_value::("x").unwrap(), 123); + scope.clear(); + engine.run_with_scope(&mut scope, "let x = 3; let x = 42; let x = 123;").unwrap(); + assert_eq!(scope.len(), 1); + assert_eq!(scope.get_value::("x").unwrap(), 123); - scope.clear(); - engine - .run_with_scope( - &mut scope, - "let x = 3; let y = 0; let x = 42; let y = 999; let x = 123;", - ) - .unwrap(); - assert_eq!(scope.len(), 2); - assert_eq!(scope.get_value::("x").unwrap(), 123); - assert_eq!(scope.get_value::("y").unwrap(), 999); + scope.clear(); + engine.run_with_scope(&mut scope, "let x = 3; let y = 0; let x = 42; let y = 999; let x = 123;").unwrap(); + assert_eq!(scope.len(), 2); + assert_eq!(scope.get_value::("x").unwrap(), 123); + assert_eq!(scope.get_value::("y").unwrap(), 999); - scope.clear(); - engine - .run_with_scope( - &mut scope, - "const x = 3; let y = 0; let x = 42; let y = 999;", - ) - .unwrap(); - assert_eq!(scope.len(), 2); - assert_eq!(scope.get_value::("x").unwrap(), 42); - assert_eq!(scope.get_value::("y").unwrap(), 999); - assert!(!scope.is_constant("x").unwrap()); - assert!(!scope.is_constant("y").unwrap()); - - scope.clear(); - engine - .run_with_scope( - &mut scope, - "const x = 3; let y = 0; let x = 42; let y = 999; const x = 123;", - ) - .unwrap(); - assert_eq!(scope.len(), 2); - assert_eq!(scope.get_value::("x").unwrap(), 123); - assert_eq!(scope.get_value::("y").unwrap(), 999); - assert!(scope.is_constant("x").unwrap()); - assert!(!scope.is_constant("y").unwrap()); - - scope.clear(); - engine - .run_with_scope( - &mut scope, - "let x = 3; let y = 0; { let x = 42; let y = 999; } let x = 123;", - ) - .unwrap(); + scope.clear(); + engine.run_with_scope(&mut scope, "const x = 3; let y = 0; let x = 42; let y = 999;").unwrap(); + assert_eq!(scope.len(), 2); + assert_eq!(scope.get_value::("x").unwrap(), 42); + assert_eq!(scope.get_value::("y").unwrap(), 999); + assert!(!scope.is_constant("x").unwrap()); + assert!(!scope.is_constant("y").unwrap()); - assert_eq!(scope.len(), 2); - assert_eq!(scope.get_value::("x").unwrap(), 123); - assert_eq!(scope.get_value::("y").unwrap(), 0); + scope.clear(); + engine.run_with_scope(&mut scope, "const x = 3; let y = 0; let x = 42; let y = 999; const x = 123;").unwrap(); + assert_eq!(scope.len(), 2); + assert_eq!(scope.get_value::("x").unwrap(), 123); + assert_eq!(scope.get_value::("y").unwrap(), 999); + assert!(scope.is_constant("x").unwrap()); + assert!(!scope.is_constant("y").unwrap()); + + scope.clear(); + engine.run_with_scope(&mut scope, "let x = 3; let y = 0; { let x = 42; let y = 999; } let x = 123;").unwrap(); + + assert_eq!(scope.len(), 2); + assert_eq!(scope.get_value::("x").unwrap(), 123); + assert_eq!(scope.get_value::("y").unwrap(), 0); - assert_eq!( - engine - .eval::( - " + assert_eq!( + engine + .eval::( + " let sum = 0; for x in 0..10 { let x = 42; @@ -87,11 +61,10 @@ fn test_var_scope() { } sum ", - ) - .unwrap(), - 420 - ); - } + ) + .unwrap(), + 420 + ); scope.clear(); @@ -339,9 +312,7 @@ fn test_scope_eval() { scope.push("z", 999 as INT); // First invocation - engine - .run_with_scope(&mut scope, " let x = 4 + 5 - y + z; y = 1;") - .expect("variables y and z should exist"); + engine.run_with_scope(&mut scope, " let x = 4 + 5 - y + z; y = 1;").expect("variables y and z should exist"); // Second invocation using the same state let result = engine.eval_with_scope::(&mut scope, "x").unwrap(); @@ -349,12 +320,7 @@ fn test_scope_eval() { println!("result: {result}"); // should print 966 // Variable y is changed in the script - assert_eq!( - scope - .get_value::("y") - .expect("variable y should exist"), - 1 - ); + assert_eq!(scope.get_value::("y").expect("variable y should exist"), 1); } #[test] @@ -378,28 +344,19 @@ fn test_var_resolver() { #[cfg(not(feature = "no_closure"))] "HELLO" => Ok(Some(shared.clone())), // Override a variable - make it not found even if it exists! - "DO_NOT_USE" => { - Err(EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE).into()) - } + "DO_NOT_USE" => Err(EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE).into()), // Silently maps 'chameleon' into 'innocent'. "chameleon" => context .scope() .get_value("innocent") .map(Some) - .ok_or_else(|| { - EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE).into() - }), + .ok_or_else(|| EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE).into()), // Return Ok(None) to continue with the normal variable resolution process. _ => Ok(None), } }); - assert_eq!( - engine - .eval_with_scope::(&mut scope, "MYSTIC_NUMBER") - .unwrap(), - 42 - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "MYSTIC_NUMBER").unwrap(), 42); #[cfg(not(feature = "no_closure"))] { @@ -413,16 +370,10 @@ fn test_var_resolver() { assert_eq!(base.as_int().unwrap(), 248); } - assert_eq!( - engine - .eval_with_scope::(&mut scope, "chameleon") - .unwrap(), - 1 - ); - assert!( - matches!(*engine.eval_with_scope::(&mut scope, "DO_NOT_USE").unwrap_err(), - EvalAltResult::ErrorVariableNotFound(n, ..) if n == "DO_NOT_USE") - ); + assert_eq!(engine.eval_with_scope::(&mut scope, "chameleon").unwrap(), 1); + assert!(matches!( + *engine.eval_with_scope::(&mut scope, "DO_NOT_USE").unwrap_err(), + EvalAltResult::ErrorVariableNotFound(n, ..) if n == "DO_NOT_USE")); } #[test] @@ -438,25 +389,11 @@ fn test_var_def_filter() { _ => Ok(true), }); - assert_eq!( - engine - .eval::("let y = 42; let y = 123; let z = y + 1; z") - .unwrap(), - 124 - ); - - assert!(matches!( - engine.compile("let x = 42;").unwrap_err().err_type(), - ParseErrorType::ForbiddenVariable(s) if s == "x" - )); - assert!(matches!( - *engine.run_ast(&ast).expect_err("should err"), - EvalAltResult::ErrorForbiddenVariable(s, _) if s == "x" - )); + assert_eq!(engine.eval::("let y = 42; let y = 123; let z = y + 1; z").unwrap(), 124); + assert!(matches!(engine.compile("let x = 42;").unwrap_err().err_type(), ParseErrorType::ForbiddenVariable(s) if s == "x")); + assert!(matches!(*engine.run_ast(&ast).expect_err("should err"), EvalAltResult::ErrorForbiddenVariable(s, _) if s == "x")); assert!(engine.run("const x = 42;").is_err()); assert!(engine.run("let y = 42; { let x = y + 1; }").is_err()); assert!(engine.run("let y = 42; { let x = y + 1; }").is_err()); - engine - .run("let y = 42; { let z = y + 1; { let x = z + 1; } }") - .unwrap(); + engine.run("let y = 42; { let z = y + 1; { let x = z + 1; } }").unwrap(); } diff --git a/tests/while_loop.rs b/tests/while_loop.rs index 03df285ad..301ade660 100644 --- a/tests/while_loop.rs +++ b/tests/while_loop.rs @@ -86,10 +86,7 @@ fn test_do() { engine.run("do {} while false").unwrap(); - assert_eq!( - engine.eval::("do { break 42; } while false").unwrap(), - 42 - ); + assert_eq!(engine.eval::("do { break 42; } while false").unwrap(), 42); } #[cfg(not(feature = "unchecked"))]