From d1a97be9e305061117425d40ce4beb307a96f993 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Thu, 10 Feb 2022 12:33:48 +0800 Subject: [PATCH] New syntax for package definition. --- CHANGELOG.md | 2 ++ src/packages/arithmetic.rs | 2 +- src/packages/array_basic.rs | 2 +- src/packages/bit_field.rs | 2 +- src/packages/blob_basic.rs | 2 +- src/packages/debugging.rs | 2 +- src/packages/fn_basic.rs | 2 +- src/packages/iter_basic.rs | 2 +- src/packages/lang_core.rs | 2 +- src/packages/logic.rs | 2 +- src/packages/map_basic.rs | 2 +- src/packages/math_basic.rs | 2 +- src/packages/mod.rs | 48 +++++++++++++++++++++++++++++++----- src/packages/pkg_core.rs | 2 +- src/packages/pkg_std.rs | 2 +- src/packages/string_basic.rs | 2 +- src/packages/string_more.rs | 2 +- src/packages/time_basic.rs | 2 +- 18 files changed, 60 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5d2e8ca..2e89aa93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ New features * `Engine::set_fail_on_invalid_map_property` is added to control whether to raise an error (new `EvalAltResult::ErrorPropertyNotFound`) when invalid properties are accessed on object maps. * `Engine::set_allow_shadowing` is added to allow/disallow variables _shadowing_, with new errors `EvalAltResult::ErrorVariableExists` and `ParseErrorType::VariableExists`. * `Engine::on_def_var` allows registering a closure which can decide whether a variable definition is allow to continue, or should fail with an error. +* A new syntax for defining custom packages is introduced that removes the need to specify the Rhai crate name (internally uses the `$crate` meta variable). Enhancements ------------ @@ -50,6 +51,7 @@ Enhancements * `Expr::start_position` is added to give the beginning of the expression (not the operator's position). * `StmtBlock` and `Stmt::Block` now keep the position of the closing `}` as well. * `EvalAltResult::unwrap_inner` is added to access the base error inside multiple layers of wrappings (e.g. `EvalAltResult::ErrorInFunction`). +* Yet another new syntax is introduced for `def_package!` that further simplifies the old syntax. REPL tool changes ----------------- diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index 8eae8764..883b29e3 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -190,7 +190,7 @@ macro_rules! reg_functions { def_package! { /// Basic arithmetic package. - crate::ArithmeticPackage => |lib| { + pub ArithmeticPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "int", int_functions); diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 9d7d67b7..c7556865 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -13,7 +13,7 @@ use std::{any::TypeId, cmp::Ordering, mem}; def_package! { /// Package of basic array utilities. - crate::BasicArrayPackage => |lib| { + pub BasicArrayPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "array", array_functions); diff --git a/src/packages/bit_field.rs b/src/packages/bit_field.rs index ee4e37f2..55b4ad40 100644 --- a/src/packages/bit_field.rs +++ b/src/packages/bit_field.rs @@ -8,7 +8,7 @@ use std::prelude::v1::*; def_package! { /// Package of basic bit-field utilities. - crate::BitFieldPackage => |lib| { + pub BitFieldPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "bit_field", bit_field_functions); diff --git a/src/packages/blob_basic.rs b/src/packages/blob_basic.rs index c88dfb16..5f27bb8d 100644 --- a/src/packages/blob_basic.rs +++ b/src/packages/blob_basic.rs @@ -20,7 +20,7 @@ const FLOAT_BYTES: usize = mem::size_of::(); def_package! { /// Package of basic BLOB utilities. - crate::BasicBlobPackage => |lib| { + pub BasicBlobPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "blob", blob_functions); diff --git a/src/packages/debugging.rs b/src/packages/debugging.rs index a476604c..e48571a8 100644 --- a/src/packages/debugging.rs +++ b/src/packages/debugging.rs @@ -16,7 +16,7 @@ use crate::Map; def_package! { /// Package of basic debugging utilities. - crate::DebuggingPackage => |lib| { + pub DebuggingPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "debugging", debugging_functions); diff --git a/src/packages/fn_basic.rs b/src/packages/fn_basic.rs index 48aeb3d8..505a08b5 100644 --- a/src/packages/fn_basic.rs +++ b/src/packages/fn_basic.rs @@ -5,7 +5,7 @@ use std::prelude::v1::*; def_package! { /// Package of basic function pointer utilities. - crate::BasicFnPackage => |lib| { + pub BasicFnPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions); diff --git a/src/packages/iter_basic.rs b/src/packages/iter_basic.rs index 78ee4519..bcf50691 100644 --- a/src/packages/iter_basic.rs +++ b/src/packages/iter_basic.rs @@ -299,7 +299,7 @@ macro_rules! reg_range { def_package! { /// Package of basic range iterators - crate::BasicIteratorPackage => |lib| { + pub BasicIteratorPackage(lib) { lib.standard = true; reg_range!(lib | "range" => INT); diff --git a/src/packages/lang_core.rs b/src/packages/lang_core.rs index 5e7c5949..ce28bf37 100644 --- a/src/packages/lang_core.rs +++ b/src/packages/lang_core.rs @@ -7,7 +7,7 @@ use std::prelude::v1::*; def_package! { /// Package of core language features. - crate::LanguageCorePackage => |lib| { + pub LanguageCorePackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "core", core_functions); diff --git a/src/packages/logic.rs b/src/packages/logic.rs index 26821a55..af494f00 100644 --- a/src/packages/logic.rs +++ b/src/packages/logic.rs @@ -37,7 +37,7 @@ macro_rules! reg_functions { def_package! { /// Package of basic logic operators. - crate::LogicPackage => |lib| { + pub LogicPackage(lib) { lib.standard = true; #[cfg(not(feature = "only_i32"))] diff --git a/src/packages/map_basic.rs b/src/packages/map_basic.rs index 8eaf6b17..a3b0931f 100644 --- a/src/packages/map_basic.rs +++ b/src/packages/map_basic.rs @@ -11,7 +11,7 @@ use crate::Array; def_package! { /// Package of basic object map utilities. - crate::BasicMapPackage => |lib| { + pub BasicMapPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "map", map_functions); diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index 6dd8f630..45fd3790 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -53,7 +53,7 @@ macro_rules! reg_functions { def_package! { /// Basic mathematical package. - crate::BasicMathPackage => |lib| { + pub BasicMathPackage(lib) { lib.standard = true; // Integer functions diff --git a/src/packages/mod.rs b/src/packages/mod.rs index f56fafe9..343dd651 100644 --- a/src/packages/mod.rs +++ b/src/packages/mod.rs @@ -67,16 +67,52 @@ pub trait Package { /// /// fn add(x: i64, y: i64) -> Result> { Ok(x + y) } /// -/// def_package!(rhai:MyPackage:"My super-duper package", module, -/// { -/// // Load a binary function with all value parameters. -/// module.set_native_fn("my_add", add); -/// }); +/// def_package! { +/// /// My super-duper package. +/// pub MyPackage(module) { +/// // Load a binary function with all value parameters. +/// module.set_native_fn("my_add", add); +/// } +/// } /// ``` #[macro_export] macro_rules! def_package { + ($($(#[$outer:meta])* $mod:vis $package:ident($lib:ident) $block:block)+) => { $( + $(#[$outer])* + $mod struct $package($crate::Shared<$crate::Module>); + + impl $crate::packages::Package for $package { + fn as_shared_module(&self) -> $crate::Shared<$crate::Module> { + self.0.clone() + } + fn init($lib: &mut $crate::Module) { + $block + } + } + + impl Default for $package { + fn default() -> Self { + Self::new() + } + } + + impl $package { + pub fn new() -> Self { + let mut module = $crate::Module::new(); + ::init(&mut module); + module.build_index(); + Self(module.into()) + } + } + )* }; ($($(#[$outer:meta])* $root:ident :: $package:ident => | $lib:ident | $block:block)+) => { $( $(#[$outer])* + /// # Deprecated + /// + /// This old syntax of `def_package!` is deprecated. Use the new syntax instead. + /// + /// This syntax will be removed in the next major version. + #[deprecated(since = "1.5.0", note = "this is an old syntax of `def_package!` and is deprecated; use the new syntax of `def_package!` instead")] pub struct $package($root::Shared<$root::Module>); impl $root::packages::Package for $package { @@ -104,7 +140,6 @@ macro_rules! def_package { } )* }; ($root:ident : $package:ident : $comment:expr , $lib:ident , $block:stmt) => { - #[deprecated(since = "1.4.0", note = "this is an old syntax of `def_package!` and is deprecated; use the new syntax of `def_package!` instead")] #[doc=$comment] /// /// # Deprecated @@ -112,6 +147,7 @@ macro_rules! def_package { /// This old syntax of `def_package!` is deprecated. Use the new syntax instead. /// /// This syntax will be removed in the next major version. + #[deprecated(since = "1.4.0", note = "this is an old syntax of `def_package!` and is deprecated; use the new syntax of `def_package!` instead")] pub struct $package($root::Shared<$root::Module>); impl $root::packages::Package for $package { diff --git a/src/packages/pkg_core.rs b/src/packages/pkg_core.rs index 94d59c7f..1603bcb8 100644 --- a/src/packages/pkg_core.rs +++ b/src/packages/pkg_core.rs @@ -14,7 +14,7 @@ def_package! { /// * [`BasicIteratorPackage`][super::BasicIteratorPackage] /// * [`BasicFnPackage`][super::BasicFnPackage] /// * [`DebuggingPackage`][super::DebuggingPackage] - crate::CorePackage => |lib| { + pub CorePackage(lib) { lib.standard = true; super::LanguageCorePackage::init(lib); diff --git a/src/packages/pkg_std.rs b/src/packages/pkg_std.rs index b388b379..cd8f29db 100644 --- a/src/packages/pkg_std.rs +++ b/src/packages/pkg_std.rs @@ -17,7 +17,7 @@ def_package! { /// * [`BasicMapPackage`][super::BasicMapPackage] /// * [`BasicTimePackage`][super::BasicTimePackage] /// * [`MoreStringPackage`][super::MoreStringPackage] - crate::StandardPackage => |lib| { + pub StandardPackage(lib) { lib.standard = true; super::CorePackage::init(lib); diff --git a/src/packages/string_basic.rs b/src/packages/string_basic.rs index 266ccec3..7be2809a 100644 --- a/src/packages/string_basic.rs +++ b/src/packages/string_basic.rs @@ -15,7 +15,7 @@ pub const FUNC_TO_DEBUG: &str = "to_debug"; def_package! { /// Package of basic string utilities (e.g. printing) - crate::BasicStringPackage => |lib| { + pub BasicStringPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "print_debug", print_debug_functions); diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index f51b27d8..90fc5fb9 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -8,7 +8,7 @@ use super::string_basic::{print_with_func, FUNC_TO_STRING}; def_package! { /// Package of additional string utilities over [`BasicStringPackage`][super::BasicStringPackage] - crate::MoreStringPackage => |lib| { + pub MoreStringPackage(lib) { lib.standard = true; combine_with_exported_module!(lib, "string", string_functions); diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 3eacee0b..b631a59d 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -15,7 +15,7 @@ use instant::{Duration, Instant}; def_package! { /// Package of basic timing utilities. - crate::BasicTimePackage => |lib| { + pub BasicTimePackage(lib) { lib.standard = true; // Register date/time functions