Refine docs and comments etc.

This commit is contained in:
Stephen Chung 2021-01-02 23:30:10 +08:00
parent 5a3bbaa322
commit ef48f47b74
22 changed files with 352 additions and 296 deletions

View File

@ -149,14 +149,18 @@ change(); // <- error: `this` is unbound
`is_def_fn` `is_def_fn`
----------- -----------
Use `is_def_fn` to detect if a Rhai function is defined (and therefore callable), based on its name Use `is_def_fn` to detect if a Rhai function is defined (and therefore callable),
and the number of parameters. based on its name and the number of parameters.
```rust ```rust
fn foo(x) { x + 1 } fn foo(x) { x + 1 }
is_def_fn("foo", 1) == true; is_def_fn("foo", 1) == true;
is_def_fn("foo", 0) == false;
is_def_fn("foo", 2) == false;
is_def_fn("bar", 1) == false; is_def_fn("bar", 1) == false;
``` ```

View File

@ -62,7 +62,7 @@ impl FnAccess {
/// _(INTERNALS)_ A type containing information on a scripted function. /// _(INTERNALS)_ A type containing information on a scripted function.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -271,6 +271,8 @@ impl AST {
/// No statements are cloned. /// No statements are cloned.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
///
/// Not available under [`no_function`].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub fn clone_functions_only(&self) -> Self { pub fn clone_functions_only(&self) -> Self {
@ -280,6 +282,8 @@ impl AST {
/// No statements are cloned. /// No statements are cloned.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
///
/// Not available under [`no_function`].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub fn clone_functions_only_filtered( pub fn clone_functions_only_filtered(
@ -564,6 +568,8 @@ impl AST {
} }
/// Filter out the functions, retaining only some based on a filter predicate. /// Filter out the functions, retaining only some based on a filter predicate.
/// ///
/// Not available under [`no_function`].
///
/// # Example /// # Example
/// ///
/// ``` /// ```
@ -597,6 +603,8 @@ impl AST {
self self
} }
/// Iterate through all function definitions. /// Iterate through all function definitions.
///
/// Not available under [`no_function`].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub fn iter_functions<'a>(&'a self) -> impl Iterator<Item = ScriptFnMetadata> + 'a { pub fn iter_functions<'a>(&'a self) -> impl Iterator<Item = ScriptFnMetadata> + 'a {
@ -605,6 +613,8 @@ impl AST {
.map(|(_, _, _, _, fn_def)| fn_def.into()) .map(|(_, _, _, _, fn_def)| fn_def.into())
} }
/// Clear all function definitions in the [`AST`]. /// Clear all function definitions in the [`AST`].
///
/// Not available under [`no_function`].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub fn clear_functions(&mut self) { pub fn clear_functions(&mut self) {
@ -650,7 +660,7 @@ impl AsRef<Module> for AST {
/// _(INTERNALS)_ An identifier containing an [immutable string][ImmutableString] name and a [position][Position]. /// _(INTERNALS)_ An identifier containing an [immutable string][ImmutableString] name and a [position][Position].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Clone, Eq, PartialEq, Hash)] #[derive(Clone, Eq, PartialEq, Hash)]
@ -671,7 +681,7 @@ impl fmt::Debug for Ident {
/// _(INTERNALS)_ A type encapsulating the mode of a `return`/`throw` statement. /// _(INTERNALS)_ A type encapsulating the mode of a `return`/`throw` statement.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)] #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
@ -685,7 +695,7 @@ pub enum ReturnType {
/// _(INTERNALS)_ A statement. /// _(INTERNALS)_ A statement.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -882,7 +892,7 @@ impl Stmt {
/// _(INTERNALS)_ A custom syntax definition. /// _(INTERNALS)_ A custom syntax definition.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Clone)] #[derive(Clone)]
@ -909,7 +919,7 @@ impl fmt::Debug for CustomExpr {
/// _(INTERNALS)_ A binary expression. /// _(INTERNALS)_ A binary expression.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -923,7 +933,7 @@ pub struct BinaryExpr {
/// _(INTERNALS)_ A function call. /// _(INTERNALS)_ A function call.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -948,7 +958,7 @@ pub struct FnCallExpr {
/// _(INTERNALS)_ An expression sub-tree. /// _(INTERNALS)_ An expression sub-tree.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -1028,7 +1038,7 @@ impl Expr {
AccessMode::ReadOnly, AccessMode::ReadOnly,
)), )),
Self::BoolConstant(x, _) => (*x).into(), Self::BoolConstant(x, _) => (*x).into(),
Self::Unit(_) => ().into(), Self::Unit(_) => Dynamic::UNIT,
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Self::Array(x, _) if self.is_constant() => { Self::Array(x, _) if self.is_constant() => {

View File

@ -9,7 +9,7 @@ use crate::stdlib::{
hash::{Hash, Hasher}, hash::{Hash, Hasher},
mem, mem,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
string::{String, ToString}, string::String,
}; };
use crate::{FnPtr, ImmutableString, INT}; use crate::{FnPtr, ImmutableString, INT};
@ -132,7 +132,7 @@ pub enum AccessMode {
} }
impl AccessMode { impl AccessMode {
/// Is the access type [`ReadOnly`]? /// Is the access type `ReadOnly`?
#[inline(always)] #[inline(always)]
pub fn is_read_only(self) -> bool { pub fn is_read_only(self) -> bool {
match self { match self {
@ -183,7 +183,7 @@ enum DynamicReadLockInner<'d, T: Variant + Clone> {
/// A simple reference to a non-shared value. /// A simple reference to a non-shared value.
Reference(&'d T), Reference(&'d T),
/// A read guard to a shared `RefCell`. /// A read guard to a shared [`RefCell`][std::cell::RefCell].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
Guard(crate::stdlib::cell::Ref<'d, Dynamic>), Guard(crate::stdlib::cell::Ref<'d, Dynamic>),
@ -220,7 +220,7 @@ enum DynamicWriteLockInner<'d, T: Variant + Clone> {
/// A simple mutable reference to a non-shared value. /// A simple mutable reference to a non-shared value.
Reference(&'d mut T), Reference(&'d mut T),
/// A write guard to a shared `RefCell`. /// A write guard to a shared [`RefCell`][std::cell::RefCell].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
Guard(crate::stdlib::cell::RefMut<'d, Dynamic>), Guard(crate::stdlib::cell::RefMut<'d, Dynamic>),
@ -258,7 +258,7 @@ impl<'d, T: Variant + Clone> DerefMut for DynamicWriteLock<'d, T> {
impl Dynamic { impl Dynamic {
/// Does this [`Dynamic`] hold a variant data type /// Does this [`Dynamic`] hold a variant data type
/// instead of one of the support system primitive types? /// instead of one of the supported system primitive types?
#[inline(always)] #[inline(always)]
pub fn is_variant(&self) -> bool { pub fn is_variant(&self) -> bool {
match self.0 { match self.0 {
@ -266,8 +266,7 @@ impl Dynamic {
_ => false, _ => false,
} }
} }
/// Does this [`Dynamic`] hold a shared data type /// Is the value held by this [`Dynamic`] shared?
/// instead of one of the supported system primitive types?
#[inline(always)] #[inline(always)]
pub fn is_shared(&self) -> bool { pub fn is_shared(&self) -> bool {
match self.0 { match self.0 {
@ -279,7 +278,7 @@ impl Dynamic {
/// Is the value held by this [`Dynamic`] a particular type? /// Is the value held by this [`Dynamic`] a particular type?
/// ///
/// If the [`Dynamic`] is a shared variant checking is performed on /// If the [`Dynamic`] is a shared variant checking is performed on
/// top of it's internal value. /// top of its internal value.
#[inline(always)] #[inline(always)]
pub fn is<T: Variant + Clone>(&self) -> bool { pub fn is<T: Variant + Clone>(&self) -> bool {
let mut target_type_id = TypeId::of::<T>(); let mut target_type_id = TypeId::of::<T>();
@ -508,7 +507,7 @@ impl fmt::Debug for Dynamic {
impl Clone for Dynamic { impl Clone for Dynamic {
/// Clone the [`Dynamic`] value. /// Clone the [`Dynamic`] value.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// The cloned copy is marked read-write even if the original is read-only. /// The cloned copy is marked read-write even if the original is read-only.
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -618,7 +617,7 @@ impl Dynamic {
/// ///
/// Constant [`Dynamic`] values are read-only. If a [`&mut Dynamic`][Dynamic] to such a constant /// Constant [`Dynamic`] values are read-only. If a [`&mut Dynamic`][Dynamic] to such a constant
/// is passed to a Rust function, the function can use this information to return an error of /// is passed to a Rust function, the function can use this information to return an error of
/// [`EvalAltResult::ErrorAssignmentToConstant`][crate::EvalAltResult::ErrorAssignmentToConstant] /// [`ErrorAssignmentToConstant`][crate::EvalAltResult::ErrorAssignmentToConstant]
/// if its value is going to be modified. This safe-guards constant values from being modified /// if its value is going to be modified. This safe-guards constant values from being modified
/// from within Rust functions. /// from within Rust functions.
pub fn is_read_only(&self) -> bool { pub fn is_read_only(&self) -> bool {
@ -707,7 +706,7 @@ impl Dynamic {
if TypeId::of::<T>() == TypeId::of::<&str>() { if TypeId::of::<T>() == TypeId::of::<&str>() {
return <dyn Any>::downcast_ref::<&str>(&value) return <dyn Any>::downcast_ref::<&str>(&value)
.unwrap() .unwrap()
.to_string() .deref()
.into(); .into();
} }
if TypeId::of::<T>() == TypeId::of::<()>() { if TypeId::of::<T>() == TypeId::of::<()>() {

View File

@ -45,13 +45,13 @@ pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical
/// _(INTERNALS)_ A stack of imported [modules][Module]. /// _(INTERNALS)_ A stack of imported [modules][Module].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
// //
// # Implementation Notes // # Implementation Notes
// //
// We cannot use &str or Cow<str> here because `eval` may load a [module][Module] and // We cannot use Cow<str> here because `eval` may load a [module][Module] and
// the module name will live beyond the AST of the eval script text. // the module name will live beyond the AST of the eval script text.
// The best we can do is a shared reference. // The best we can do is a shared reference.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -214,55 +214,62 @@ pub const FN_ANONYMOUS: &str = "anon$";
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
pub const OP_EQUALS: &str = "=="; pub const OP_EQUALS: &str = "==";
/// A type specifying the method of chaining. /// Method of chaining.
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum ChainType { pub enum ChainType {
None, /// Not a chaining type.
NonChaining,
/// Indexing.
Index, Index,
/// Dotting.
Dot, Dot,
} }
/// Value of a chaining argument.
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
#[derive(Debug, Clone)] #[derive(Debug, Clone, Hash)]
pub enum IndexChainValue { pub enum ChainArgument {
None, /// Dot-property access.
Property,
/// Arguments to a dot-function call.
FnCallArgs(StaticVec<Dynamic>), FnCallArgs(StaticVec<Dynamic>),
Value(Dynamic), /// Index value.
IndexValue(Dynamic),
} }
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
impl IndexChainValue { impl ChainArgument {
/// Return the `Dynamic` value. /// Return the `Dynamic` value.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if not `IndexChainValue::Value`. /// Panics if not `ChainArgument::IndexValue`.
#[inline(always)] #[inline(always)]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub fn as_value(self) -> Dynamic { pub fn as_index_value(self) -> Dynamic {
match self { match self {
Self::None | Self::FnCallArgs(_) => panic!("expecting IndexChainValue::Value"), Self::Property | Self::FnCallArgs(_) => panic!("expecting ChainArgument::IndexValue"),
Self::Value(value) => value, Self::IndexValue(value) => value,
} }
} }
/// Return the `StaticVec<Dynamic>` value. /// Return the `StaticVec<Dynamic>` value.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if not `IndexChainValue::FnCallArgs`. /// Panics if not `ChainArgument::FnCallArgs`.
#[inline(always)] #[inline(always)]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub fn as_fn_call_args(self) -> StaticVec<Dynamic> { pub fn as_fn_call_args(self) -> StaticVec<Dynamic> {
match self { match self {
Self::None | Self::Value(_) => panic!("expecting IndexChainValue::FnCallArgs"), Self::Property | Self::IndexValue(_) => panic!("expecting ChainArgument::FnCallArgs"),
Self::FnCallArgs(value) => value, Self::FnCallArgs(value) => value,
} }
} }
} }
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
impl From<StaticVec<Dynamic>> for IndexChainValue { impl From<StaticVec<Dynamic>> for ChainArgument {
#[inline(always)] #[inline(always)]
fn from(value: StaticVec<Dynamic>) -> Self { fn from(value: StaticVec<Dynamic>) -> Self {
Self::FnCallArgs(value) Self::FnCallArgs(value)
@ -270,10 +277,10 @@ impl From<StaticVec<Dynamic>> for IndexChainValue {
} }
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
impl From<Dynamic> for IndexChainValue { impl From<Dynamic> for ChainArgument {
#[inline(always)] #[inline(always)]
fn from(value: Dynamic) -> Self { fn from(value: Dynamic) -> Self {
Self::Value(value) Self::IndexValue(value)
} }
} }
@ -487,7 +494,7 @@ impl<T: Into<Dynamic>> From<T> for Target<'_> {
/// _(INTERNALS)_ A type that holds all the current states of the [`Engine`]. /// _(INTERNALS)_ A type that holds all the current states of the [`Engine`].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -524,7 +531,7 @@ impl State {
/// _(INTERNALS)_ A type containing all the limits imposed by the [`Engine`]. /// _(INTERNALS)_ A type containing all the limits imposed by the [`Engine`].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
@ -850,7 +857,8 @@ impl Engine {
} }
/// Create a new [`Engine`] with minimal built-in functions. /// Create a new [`Engine`] with minimal built-in functions.
/// Use the [`register_global_module`][Engine::register_global_module] method to load additional packages of functions. ///
/// Use [`register_global_module`][Engine::register_global_module] to add packages of functions.
#[inline] #[inline]
pub fn new_raw() -> Self { pub fn new_raw() -> Self {
Self { Self {
@ -1021,13 +1029,13 @@ impl Engine {
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
target: &mut Target, target: &mut Target,
rhs: &Expr, rhs: &Expr,
idx_values: &mut StaticVec<IndexChainValue>, idx_values: &mut StaticVec<ChainArgument>,
chain_type: ChainType, chain_type: ChainType,
level: usize, level: usize,
new_val: Option<(Dynamic, Position)>, new_val: Option<(Dynamic, Position)>,
) -> Result<(Dynamic, bool), Box<EvalAltResult>> { ) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
if chain_type == ChainType::None { if chain_type == ChainType::NonChaining {
unreachable!("should not be ChainType::None"); unreachable!("should not be ChainType::NonChaining");
} }
let is_ref = target.is_ref(); let is_ref = target.is_ref();
@ -1035,7 +1043,7 @@ impl Engine {
let next_chain = match rhs { let next_chain = match rhs {
Expr::Index(_, _) => ChainType::Index, Expr::Index(_, _) => ChainType::Index,
Expr::Dot(_, _) => ChainType::Dot, Expr::Dot(_, _) => ChainType::Dot,
_ => ChainType::None, _ => ChainType::NonChaining,
}; };
// Pop the last index value // Pop the last index value
@ -1052,7 +1060,7 @@ impl Engine {
// xxx[idx].expr... | xxx[idx][expr]... // xxx[idx].expr... | xxx[idx][expr]...
Expr::Dot(x, x_pos) | Expr::Index(x, x_pos) => { Expr::Dot(x, x_pos) | Expr::Index(x, x_pos) => {
let idx_pos = x.lhs.position(); let idx_pos = x.lhs.position();
let idx_val = idx_val.as_value(); let idx_val = idx_val.as_index_value();
let obj_ptr = &mut self.get_indexed_mut( let obj_ptr = &mut self.get_indexed_mut(
mods, state, lib, target_val, idx_val, idx_pos, false, is_ref, true, mods, state, lib, target_val, idx_val, idx_pos, false, is_ref, true,
level, level,
@ -1066,7 +1074,7 @@ impl Engine {
} }
// xxx[rhs] = new_val // xxx[rhs] = new_val
_ if new_val.is_some() => { _ if new_val.is_some() => {
let idx_val = idx_val.as_value(); let idx_val = idx_val.as_index_value();
let mut idx_val2 = idx_val.clone(); let mut idx_val2 = idx_val.clone();
// `call_setter` is introduced to bypass double mutable borrowing of target // `call_setter` is introduced to bypass double mutable borrowing of target
@ -1114,7 +1122,7 @@ impl Engine {
} }
// xxx[rhs] // xxx[rhs]
_ => { _ => {
let idx_val = idx_val.as_value(); let idx_val = idx_val.as_index_value();
self.get_indexed_mut( self.get_indexed_mut(
mods, state, lib, target_val, idx_val, pos, false, is_ref, true, level, mods, state, lib, target_val, idx_val, pos, false, is_ref, true, level,
) )
@ -1405,7 +1413,7 @@ impl Engine {
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
expr: &Expr, expr: &Expr,
parent_chain_type: ChainType, parent_chain_type: ChainType,
idx_values: &mut StaticVec<IndexChainValue>, idx_values: &mut StaticVec<ChainArgument>,
size: usize, size: usize,
level: usize, level: usize,
) -> Result<(), Box<EvalAltResult>> { ) -> Result<(), Box<EvalAltResult>> {
@ -1428,7 +1436,7 @@ impl Engine {
} }
Expr::Property(_) if parent_chain_type == ChainType::Dot => { Expr::Property(_) if parent_chain_type == ChainType::Dot => {
idx_values.push(IndexChainValue::None) idx_values.push(ChainArgument::Property)
} }
Expr::Property(_) => unreachable!("unexpected Expr::Property for indexing"), Expr::Property(_) => unreachable!("unexpected Expr::Property for indexing"),
@ -1438,7 +1446,7 @@ impl Engine {
// Evaluate in left-to-right order // Evaluate in left-to-right order
let lhs_val = match lhs { let lhs_val = match lhs {
Expr::Property(_) if parent_chain_type == ChainType::Dot => { Expr::Property(_) if parent_chain_type == ChainType::Dot => {
IndexChainValue::None ChainArgument::Property
} }
Expr::Property(_) => unreachable!("unexpected Expr::Property for indexing"), Expr::Property(_) => unreachable!("unexpected Expr::Property for indexing"),
Expr::FnCall(x, _) Expr::FnCall(x, _)
@ -2312,7 +2320,7 @@ impl Engine {
let result = self let result = self
.eval_stmt(scope, mods, state, lib, this_ptr, try_body, level) .eval_stmt(scope, mods, state, lib, this_ptr, try_body, level)
.map(|_| ().into()); .map(|_| Dynamic::UNIT);
match result { match result {
Ok(_) => result, Ok(_) => result,
@ -2374,7 +2382,7 @@ impl Engine {
// Empty throw // Empty throw
Stmt::Return((ReturnType::Exception, pos), None, _) => { Stmt::Return((ReturnType::Exception, pos), None, _) => {
EvalAltResult::ErrorRuntime(().into(), *pos).into() EvalAltResult::ErrorRuntime(Dynamic::UNIT, *pos).into()
} }
// Let/const statement // Let/const statement
@ -2389,7 +2397,7 @@ impl Engine {
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)? self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.flatten() .flatten()
} else { } else {
().into() Dynamic::UNIT
}; };
let (var_name, _alias): (Cow<'_, str>, _) = if state.is_global() { let (var_name, _alias): (Cow<'_, str>, _) = if state.is_global() {
( (
@ -2607,6 +2615,7 @@ impl Engine {
} }
/// Check if the number of operations stay within limit. /// Check if the number of operations stay within limit.
#[inline]
pub(crate) fn inc_operations( pub(crate) fn inc_operations(
&self, &self,
state: &mut State, state: &mut State,

View File

@ -35,7 +35,7 @@ fn calc_hash_for_scripts<'a>(scripts: impl IntoIterator<Item = &'a &'a str>) ->
impl Engine { impl Engine {
/// Register a function of the [`Engine`]. /// Register a function of the [`Engine`].
/// ///
/// ## WARNING - Low Level API /// # WARNING - Low Level API
/// ///
/// This function is very low level. It takes a list of [`TypeId`][std::any::TypeId]'s indicating the actual types of the parameters. /// This function is very low level. It takes a list of [`TypeId`][std::any::TypeId]'s indicating the actual types of the parameters.
/// ///
@ -88,13 +88,12 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new)
/// /// // Use `register_fn` to register methods on the type.
/// // Use `register_fn` to register methods on the type. /// .register_fn("update", TestStruct::update);
/// engine.register_fn("update", TestStruct::update);
/// ///
/// assert_eq!( /// assert_eq!(
/// engine.eval::<TestStruct>("let x = new_ts(); x.update(41); x")?, /// engine.eval::<TestStruct>("let x = new_ts(); x.update(41); x")?,
@ -128,22 +127,19 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new);
/// ///
/// assert_eq!( /// assert_eq!(
/// engine.eval::<String>("let x = new_ts(); type_of(x)")?, /// engine.eval::<String>("let x = new_ts(); type_of(x)")?,
/// "rust_out::TestStruct" /// "rust_out::TestStruct"
/// ); /// );
/// ///
/// // Register the custom type with a name. /// // Re-register the custom type with a name.
/// engine.register_type_with_name::<TestStruct>("Hello"); /// engine.register_type_with_name::<TestStruct>("Hello");
/// ///
/// // Register methods on the type.
/// engine.register_fn("new_ts", TestStruct::new);
///
/// assert_eq!( /// assert_eq!(
/// engine.eval::<String>("let x = new_ts(); type_of(x)")?, /// engine.eval::<String>("let x = new_ts(); type_of(x)")?,
/// "Hello" /// "Hello"
@ -192,13 +188,12 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new)
/// /// // Register a getter on a property (notice it doesn't have to be the same name).
/// // Register a getter on a property (notice it doesn't have to be the same name). /// .register_get("xyz", TestStruct::get_field);
/// engine.register_get("xyz", TestStruct::get_field);
/// ///
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1); /// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1);
/// # Ok(()) /// # Ok(())
@ -239,13 +234,12 @@ impl Engine {
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new)
/// /// // Register a getter on a property (notice it doesn't have to be the same name).
/// // Register a getter on a property (notice it doesn't have to be the same name). /// .register_get_result("xyz", TestStruct::get_field);
/// engine.register_get_result("xyz", TestStruct::get_field);
/// ///
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1); /// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1);
/// # Ok(()) /// # Ok(())
@ -281,13 +275,12 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new)
/// /// // Register a setter on a property (notice it doesn't have to be the same name)
/// // Register a setter on a property (notice it doesn't have to be the same name) /// .register_set("xyz", TestStruct::set_field);
/// engine.register_set("xyz", TestStruct::set_field);
/// ///
/// // Notice that, with a getter, there is no way to get the property value /// // Notice that, with a getter, there is no way to get the property value
/// assert_eq!( /// assert_eq!(
@ -330,13 +323,12 @@ impl Engine {
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new)
/// /// // Register a setter on a property (notice it doesn't have to be the same name)
/// // Register a setter on a property (notice it doesn't have to be the same name) /// .register_set_result("xyz", TestStruct::set_field);
/// engine.register_set_result("xyz", TestStruct::set_field);
/// ///
/// // Notice that, with a getter, there is no way to get the property value /// // Notice that, with a getter, there is no way to get the property value
/// assert_eq!( /// assert_eq!(
@ -383,14 +375,13 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// engine.register_type::<TestStruct>(); /// engine
/// /// .register_type::<TestStruct>()
/// engine.register_fn("new_ts", TestStruct::new); /// .register_fn("new_ts", TestStruct::new)
/// /// // Register both a getter and a setter on a property
/// // Register a getter and a setter on a property /// // (notice it doesn't have to be the same name)
/// // (notice it doesn't have to be the same name) /// .register_get_set("xyz", TestStruct::get_field, TestStruct::set_field);
/// engine.register_get_set("xyz", TestStruct::get_field, TestStruct::set_field);
/// ///
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz = 42; a.xyz")?, 42); /// assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz = 42; a.xyz")?, 42);
/// # Ok(()) /// # Ok(())
@ -434,14 +425,14 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// # #[cfg(not(feature = "no_object"))] /// # #[cfg(not(feature = "no_object"))]
/// engine.register_type::<TestStruct>(); /// engine.register_type::<TestStruct>();
/// ///
/// engine.register_fn("new_ts", TestStruct::new); /// engine
/// /// .register_fn("new_ts", TestStruct::new)
/// // Register an indexer. /// // Register an indexer.
/// engine.register_indexer_get(TestStruct::get_field); /// .register_indexer_get(TestStruct::get_field);
/// ///
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3); /// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3);
/// # Ok(()) /// # Ok(())
@ -500,14 +491,14 @@ impl Engine {
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// # #[cfg(not(feature = "no_object"))] /// # #[cfg(not(feature = "no_object"))]
/// engine.register_type::<TestStruct>(); /// engine.register_type::<TestStruct>();
/// ///
/// engine.register_fn("new_ts", TestStruct::new); /// engine
/// /// .register_fn("new_ts", TestStruct::new)
/// // Register an indexer. /// // Register an indexer.
/// engine.register_indexer_get_result(TestStruct::get_field); /// .register_indexer_get_result(TestStruct::get_field);
/// ///
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3); /// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3);
/// # Ok(()) /// # Ok(())
@ -561,14 +552,14 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// # #[cfg(not(feature = "no_object"))] /// # #[cfg(not(feature = "no_object"))]
/// engine.register_type::<TestStruct>(); /// engine.register_type::<TestStruct>();
/// ///
/// engine.register_fn("new_ts", TestStruct::new); /// engine
/// /// .register_fn("new_ts", TestStruct::new)
/// // Register an indexer. /// // Register an indexer.
/// engine.register_indexer_set(TestStruct::set_field); /// .register_indexer_set(TestStruct::set_field);
/// ///
/// assert_eq!( /// assert_eq!(
/// engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2], /// engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2],
@ -628,14 +619,14 @@ impl Engine {
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// # #[cfg(not(feature = "no_object"))] /// # #[cfg(not(feature = "no_object"))]
/// engine.register_type::<TestStruct>(); /// engine.register_type::<TestStruct>();
/// ///
/// engine.register_fn("new_ts", TestStruct::new); /// engine
/// /// .register_fn("new_ts", TestStruct::new)
/// // Register an indexer. /// // Register an indexer.
/// engine.register_indexer_set_result(TestStruct::set_field); /// .register_indexer_set_result(TestStruct::set_field);
/// ///
/// assert_eq!( /// assert_eq!(
/// engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2], /// engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2],
@ -700,14 +691,14 @@ impl Engine {
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register the custom type. /// // Register API for the custom type.
/// # #[cfg(not(feature = "no_object"))] /// # #[cfg(not(feature = "no_object"))]
/// engine.register_type::<TestStruct>(); /// engine.register_type::<TestStruct>();
/// ///
/// engine.register_fn("new_ts", TestStruct::new); /// engine
/// /// .register_fn("new_ts", TestStruct::new)
/// // Register an indexer. /// // Register an indexer.
/// engine.register_indexer_get_set(TestStruct::get_field, TestStruct::set_field); /// .register_indexer_get_set(TestStruct::get_field, TestStruct::set_field);
/// ///
/// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2] = 42; a[2]")?, 42); /// assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2] = 42; a[2]")?, 42);
/// # Ok(()) /// # Ok(())
@ -740,9 +731,9 @@ impl Engine {
} }
/// Register a shared [`Module`] into the global namespace of [`Engine`]. /// Register a shared [`Module`] into the global namespace of [`Engine`].
/// ///
/// ## Deprecated /// # Deprecated
/// ///
/// Use `register_global_module` instead. /// Use [`register_global_module`][Engine::register_global_module] instead.
#[inline(always)] #[inline(always)]
#[deprecated = "use `register_global_module` instead"] #[deprecated = "use `register_global_module` instead"]
pub fn load_package(&mut self, module: impl Into<Shared<Module>>) -> &mut Self { pub fn load_package(&mut self, module: impl Into<Shared<Module>>) -> &mut Self {
@ -768,13 +759,12 @@ impl Engine {
/// ///
/// let module: Shared<Module> = module.into(); /// let module: Shared<Module> = module.into();
/// ///
/// // Register the module as a fixed sub-module /// engine
/// engine.register_static_module("foo::bar::baz", module.clone()); /// // Register the module as a fixed sub-module
/// /// .register_static_module("foo::bar::baz", module.clone())
/// // Multiple registrations to the same partial path is also OK! /// // Multiple registrations to the same partial path is also OK!
/// engine.register_static_module("foo::bar::hello", module.clone()); /// .register_static_module("foo::bar::hello", module.clone())
/// /// .register_static_module("CalcService", module);
/// engine.register_static_module("CalcService", module);
/// ///
/// assert_eq!(engine.eval::<i64>("foo::bar::baz::calc(41)")?, 42); /// assert_eq!(engine.eval::<i64>("foo::bar::baz::calc(41)")?, 42);
/// assert_eq!(engine.eval::<i64>("foo::bar::hello::calc(41)")?, 42); /// assert_eq!(engine.eval::<i64>("foo::bar::hello::calc(41)")?, 42);
@ -830,9 +820,9 @@ impl Engine {
/// Register a shared [`Module`] as a static module namespace with the [`Engine`]. /// Register a shared [`Module`] as a static module namespace with the [`Engine`].
/// ///
/// ## Deprecated /// # Deprecated
/// ///
/// Use `register_static_module` instead. /// Use [`register_static_module`][Engine::register_static_module] instead.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
#[deprecated = "use `register_static_module` instead"] #[deprecated = "use `register_static_module` instead"]
@ -1001,6 +991,8 @@ impl Engine {
} }
/// Compile a script file into an [`AST`], which can be used later for evaluation. /// Compile a script file into an [`AST`], which can be used later for evaluation.
/// ///
/// Not available under `no_std` or `WASM`.
///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
@ -1030,6 +1022,8 @@ impl Engine {
} }
/// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation. /// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation.
/// ///
/// Not available under `no_std` or `WASM`.
///
/// The scope is useful for passing constants into the script for optimization /// The scope is useful for passing constants into the script for optimization
/// when using [`OptimizationLevel::Full`]. /// when using [`OptimizationLevel::Full`].
/// ///
@ -1069,12 +1063,13 @@ impl Engine {
) -> Result<AST, Box<EvalAltResult>> { ) -> Result<AST, Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| Ok(self.compile_with_scope(scope, &contents)?)) Self::read_file(path).and_then(|contents| Ok(self.compile_with_scope(scope, &contents)?))
} }
/// Parse a JSON string into a map. /// Parse a JSON string into an [object map][`Map`].
/// This is a light-weight alternative to using, say, [`serde_json`][https://crates.io/crates/serde_json] to deserialize the JSON.
/// ///
/// The JSON string must be an object hash. It cannot be a simple JavaScript primitive. /// The JSON string must be an object hash. It cannot be a simple scalar value.
/// ///
/// Set `has_null` to `true` in order to map `null` values to `()`. /// Set `has_null` to `true` in order to map `null` values to `()`.
/// Setting it to `false` will cause a _variable not found_ error during parsing. /// Setting it to `false` will cause an [`ErrorVariableNotFound`][EvalAltResult::ErrorVariableNotFound] error during parsing.
/// ///
/// # JSON With Sub-Objects /// # JSON With Sub-Objects
/// ///
@ -1083,7 +1078,7 @@ impl Engine {
/// Parsing a JSON string with sub-objects will cause a syntax error. /// Parsing a JSON string with sub-objects will cause a syntax error.
/// ///
/// If it is certain that the character `{` never appears in any text string within the JSON object, /// If it is certain that the character `{` never appears in any text string within the JSON object,
/// then globally replace `{` with `#{` before calling this method. /// which is a valid assumption for many use cases, then globally replace `{` with `#{` before calling this method.
/// ///
/// # Example /// # Example
/// ///
@ -1235,6 +1230,8 @@ impl Engine {
} }
/// Evaluate a script file. /// Evaluate a script file.
/// ///
/// Not available under `no_std` or `WASM`.
///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
@ -1259,6 +1256,8 @@ impl Engine {
} }
/// Evaluate a script file with own scope. /// Evaluate a script file with own scope.
/// ///
/// Not available under `no_std` or `WASM`.
///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
@ -1483,6 +1482,8 @@ impl Engine {
} }
/// Evaluate a file, but throw away the result and only return error (if any). /// Evaluate a file, but throw away the result and only return error (if any).
/// Useful for when you don't need the result, but still need to keep track of possible errors. /// Useful for when you don't need the result, but still need to keep track of possible errors.
///
/// Not available under `no_std` or `WASM`.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)] #[inline(always)]
@ -1494,6 +1495,8 @@ impl Engine {
} }
/// Evaluate a file with own scope, but throw away the result and only return error (if any). /// Evaluate a file with own scope, but throw away the result and only return error (if any).
/// Useful for when you don't need the result, but still need to keep track of possible errors. /// Useful for when you don't need the result, but still need to keep track of possible errors.
///
/// Not available under `no_std` or `WASM`.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)] #[inline(always)]
@ -1611,7 +1614,7 @@ impl Engine {
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments /// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
/// and optionally a value for binding to the `this` pointer. /// and optionally a value for binding to the `this` pointer.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// All the arguments are _consumed_, meaning that they're replaced by `()`. /// All the arguments are _consumed_, meaning that they're replaced by `()`.
/// This is to avoid unnecessarily cloning the arguments. /// This is to avoid unnecessarily cloning the arguments.
@ -1673,7 +1676,7 @@ impl Engine {
} }
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments. /// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// All the arguments are _consumed_, meaning that they're replaced by `()`. /// All the arguments are _consumed_, meaning that they're replaced by `()`.
/// This is to avoid unnecessarily cloning the arguments. /// This is to avoid unnecessarily cloning the arguments.
@ -1776,12 +1779,12 @@ impl Engine {
} }
/// Provide a callback that will be invoked before each variable access. /// Provide a callback that will be invoked before each variable access.
/// ///
/// ## Return Value of Callback /// # Return Value of Callback
/// ///
/// Return `Ok(None)` to continue with normal variable access. /// Return `Ok(None)` to continue with normal variable access.
/// Return `Ok(Some(Dynamic))` as the variable's value. /// Return `Ok(Some(Dynamic))` as the variable's value.
/// ///
/// ## Errors in Callback /// # Errors in Callback
/// ///
/// Return `Err(...)` if there is an error. /// Return `Err(...)` if there is an error.
/// ///

View File

@ -10,7 +10,7 @@ use crate::stdlib::boxed::Box;
impl Engine { impl Engine {
/// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation. /// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation.
/// ///
/// Not available under the `no_optimize` feature. /// Not available under `no_optimize`.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline(always)] #[inline(always)]
pub fn set_optimization_level( pub fn set_optimization_level(
@ -23,7 +23,7 @@ impl Engine {
/// The current optimization level. /// The current optimization level.
/// It controls whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation. /// It controls whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation.
/// ///
/// Not available under the `no_optimize` feature. /// Not available under `no_optimize`.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline(always)] #[inline(always)]
pub fn optimization_level(&self) -> crate::OptimizationLevel { pub fn optimization_level(&self) -> crate::OptimizationLevel {
@ -37,6 +37,8 @@ impl Engine {
} }
/// Set the maximum levels of function calls allowed for a script in order to avoid /// Set the maximum levels of function calls allowed for a script in order to avoid
/// infinite recursion and stack overflows. /// infinite recursion and stack overflows.
///
/// Not available under `unchecked` or `no_function`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
@ -45,6 +47,8 @@ impl Engine {
self self
} }
/// The maximum levels of function calls allowed for a script. /// The maximum levels of function calls allowed for a script.
///
/// Not available under `unchecked` or `no_function`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
@ -53,6 +57,8 @@ impl Engine {
} }
/// Set the maximum number of operations allowed for a script to run to avoid /// Set the maximum number of operations allowed for a script to run to avoid
/// consuming too much resources (0 for unlimited). /// consuming too much resources (0 for unlimited).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn set_max_operations(&mut self, operations: u64) -> &mut Self { pub fn set_max_operations(&mut self, operations: u64) -> &mut Self {
@ -64,12 +70,16 @@ impl Engine {
self self
} }
/// The maximum number of operations allowed for a script to run (0 for unlimited). /// The maximum number of operations allowed for a script to run (0 for unlimited).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn max_operations(&self) -> u64 { pub fn max_operations(&self) -> u64 {
self.limits.max_operations self.limits.max_operations
} }
/// Set the maximum number of imported [modules][crate::Module] allowed for a script. /// Set the maximum number of imported [modules][crate::Module] allowed for a script.
///
/// Not available under `unchecked` or `no_module`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
@ -78,6 +88,8 @@ impl Engine {
self self
} }
/// The maximum number of imported [modules][crate::Module] allowed for a script. /// The maximum number of imported [modules][crate::Module] allowed for a script.
///
/// Not available under `unchecked` or `no_module`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
@ -85,6 +97,8 @@ impl Engine {
self.limits.max_modules self.limits.max_modules
} }
/// Set the depth limits for expressions (0 for unlimited). /// Set the depth limits for expressions (0 for unlimited).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn set_max_expr_depths( pub fn set_max_expr_depths(
@ -108,12 +122,16 @@ impl Engine {
self self
} }
/// The depth limit for expressions (0 for unlimited). /// The depth limit for expressions (0 for unlimited).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn max_expr_depth(&self) -> usize { pub fn max_expr_depth(&self) -> usize {
self.limits.max_expr_depth self.limits.max_expr_depth
} }
/// The depth limit for expressions in functions (0 for unlimited). /// The depth limit for expressions in functions (0 for unlimited).
///
/// Not available under `unchecked` or `no_function`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
@ -121,6 +139,8 @@ impl Engine {
self.limits.max_function_expr_depth self.limits.max_function_expr_depth
} }
/// Set the maximum length of [strings][crate::ImmutableString] (0 for unlimited). /// Set the maximum length of [strings][crate::ImmutableString] (0 for unlimited).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self { pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self {
@ -128,12 +148,16 @@ impl Engine {
self self
} }
/// The maximum length of [strings][crate::ImmutableString] (0 for unlimited). /// The maximum length of [strings][crate::ImmutableString] (0 for unlimited).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn max_string_size(&self) -> usize { pub fn max_string_size(&self) -> usize {
self.limits.max_string_size self.limits.max_string_size
} }
/// Set the maximum length of [arrays][crate::Array] (0 for unlimited). /// Set the maximum length of [arrays][crate::Array] (0 for unlimited).
///
/// Not available under `unchecked` or `no_index`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)] #[inline(always)]
@ -142,13 +166,17 @@ impl Engine {
self self
} }
/// The maximum length of [arrays][crate::Array] (0 for unlimited). /// The maximum length of [arrays][crate::Array] (0 for unlimited).
///
/// Not available under `unchecked` or `no_index`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)] #[inline(always)]
pub fn max_array_size(&self) -> usize { pub fn max_array_size(&self) -> usize {
self.limits.max_array_size self.limits.max_array_size
} }
/// Set the maximum length of [object maps][crate::Map] (0 for unlimited). /// Set the maximum size of [object maps][crate::Map] (0 for unlimited).
///
/// Not available under `unchecked` or `no_object`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]
@ -156,7 +184,9 @@ impl Engine {
self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size };
self self
} }
/// The maximum length of [object maps][crate::Map] (0 for unlimited). /// The maximum size of [object maps][crate::Map] (0 for unlimited).
///
/// Not available under `unchecked` or `no_object`.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]
@ -165,7 +195,7 @@ impl Engine {
} }
/// Set the module resolution service used by the [`Engine`]. /// Set the module resolution service used by the [`Engine`].
/// ///
/// Not available under the `no_module` feature. /// Not available under `no_module`.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
pub fn set_module_resolver( pub fn set_module_resolver(

View File

@ -155,7 +155,7 @@ pub fn ensure_no_data_race(
impl Engine { impl Engine {
/// Call a native Rust function registered with the [`Engine`]. /// Call a native Rust function registered with the [`Engine`].
/// ///
/// ## WARNING /// # WARNING
/// ///
/// Function call arguments be _consumed_ when the function requires them to be passed by value. /// Function call arguments be _consumed_ when the function requires them to be passed by value.
/// All function arguments not in the first position are always passed by value and thus consumed. /// All function arguments not in the first position are always passed by value and thus consumed.
@ -346,7 +346,7 @@ impl Engine {
/// Call a script-defined function. /// Call a script-defined function.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// Function call arguments may be _consumed_ when the function requires them to be passed by value. /// Function call arguments may be _consumed_ when the function requires them to be passed by value.
/// All function arguments not in the first position are always passed by value and thus consumed. /// All function arguments not in the first position are always passed by value and thus consumed.
@ -516,7 +516,7 @@ impl Engine {
/// Perform an actual function call, native Rust or scripted, taking care of special functions. /// Perform an actual function call, native Rust or scripted, taking care of special functions.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// Function call arguments may be _consumed_ when the function requires them to be passed by value. /// Function call arguments may be _consumed_ when the function requires them to be passed by value.
/// All function arguments not in the first position are always passed by value and thus consumed. /// All function arguments not in the first position are always passed by value and thus consumed.
@ -698,7 +698,7 @@ impl Engine {
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
statements statements
.into_iter() .into_iter()
.try_fold(().into(), |_, stmt| { .try_fold(Dynamic::UNIT, |_, stmt| {
self.eval_stmt(scope, mods, state, lib, &mut None, stmt, level) self.eval_stmt(scope, mods, state, lib, &mut None, stmt, level)
}) })
.or_else(|err| match *err { .or_else(|err| match *err {

View File

@ -12,6 +12,7 @@ pub trait Func<ARGS, RET> {
type Output; type Output;
/// Create a Rust closure from an [`AST`]. /// Create a Rust closure from an [`AST`].
///
/// The [`Engine`] and [`AST`] are consumed and basically embedded into the closure. /// The [`Engine`] and [`AST`] are consumed and basically embedded into the closure.
/// ///
/// # Example /// # Example
@ -43,6 +44,7 @@ pub trait Func<ARGS, RET> {
fn create_from_ast(self, ast: AST, entry_point: &str) -> Self::Output; fn create_from_ast(self, ast: AST, entry_point: &str) -> Self::Output;
/// Create a Rust closure from a script. /// Create a Rust closure from a script.
///
/// The [`Engine`] is consumed and basically embedded into the closure. /// The [`Engine`] is consumed and basically embedded into the closure.
/// ///
/// # Example /// # Example

View File

@ -134,7 +134,7 @@ impl<'e, 's, 'a, 'm, 'pm> NativeCallContext<'e, 's, 'a, 'm, 'pm> {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &Module)> { pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &Module)> {
self.mods.iter().flat_map(|m| m.iter()) self.mods.iter().flat_map(|&m| m.iter())
} }
/// _(INTERNALS)_ The current set of modules imported via `import` statements. /// _(INTERNALS)_ The current set of modules imported via `import` statements.
/// Available under the `internals` feature only. /// Available under the `internals` feature only.
@ -158,7 +158,7 @@ impl<'e, 's, 'a, 'm, 'pm> NativeCallContext<'e, 's, 'a, 'm, 'pm> {
} }
/// Call a function inside the call context. /// Call a function inside the call context.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// All arguments may be _consumed_, meaning that they may be replaced by `()`. /// All arguments may be _consumed_, meaning that they may be replaced by `()`.
/// This is to avoid unnecessarily cloning the arguments. /// This is to avoid unnecessarily cloning the arguments.
@ -298,7 +298,7 @@ impl FnPtr {
/// ///
/// If this function is a script-defined function, it must not be marked private. /// If this function is a script-defined function, it must not be marked private.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// All the arguments are _consumed_, meaning that they're replaced by `()`. /// All the arguments are _consumed_, meaning that they're replaced by `()`.
/// This is to avoid unnecessarily cloning the arguments. /// This is to avoid unnecessarily cloning the arguments.

View File

@ -104,7 +104,7 @@ pub type INT = i32;
/// ///
/// If the `f32_float` feature is enabled, this will be [`i32`] instead. /// If the `f32_float` feature is enabled, this will be [`i32`] instead.
/// ///
/// Not available under the `no_float` feature. /// Not available under `no_float`.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
#[cfg(not(feature = "f32_float"))] #[cfg(not(feature = "f32_float"))]
pub type FLOAT = f64; pub type FLOAT = f64;
@ -114,7 +114,7 @@ pub type FLOAT = f64;
/// ///
/// If the `f32_float` feature is not used, this will be `f64` instead. /// If the `f32_float` feature is not used, this will be `f64` instead.
/// ///
/// Not available under the `no_float` feature. /// Not available under `no_float`.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
#[cfg(feature = "f32_float")] #[cfg(feature = "f32_float")]
pub type FLOAT = f32; pub type FLOAT = f32;
@ -148,13 +148,13 @@ pub use fn_func::Func;
/// Variable-sized array of [`Dynamic`] values. /// Variable-sized array of [`Dynamic`] values.
/// ///
/// Not available under the `no_index` feature. /// Not available under `no_index`.
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub type Array = stdlib::vec::Vec<Dynamic>; pub type Array = stdlib::vec::Vec<Dynamic>;
/// Hash map of [`Dynamic`] values with [`ImmutableString`] keys. /// Hash map of [`Dynamic`] values with [`ImmutableString`] keys.
/// ///
/// Not available under the `no_object` feature. /// Not available under `no_object`.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub type Map = stdlib::collections::HashMap<ImmutableString, Dynamic>; pub type Map = stdlib::collections::HashMap<ImmutableString, Dynamic>;

View File

@ -125,17 +125,15 @@ impl FuncInfo {
/// A module which may contain variables, sub-modules, external Rust functions, /// A module which may contain variables, sub-modules, external Rust functions,
/// and/or script-defined functions. /// and/or script-defined functions.
///
/// Not available under the `no_module` feature.
#[derive(Clone)] #[derive(Clone)]
pub struct Module { pub struct Module {
/// ID identifying the module. /// ID identifying the module.
id: Option<ImmutableString>, id: Option<ImmutableString>,
/// Sub-modules. /// Sub-modules.
modules: HashMap<ImmutableString, Shared<Module>>, modules: HashMap<ImmutableString, Shared<Module>>,
/// Module variables. /// [`Module`] variables.
variables: HashMap<ImmutableString, Dynamic>, variables: HashMap<ImmutableString, Dynamic>,
/// Flattened collection of all module variables, including those in sub-modules. /// Flattened collection of all [`Module`] variables, including those in sub-modules.
all_variables: HashMap<NonZeroU64, Dynamic, StraightHasherBuilder>, all_variables: HashMap<NonZeroU64, Dynamic, StraightHasherBuilder>,
/// External Rust functions. /// External Rust functions.
functions: HashMap<NonZeroU64, FuncInfo, StraightHasherBuilder>, functions: HashMap<NonZeroU64, FuncInfo, StraightHasherBuilder>,
@ -146,7 +144,7 @@ pub struct Module {
type_iterators: HashMap<TypeId, IteratorFn>, type_iterators: HashMap<TypeId, IteratorFn>,
/// Flattened collection of iterator functions, including those in sub-modules. /// Flattened collection of iterator functions, including those in sub-modules.
all_type_iterators: HashMap<TypeId, IteratorFn>, all_type_iterators: HashMap<TypeId, IteratorFn>,
/// Is the module indexed? /// Is the [`Module`] indexed?
indexed: bool, indexed: bool,
} }
@ -203,7 +201,7 @@ impl AsRef<Module> for Module {
} }
impl Module { impl Module {
/// Create a new module. /// Create a new [`Module`].
/// ///
/// # Example /// # Example
/// ///
@ -219,7 +217,7 @@ impl Module {
Default::default() Default::default()
} }
/// Create a new module with a specified capacity for native Rust functions. /// Create a new [`Module`] with a specified capacity for native Rust functions.
/// ///
/// # Example /// # Example
/// ///
@ -238,7 +236,7 @@ impl Module {
} }
} }
/// Get the ID of the module, if any. /// Get the ID of the [`Module`], if any.
/// ///
/// # Example /// # Example
/// ///
@ -253,12 +251,12 @@ impl Module {
self.id.as_ref().map(|s| s.as_str()) self.id.as_ref().map(|s| s.as_str())
} }
/// Get the ID of the module, if any. /// Get the ID of the [`Module`], if any.
pub(crate) fn id_raw(&self) -> &Option<ImmutableString> { pub(crate) fn id_raw(&self) -> &Option<ImmutableString> {
&self.id &self.id
} }
/// Set the ID of the module. /// Set the ID of the [`Module`].
/// ///
/// # Example /// # Example
/// ///
@ -273,7 +271,7 @@ impl Module {
self.id = id.map(|s| s.into()); self.id = id.map(|s| s.into());
} }
/// Is the module empty? /// Is the [`Module`] empty?
/// ///
/// # Example /// # Example
/// ///
@ -294,7 +292,7 @@ impl Module {
&& self.all_type_iterators.is_empty() && self.all_type_iterators.is_empty()
} }
/// Is the module indexed? /// Is the [`Module`] indexed?
/// ///
/// # Example /// # Example
/// ///
@ -314,7 +312,7 @@ impl Module {
self.indexed self.indexed
} }
/// Generate signatures for all the functions in the module. /// Generate signatures for all the functions in the [`Module`].
pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator<Item = String> + 'a { pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator<Item = String> + 'a {
self.functions self.functions
.values() .values()
@ -322,7 +320,7 @@ impl Module {
.map(FuncInfo::gen_signature) .map(FuncInfo::gen_signature)
} }
/// Does a variable exist in the module? /// Does a variable exist in the [`Module`]?
/// ///
/// # Example /// # Example
/// ///
@ -338,7 +336,7 @@ impl Module {
self.variables.contains_key(name) self.variables.contains_key(name)
} }
/// Get the value of a module variable. /// Get the value of a [`Module`] variable.
/// ///
/// # Example /// # Example
/// ///
@ -354,7 +352,7 @@ impl Module {
self.get_var(name).and_then(Dynamic::try_cast::<T>) self.get_var(name).and_then(Dynamic::try_cast::<T>)
} }
/// Get a module variable as a [`Dynamic`]. /// Get a [`Module`] variable as a [`Dynamic`].
/// ///
/// # Example /// # Example
/// ///
@ -370,7 +368,7 @@ impl Module {
self.variables.get(name).cloned() self.variables.get(name).cloned()
} }
/// Set a variable into the module. /// Set a variable into the [`Module`].
/// ///
/// If there is an existing variable of the same name, it is replaced. /// If there is an existing variable of the same name, it is replaced.
/// ///
@ -397,7 +395,7 @@ impl Module {
/// Get a reference to a namespace-qualified variable. /// Get a reference to a namespace-qualified variable.
/// Name and Position in [`EvalAltResult`] are [`None`] and [`NONE`][Position::NONE] and must be set afterwards. /// Name and Position in [`EvalAltResult`] are [`None`] and [`NONE`][Position::NONE] and must be set afterwards.
/// ///
/// The [`NonZeroU64`] hash is calculated by the function [`crate::calc_native_fn_hash`]. /// The [`NonZeroU64`] hash is calculated by the function [`calc_native_fn_hash`][crate::calc_native_fn_hash].
#[inline(always)] #[inline(always)]
pub(crate) fn get_qualified_var( pub(crate) fn get_qualified_var(
&self, &self,
@ -408,7 +406,7 @@ impl Module {
}) })
} }
/// Set a script-defined function into the module. /// Set a script-defined function into the [`Module`].
/// ///
/// If there is an existing function of the same name and number of arguments, it is replaced. /// If there is an existing function of the same name and number of arguments, it is replaced.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
@ -437,7 +435,7 @@ impl Module {
hash_script hash_script
} }
/// Get a script-defined function in the module based on name and number of parameters. /// Get a script-defined function in the [`Module`] based on name and number of parameters.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub fn get_script_fn( pub fn get_script_fn(
@ -465,10 +463,10 @@ impl Module {
/// Get a mutable reference to the underlying [`HashMap`] of sub-modules. /// Get a mutable reference to the underlying [`HashMap`] of sub-modules.
/// ///
/// ## Warning /// # WARNING
/// ///
/// By taking a mutable reference, it is assumed that some sub-modules will be modified. /// By taking a mutable reference, it is assumed that some sub-modules will be modified.
/// Thus the module is automatically set to be non-indexed. /// Thus the [`Module`] is automatically set to be non-indexed.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
pub(crate) fn sub_modules_mut(&mut self) -> &mut HashMap<ImmutableString, Shared<Module>> { pub(crate) fn sub_modules_mut(&mut self) -> &mut HashMap<ImmutableString, Shared<Module>> {
@ -482,7 +480,7 @@ impl Module {
&mut self.modules &mut self.modules
} }
/// Does a sub-module exist in the module? /// Does a sub-module exist in the [`Module`]?
/// ///
/// # Example /// # Example
/// ///
@ -499,7 +497,7 @@ impl Module {
self.modules.contains_key(name) self.modules.contains_key(name)
} }
/// Get a sub-module. /// Get a sub-module in the [`Module`].
/// ///
/// # Example /// # Example
/// ///
@ -516,7 +514,7 @@ impl Module {
self.modules.get(name).map(|m| m.as_ref()) self.modules.get(name).map(|m| m.as_ref())
} }
/// Set a sub-module into the module. /// Set a sub-module into the [`Module`].
/// ///
/// If there is an existing sub-module of the same name, it is replaced. /// If there is an existing sub-module of the same name, it is replaced.
/// ///
@ -541,9 +539,9 @@ impl Module {
self self
} }
/// Does the particular Rust function exist in the module? /// Does the particular Rust function exist in the [`Module`]?
/// ///
/// The [`NonZeroU64`] hash is calculated by the function [`crate::calc_native_fn_hash`]. /// The [`NonZeroU64`] hash is calculated by the function [`calc_native_fn_hash`][crate::calc_native_fn_hash].
/// It is also returned by the `set_fn_XXX` calls. /// It is also returned by the `set_fn_XXX` calls.
/// ///
/// # Example /// # Example
@ -569,12 +567,17 @@ impl Module {
/// Update the metadata (parameter names/types and return type) of a registered function. /// Update the metadata (parameter names/types and return type) of a registered function.
/// ///
/// The [`NonZeroU64`] hash is calculated either by the function [`crate::calc_native_fn_hash`] or /// The [`NonZeroU64`] hash is calculated either by the function
/// the function [`crate::calc_script_fn_hash`]. /// [`calc_native_fn_hash`][crate::calc_native_fn_hash] or the function
/// [`calc_script_fn_hash`][crate::calc_script_fn_hash].
///
/// ## Parameter Names and Types
/// ///
/// Each parameter name/type pair should be a single string of the format: `var_name: type`. /// Each parameter name/type pair should be a single string of the format: `var_name: type`.
/// ///
/// The last entry in the list should be the return type of the function. /// ## Return Type
///
/// The _last entry_ in the list should be the _return type_ of the function.
/// In other words, the number of entries should be one larger than the number of parameters. /// In other words, the number of entries should be one larger than the number of parameters.
pub fn update_fn_metadata<'a>( pub fn update_fn_metadata<'a>(
&mut self, &mut self,
@ -589,8 +592,9 @@ impl Module {
/// Update the namespace of a registered function. /// Update the namespace of a registered function.
/// ///
/// The [`NonZeroU64`] hash is calculated either by the function [`crate::calc_native_fn_hash`] or /// The [`NonZeroU64`] hash is calculated either by the function
/// the function [`crate::calc_script_fn_hash`]. /// [`calc_native_fn_hash`][crate::calc_native_fn_hash] or the function
/// [`calc_script_fn_hash`][crate::calc_script_fn_hash].
pub fn update_fn_namespace( pub fn update_fn_namespace(
&mut self, &mut self,
hash_fn: NonZeroU64, hash_fn: NonZeroU64,
@ -603,11 +607,11 @@ impl Module {
self self
} }
/// Set a Rust function into the module, returning a hash key. /// Set a Rust function into the [`Module`], returning a hash key.
/// ///
/// If there is an existing Rust function of the same hash, it is replaced. /// If there is an existing Rust function of the same hash, it is replaced.
/// ///
/// ## WARNING - Low Level API /// # WARNING - Low Level API
/// ///
/// This function is very low level. /// This function is very low level.
pub fn set_fn( pub fn set_fn(
@ -660,7 +664,7 @@ impl Module {
/// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine], /// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine],
/// the current set of functions, plus a list of mutable [`Dynamic`] references /// the current set of functions, plus a list of mutable [`Dynamic`] references
/// into the module, returning a hash key. /// into the [`Module`], returning a hash key.
/// ///
/// Use this to register a built-in function which must reference settings on the scripting /// Use this to register a built-in function which must reference settings on the scripting
/// [`Engine`][crate::Engine] (e.g. to prevent growing an array beyond the allowed maximum size), /// [`Engine`][crate::Engine] (e.g. to prevent growing an array beyond the allowed maximum size),
@ -668,13 +672,13 @@ impl Module {
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
/// ## WARNING - Low Level API /// # WARNING - Low Level API
/// ///
/// This function is very low level. /// This function is very low level.
/// ///
/// A list of [`TypeId`]'s is taken as the argument types. /// A list of [`TypeId`]'s is taken as the argument types.
/// ///
/// Arguments are simply passed in as a mutable array of [`&mut Dynamic`], /// Arguments are simply passed in as a mutable array of [`&mut Dynamic`][Dynamic],
/// which is guaranteed to contain enough arguments of the correct types. /// which is guaranteed to contain enough arguments of the correct types.
/// ///
/// The function is assumed to be a _method_, meaning that the first argument should not be consumed. /// The function is assumed to be a _method_, meaning that the first argument should not be consumed.
@ -746,7 +750,7 @@ impl Module {
) )
} }
/// Set a Rust function taking no parameters into the module, returning a hash key. /// Set a Rust function taking no parameters into the [`Module`], returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -781,7 +785,7 @@ impl Module {
) )
} }
/// Set a Rust function taking one parameter into the module, returning a hash key. /// Set a Rust function taking one parameter into the [`Module`], returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -818,7 +822,7 @@ impl Module {
) )
} }
/// Set a Rust function taking one mutable parameter into the module, returning a hash key. /// Set a Rust function taking one mutable parameter into the [`Module`], returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -890,7 +894,7 @@ impl Module {
) )
} }
/// Set a Rust function taking two parameters into the module, returning a hash key. /// Set a Rust function taking two parameters into the [`Module`], returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -932,7 +936,7 @@ impl Module {
) )
} }
/// Set a Rust function taking two parameters (the first one mutable) into the module, /// Set a Rust function taking two parameters (the first one mutable) into the [`Module`],
/// returning a hash key. /// returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
@ -979,7 +983,7 @@ impl Module {
) )
} }
/// Set a Rust setter function taking two parameters (the first one mutable) into the module, /// Set a Rust setter function taking two parameters (the first one mutable) into the [`Module`],
/// returning a hash key. /// returning a hash key.
/// This function is automatically exposed to the global namespace. /// This function is automatically exposed to the global namespace.
/// ///
@ -1015,7 +1019,7 @@ impl Module {
) )
} }
/// Set a Rust index getter taking two parameters (the first one mutable) into the module, /// Set a Rust index getter taking two parameters (the first one mutable) into the [`Module`],
/// returning a hash key. /// returning a hash key.
/// This function is automatically exposed to the global namespace. /// This function is automatically exposed to the global namespace.
/// ///
@ -1064,7 +1068,7 @@ impl Module {
self.set_fn_2_mut(crate::engine::FN_IDX_GET, FnNamespace::Global, func) self.set_fn_2_mut(crate::engine::FN_IDX_GET, FnNamespace::Global, func)
} }
/// Set a Rust function taking three parameters into the module, returning a hash key. /// Set a Rust function taking three parameters into the [`Module`], returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -1112,7 +1116,7 @@ impl Module {
) )
} }
/// Set a Rust function taking three parameters (the first one mutable) into the module, /// Set a Rust function taking three parameters (the first one mutable) into the [`Module`],
/// returning a hash key. /// returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
@ -1165,7 +1169,7 @@ impl Module {
) )
} }
/// Set a Rust index setter taking three parameters (the first one mutable) into the module, /// Set a Rust index setter taking three parameters (the first one mutable) into the [`Module`],
/// returning a hash key. /// returning a hash key.
/// This function is automatically exposed to the global namespace. /// This function is automatically exposed to the global namespace.
/// ///
@ -1276,7 +1280,7 @@ impl Module {
) )
} }
/// Set a Rust function taking four parameters into the module, returning a hash key. /// Set a Rust function taking four parameters into the [`Module`], returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -1331,7 +1335,7 @@ impl Module {
) )
} }
/// Set a Rust function taking four parameters (the first one mutable) into the module, /// Set a Rust function taking four parameters (the first one mutable) into the [`Module`],
/// returning a hash key. /// returning a hash key.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
@ -1393,7 +1397,7 @@ impl Module {
/// Get a Rust function. /// Get a Rust function.
/// ///
/// The [`NonZeroU64`] hash is calculated by the function [`crate::calc_native_fn_hash`]. /// The [`NonZeroU64`] hash is calculated by the function [`calc_native_fn_hash`][crate::calc_native_fn_hash].
/// It is also returned by the `set_fn_XXX` calls. /// It is also returned by the `set_fn_XXX` calls.
#[inline(always)] #[inline(always)]
pub(crate) fn get_fn( pub(crate) fn get_fn(
@ -1410,9 +1414,10 @@ impl Module {
}) })
} }
/// Does the particular namespace-qualified function exist in the module? /// Does the particular namespace-qualified function exist in the [`Module`]?
/// ///
/// The [`NonZeroU64`] hash is calculated by the function [`crate::calc_native_fn_hash`] and must match /// The [`NonZeroU64`] hash is calculated by the function
/// [`calc_native_fn_hash`][crate::calc_native_fn_hash] and must match
/// the hash calculated by [`build_index`][Module::build_index]. /// the hash calculated by [`build_index`][Module::build_index].
#[inline(always)] #[inline(always)]
pub fn contains_qualified_fn(&self, hash_fn: NonZeroU64) -> bool { pub fn contains_qualified_fn(&self, hash_fn: NonZeroU64) -> bool {
@ -1421,7 +1426,8 @@ impl Module {
/// Get a namespace-qualified function. /// Get a namespace-qualified function.
/// ///
/// The [`NonZeroU64`] hash is calculated by the function [`crate::calc_native_fn_hash`] and must match /// The [`NonZeroU64`] hash is calculated by the function
/// [`calc_native_fn_hash`][crate::calc_native_fn_hash] and must match
/// the hash calculated by [`build_index`][Module::build_index]. /// the hash calculated by [`build_index`][Module::build_index].
#[inline(always)] #[inline(always)]
pub(crate) fn get_qualified_fn( pub(crate) fn get_qualified_fn(
@ -1431,8 +1437,8 @@ impl Module {
self.all_functions.get(&hash_qualified_fn) self.all_functions.get(&hash_qualified_fn)
} }
/// Combine another module into this module. /// Combine another [`Module`] into this [`Module`].
/// The other module is consumed to merge into this module. /// The other [`Module`] is _consumed_ to merge into this [`Module`].
#[inline] #[inline]
pub fn combine(&mut self, other: Self) -> &mut Self { pub fn combine(&mut self, other: Self) -> &mut Self {
self.modules.extend(other.modules.into_iter()); self.modules.extend(other.modules.into_iter());
@ -1446,9 +1452,9 @@ impl Module {
self self
} }
/// Combine another module into this module. /// Combine another [`Module`] into this [`Module`].
/// The other module is consumed to merge into this module. /// The other [`Module`] is _consumed_ to merge into this [`Module`].
/// Sub-modules are flattened onto the root module, with higher level overriding lower level. /// Sub-modules are flattened onto the root [`Module`], with higher level overriding lower level.
#[inline] #[inline]
pub fn combine_flatten(&mut self, other: Self) -> &mut Self { pub fn combine_flatten(&mut self, other: Self) -> &mut Self {
other.modules.into_iter().for_each(|(_, m)| { other.modules.into_iter().for_each(|(_, m)| {
@ -1464,8 +1470,8 @@ impl Module {
self self
} }
/// Poly-fill this module with another module. /// Polyfill this [`Module`] with another [`Module`].
/// Only items not existing in this module are added. /// Only items not existing in this [`Module`] are added.
#[inline] #[inline]
pub fn fill_with(&mut self, other: &Self) -> &mut Self { pub fn fill_with(&mut self, other: &Self) -> &mut Self {
other.modules.iter().for_each(|(k, v)| { other.modules.iter().for_each(|(k, v)| {
@ -1491,13 +1497,13 @@ impl Module {
self self
} }
/// Merge another module into this module. /// Merge another [`Module`] into this [`Module`].
#[inline(always)] #[inline(always)]
pub fn merge(&mut self, other: &Self) -> &mut Self { pub fn merge(&mut self, other: &Self) -> &mut Self {
self.merge_filtered(other, &mut |_, _, _, _, _| true) self.merge_filtered(other, &mut |_, _, _, _, _| true)
} }
/// Merge another module into this module based on a filter predicate. /// Merge another [`Module`] into this [`Module`] based on a filter predicate.
pub(crate) fn merge_filtered( pub(crate) fn merge_filtered(
&mut self, &mut self,
other: &Self, other: &Self,
@ -1583,7 +1589,7 @@ impl Module {
self self
} }
/// Get the number of variables, functions and type iterators in the module. /// Get the number of variables, functions and type iterators in the [`Module`].
#[inline(always)] #[inline(always)]
pub fn count(&self) -> (usize, usize, usize) { pub fn count(&self) -> (usize, usize, usize) {
( (
@ -1593,19 +1599,19 @@ impl Module {
) )
} }
/// Get an iterator to the sub-modules in the module. /// Get an iterator to the sub-modules in the [`Module`].
#[inline(always)] #[inline(always)]
pub fn iter_sub_modules(&self) -> impl Iterator<Item = (&str, Shared<Module>)> { pub fn iter_sub_modules(&self) -> impl Iterator<Item = (&str, Shared<Module>)> {
self.modules.iter().map(|(k, m)| (k.as_str(), m.clone())) self.modules.iter().map(|(k, m)| (k.as_str(), m.clone()))
} }
/// Get an iterator to the variables in the module. /// Get an iterator to the variables in the [`Module`].
#[inline(always)] #[inline(always)]
pub fn iter_var(&self) -> impl Iterator<Item = (&str, &Dynamic)> { pub fn iter_var(&self) -> impl Iterator<Item = (&str, &Dynamic)> {
self.variables.iter().map(|(k, v)| (k.as_str(), v)) self.variables.iter().map(|(k, v)| (k.as_str(), v))
} }
/// Get an iterator to the functions in the module. /// Get an iterator to the functions in the [`Module`].
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
@ -1613,7 +1619,7 @@ impl Module {
self.functions.values() self.functions.values()
} }
/// Get an iterator over all script-defined functions in the module. /// Get an iterator over all script-defined functions in the [`Module`].
/// ///
/// Function metadata includes: /// Function metadata includes:
/// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]). /// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]).
@ -1646,7 +1652,7 @@ impl Module {
) )
} }
/// Get an iterator over all script-defined functions in the module. /// Get an iterator over all script-defined functions in the [`Module`].
/// ///
/// Function metadata includes: /// Function metadata includes:
/// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]). /// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]).
@ -1670,7 +1676,7 @@ impl Module {
) )
} }
/// Get an iterator over all script-defined functions in the module. /// Get an iterator over all script-defined functions in the [`Module`].
/// ///
/// Function metadata includes: /// Function metadata includes:
/// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]). /// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]).
@ -1688,11 +1694,11 @@ impl Module {
self.iter_script_fn() self.iter_script_fn()
} }
/// Create a new module by evaluating an [`AST`][crate::AST]. /// Create a new [`Module`] by evaluating an [`AST`][crate::AST].
/// ///
/// The entire [`AST`][crate::AST] is encapsulated into each function, allowing functions /// The entire [`AST`][crate::AST] is encapsulated into each function, allowing functions
/// to cross-call each other. Functions in the global namespace, plus all functions /// to cross-call each other. Functions in the global namespace, plus all functions
/// defined in the module, are _merged_ into a _unified_ namespace before each call. /// defined in the [`Module`], are _merged_ into a _unified_ namespace before each call.
/// Therefore, all functions will be found. /// Therefore, all functions will be found.
/// ///
/// # Example /// # Example
@ -1765,10 +1771,10 @@ impl Module {
Ok(module) Ok(module)
} }
/// Scan through all the sub-modules in the module and build a hash index of all /// Scan through all the sub-modules in the [`Module`] and build a hash index of all
/// variables and functions as one flattened namespace. /// variables and functions as one flattened namespace.
/// ///
/// If the module is already indexed, this method has no effect. /// If the [`Module`] is already indexed, this method has no effect.
pub fn build_index(&mut self) -> &mut Self { pub fn build_index(&mut self) -> &mut Self {
// Collect a particular module. // Collect a particular module.
fn index_module<'a>( fn index_module<'a>(
@ -1886,14 +1892,14 @@ impl Module {
self.type_iterators.contains_key(&id) self.type_iterators.contains_key(&id)
} }
/// Set a type iterator into the module. /// Set a type iterator into the [`Module`].
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self { pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self {
self.type_iterators.insert(typ, func); self.type_iterators.insert(typ, func);
self.indexed = false; self.indexed = false;
self self
} }
/// Set a type iterator into the module. /// Set a type iterator into the [`Module`].
pub fn set_iterable<T>(&mut self) -> &mut Self pub fn set_iterable<T>(&mut self) -> &mut Self
where where
T: Variant + Clone + IntoIterator, T: Variant + Clone + IntoIterator,
@ -1904,7 +1910,7 @@ impl Module {
}) })
} }
/// Set an iterator type into the module as a type iterator. /// Set an iterator type into the [`Module`] as a type iterator.
pub fn set_iterator<T>(&mut self) -> &mut Self pub fn set_iterator<T>(&mut self) -> &mut Self
where where
T: Variant + Clone + Iterator, T: Variant + Clone + Iterator,
@ -1934,7 +1940,7 @@ impl Module {
/// A [`StaticVec`] is used because most namespace-qualified access contains only one level, /// A [`StaticVec`] is used because most namespace-qualified access contains only one level,
/// and it is wasteful to always allocate a [`Vec`] with one element. /// and it is wasteful to always allocate a [`Vec`] with one element.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Clone, Eq, PartialEq, Default, Hash)] #[derive(Clone, Eq, PartialEq, Default, Hash)]
@ -2018,10 +2024,9 @@ impl NamespaceRef {
} }
} }
/// Re-export module resolver trait.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
pub use resolvers::ModuleResolver; pub use resolvers::ModuleResolver;
/// Re-export module resolvers. /// Module containing all built-in [module resolvers][ModuleResolver].
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
pub mod resolvers; pub mod resolvers;

View File

@ -1,7 +1,7 @@
use crate::stdlib::{boxed::Box, ops::AddAssign, vec::Vec}; use crate::stdlib::{boxed::Box, ops::AddAssign, vec::Vec};
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
/// Module resolution service that holds a collection of module resolves, /// [Module] resolution service that holds a collection of [module][Module] resolves,
/// to be searched in sequential order. /// to be searched in sequential order.
/// ///
/// # Example /// # Example
@ -42,13 +42,13 @@ impl ModuleResolversCollection {
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
/// Append a module resolver to the end. /// Append a [module resolver][ModuleResolver] to the end.
#[inline(always)] #[inline(always)]
pub fn push(&mut self, resolver: impl ModuleResolver + 'static) -> &mut Self { pub fn push(&mut self, resolver: impl ModuleResolver + 'static) -> &mut Self {
self.0.push(Box::new(resolver)); self.0.push(Box::new(resolver));
self self
} }
/// Insert a module resolver to an offset index. /// Insert a [module resolver][ModuleResolver] to an offset index.
/// ///
/// # Panics /// # Panics
/// ///
@ -58,12 +58,12 @@ impl ModuleResolversCollection {
self.0.insert(index, Box::new(resolver)); self.0.insert(index, Box::new(resolver));
self self
} }
/// Remove the last module resolver from the end, if any. /// Remove the last [module resolver][ModuleResolver] from the end, if any.
#[inline(always)] #[inline(always)]
pub fn pop(&mut self) -> Option<Box<dyn ModuleResolver>> { pub fn pop(&mut self) -> Option<Box<dyn ModuleResolver>> {
self.0.pop() self.0.pop()
} }
/// Remove a module resolver at an offset index. /// Remove a [module resolver][ModuleResolver] at an offset index.
/// ///
/// # Panics /// # Panics
/// ///
@ -72,17 +72,17 @@ impl ModuleResolversCollection {
pub fn remove(&mut self, index: usize) -> Box<dyn ModuleResolver> { pub fn remove(&mut self, index: usize) -> Box<dyn ModuleResolver> {
self.0.remove(index) self.0.remove(index)
} }
/// Get an iterator of all the module resolvers. /// Get an iterator of all the [module resolvers][ModuleResolver].
#[inline(always)] #[inline(always)]
pub fn iter(&self) -> impl Iterator<Item = &dyn ModuleResolver> { pub fn iter(&self) -> impl Iterator<Item = &dyn ModuleResolver> {
self.0.iter().map(|v| v.as_ref()) self.0.iter().map(|v| v.as_ref())
} }
/// Get a mutable iterator of all the modules. /// Get a mutable iterator of all the [module resolvers][ModuleResolver].
#[inline(always)] #[inline(always)]
pub fn into_iter(self) -> impl Iterator<Item = Box<dyn ModuleResolver>> { pub fn into_iter(self) -> impl Iterator<Item = Box<dyn ModuleResolver>> {
self.0.into_iter() self.0.into_iter()
} }
/// Remove all module resolvers. /// Remove all [module resolvers][ModuleResolver].
#[inline(always)] #[inline(always)]
pub fn clear(&mut self) -> &mut Self { pub fn clear(&mut self) -> &mut Self {
self.0.clear(); self.0.clear();
@ -93,7 +93,7 @@ impl ModuleResolversCollection {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.is_empty() self.0.is_empty()
} }
/// Get the number of module resolvers in this [`ModuleResolversCollection`]. /// Get the number of [module resolvers][ModuleResolver] in this [`ModuleResolversCollection`].
#[inline(always)] #[inline(always)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.0.len() self.0.len()

View File

@ -1,7 +1,7 @@
use crate::stdlib::boxed::Box; use crate::stdlib::boxed::Box;
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
/// Empty/disabled module resolution service that acts as a dummy. /// Empty/disabled [module][Module] resolution service that acts as a dummy.
/// ///
/// # Example /// # Example
/// ///

View File

@ -7,21 +7,15 @@ use crate::stdlib::{
}; };
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
/// Module resolution service that loads module script files from the file system. /// [Module] resolution service that loads [module][Module] script files from the file system.
/// ///
/// Script files are cached so they are are not reloaded and recompiled in subsequent requests. /// Script files are cached so they are are not reloaded and recompiled in subsequent requests.
/// ///
/// The [`new_with_path`][FileModuleResolver::new_with_path] and
/// [`new_with_path_and_extension`][FileModuleResolver::new_with_path_and_extension] constructor functions
/// allow specification of a base directory with module path used as a relative path offset
/// to the base directory. The script file is then forced to be in a specified extension
/// (default `.rhai`).
///
/// # Function Namespace /// # Function Namespace
/// ///
/// When a function within a script file module is loaded, all functions in the _global_ namespace /// When a function within a script file module is called, all functions in the _global_ namespace
/// plus all those defined within the same module are _merged_ into a _unified_ namespace before /// plus all those defined within the same module are _merged_ into a _unified_ namespace before
/// the call. Therefore, functions in a module script can cross-call each other. /// the call. Therefore, functions in a module script can always cross-call each other.
/// ///
/// # Example /// # Example
/// ///
@ -58,6 +52,8 @@ impl Default for FileModuleResolver {
impl FileModuleResolver { impl FileModuleResolver {
/// Create a new [`FileModuleResolver`] with a specific base path. /// Create a new [`FileModuleResolver`] with a specific base path.
/// ///
/// The default extension is `.rhai`.
///
/// # Example /// # Example
/// ///
/// ``` /// ```
@ -78,8 +74,6 @@ impl FileModuleResolver {
/// Create a new [`FileModuleResolver`] with a specific base path and file extension. /// Create a new [`FileModuleResolver`] with a specific base path and file extension.
/// ///
/// The default extension is `.rhai`.
///
/// # Example /// # Example
/// ///
/// ``` /// ```
@ -107,6 +101,8 @@ impl FileModuleResolver {
/// Create a new [`FileModuleResolver`] with the current directory as base path. /// Create a new [`FileModuleResolver`] with the current directory as base path.
/// ///
/// The default extension is `.rhai`.
///
/// # Example /// # Example
/// ///
/// ``` /// ```
@ -159,7 +155,9 @@ impl FileModuleResolver {
self.cache.write().unwrap().clear(); self.cache.write().unwrap().clear();
} }
/// Empty the internal cache. /// Remove the specified path from internal cache.
///
/// The next time this path is resolved, the script file will be loaded once again.
#[inline(always)] #[inline(always)]
pub fn clear_cache_for_path(&mut self, path: impl AsRef<Path>) -> Option<Shared<Module>> { pub fn clear_cache_for_path(&mut self, path: impl AsRef<Path>) -> Option<Shared<Module>> {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]

View File

@ -1,7 +1,7 @@
use crate::stdlib::{boxed::Box, collections::HashMap, ops::AddAssign, string::String}; use crate::stdlib::{boxed::Box, collections::HashMap, ops::AddAssign, string::String};
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
/// Module resolution service that serves modules added into it. /// [Module] resolution service that serves [modules][Module] added into it.
/// ///
/// # Example /// # Example
/// ///
@ -42,13 +42,13 @@ impl StaticModuleResolver {
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
/// Add a module keyed by its path. /// Add a [module][Module] keyed by its path.
#[inline(always)] #[inline(always)]
pub fn insert(&mut self, path: impl Into<String>, mut module: Module) { pub fn insert(&mut self, path: impl Into<String>, mut module: Module) {
module.build_index(); module.build_index();
self.0.insert(path.into(), module.into()); self.0.insert(path.into(), module.into());
} }
/// Remove a module given its path. /// Remove a [module][Module] given its path.
#[inline(always)] #[inline(always)]
pub fn remove(&mut self, path: &str) -> Option<Shared<Module>> { pub fn remove(&mut self, path: &str) -> Option<Shared<Module>> {
self.0.remove(path) self.0.remove(path)
@ -58,12 +58,12 @@ impl StaticModuleResolver {
pub fn contains_path(&self, path: &str) -> bool { pub fn contains_path(&self, path: &str) -> bool {
self.0.contains_key(path) self.0.contains_key(path)
} }
/// Get an iterator of all the modules. /// Get an iterator of all the [modules][Module].
#[inline(always)] #[inline(always)]
pub fn iter(&self) -> impl Iterator<Item = (&str, &Shared<Module>)> { pub fn iter(&self) -> impl Iterator<Item = (&str, &Shared<Module>)> {
self.0.iter().map(|(k, v)| (k.as_str(), v)) self.0.iter().map(|(k, v)| (k.as_str(), v))
} }
/// Get a mutable iterator of all the modules. /// Get a mutable iterator of all the [modules][Module].
#[inline(always)] #[inline(always)]
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &mut Shared<Module>)> { pub fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &mut Shared<Module>)> {
self.0.iter_mut().map(|(k, v)| (k.as_str(), v)) self.0.iter_mut().map(|(k, v)| (k.as_str(), v))
@ -73,17 +73,17 @@ impl StaticModuleResolver {
pub fn into_iter(self) -> impl Iterator<Item = (String, Shared<Module>)> { pub fn into_iter(self) -> impl Iterator<Item = (String, Shared<Module>)> {
self.0.into_iter() self.0.into_iter()
} }
/// Get an iterator of all the module paths. /// Get an iterator of all the [module][Module] paths.
#[inline(always)] #[inline(always)]
pub fn paths(&self) -> impl Iterator<Item = &str> { pub fn paths(&self) -> impl Iterator<Item = &str> {
self.0.keys().map(String::as_str) self.0.keys().map(String::as_str)
} }
/// Get an iterator of all the modules. /// Get an iterator of all the [modules][Module].
#[inline(always)] #[inline(always)]
pub fn values(&self) -> impl Iterator<Item = &Shared<Module>> { pub fn values(&self) -> impl Iterator<Item = &Shared<Module>> {
self.0.values().map(|m| m) self.0.values().map(|m| m)
} }
/// Remove all modules. /// Remove all [modules][Module].
#[inline(always)] #[inline(always)]
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.0.clear(); self.0.clear();
@ -93,7 +93,7 @@ impl StaticModuleResolver {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.is_empty() self.0.is_empty()
} }
/// Get the number of modules in this [`StaticModuleResolver`]. /// Get the number of [modules][Module] in this [`StaticModuleResolver`].
#[inline(always)] #[inline(always)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.0.len() self.0.len()

View File

@ -19,8 +19,6 @@ use crate::utils::get_hasher;
use crate::{calc_native_fn_hash, Dynamic, Engine, Module, Position, Scope, StaticVec, AST}; use crate::{calc_native_fn_hash, Dynamic, Engine, Module, Position, Scope, StaticVec, AST};
/// Level of optimization performed. /// Level of optimization performed.
///
/// Not available under the `no_optimize` feature.
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)] #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
pub enum OptimizationLevel { pub enum OptimizationLevel {
/// No optimization performed. /// No optimization performed.

View File

@ -41,9 +41,9 @@ pub trait Package {
/// Retrieve the generic package library from this package. /// Retrieve the generic package library from this package.
/// ///
/// ## Deprecated /// # Deprecated
/// ///
/// Use `as_shared_module` instead. /// Use [`as_shared_module`][Package::as_shared_module] instead.
#[deprecated = "use `as_shared_module` instead"] #[deprecated = "use `as_shared_module` instead"]
fn get(&self) -> Shared<Module> { fn get(&self) -> Shared<Module> {
self.as_shared_module() self.as_shared_module()

View File

@ -11,7 +11,7 @@ use crate::{EvalAltResult, Position};
/// _(INTERNALS)_ Error encountered when tokenizing the script text. /// _(INTERNALS)_ Error encountered when tokenizing the script text.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Eq, PartialEq, Clone, Hash)] #[derive(Debug, Eq, PartialEq, Clone, Hash)]

View File

@ -173,11 +173,9 @@ impl<'e> ParseState<'e> {
) -> ImmutableString { ) -> ImmutableString {
#[allow(clippy::map_entry)] #[allow(clippy::map_entry)]
if !self.strings.contains_key(text.as_ref()) { if !self.strings.contains_key(text.as_ref()) {
let value: ImmutableString = text.into(); let value = text.into();
let result = value.clone(); self.strings.insert(value.clone().into(), value.clone());
let key = value.to_string(); value
self.strings.insert(key, value);
result
} else { } else {
self.strings.get(text.as_ref()).unwrap().clone() self.strings.get(text.as_ref()).unwrap().clone()
} }

View File

@ -445,7 +445,7 @@ impl<'a> Scope<'a> {
/// let mut my_scope = Scope::new(); /// let mut my_scope = Scope::new();
/// ///
/// my_scope.push("x", 42_i64); /// my_scope.push("x", 42_i64);
/// my_scope.push_constant("foo", "hello".to_string()); /// my_scope.push_constant("foo", "hello");
/// ///
/// let mut iter = my_scope.iter(); /// let mut iter = my_scope.iter();
/// ///

View File

@ -64,7 +64,7 @@ impl Expression<'_> {
impl EvalContext<'_, '_, '_, '_, '_, '_, '_, '_, '_> { impl EvalContext<'_, '_, '_, '_, '_, '_, '_, '_, '_> {
/// Evaluate an [expression tree][Expression]. /// Evaluate an [expression tree][Expression].
/// ///
/// ## WARNING - Low Level API /// # WARNING - Low Level API
/// ///
/// This function is very low level. It evaluates an expression from an [`AST`][crate::AST]. /// This function is very low level. It evaluates an expression from an [`AST`][crate::AST].
#[inline(always)] #[inline(always)]
@ -210,7 +210,7 @@ impl Engine {
} }
/// Register a custom syntax with the [`Engine`]. /// Register a custom syntax with the [`Engine`].
/// ///
/// ## WARNING - Low Level API /// # WARNING - Low Level API
/// ///
/// This function is very low level. /// This function is very low level.
/// ///

View File

@ -149,7 +149,7 @@ impl fmt::Debug for Position {
/// _(INTERNALS)_ A Rhai language token. /// _(INTERNALS)_ A Rhai language token.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -741,7 +741,7 @@ impl From<Token> for String {
/// _(INTERNALS)_ State of the tokenizer. /// _(INTERNALS)_ State of the tokenizer.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[derive(Debug, Clone, Eq, PartialEq, Default)] #[derive(Debug, Clone, Eq, PartialEq, Default)]
@ -763,7 +763,7 @@ pub struct TokenizeState {
/// _(INTERNALS)_ Trait that encapsulates a peekable character input stream. /// _(INTERNALS)_ Trait that encapsulates a peekable character input stream.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This trait is volatile and may change. /// This trait is volatile and may change.
pub trait InputStream { pub trait InputStream {
@ -777,7 +777,7 @@ pub trait InputStream {
/// _(INTERNALS)_ Parse a string literal wrapped by `enclosing_char`. /// _(INTERNALS)_ Parse a string literal wrapped by `enclosing_char`.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
pub fn parse_string_literal( pub fn parse_string_literal(
@ -968,7 +968,7 @@ fn scan_block_comment(
/// _(INTERNALS)_ Get the next token from the `stream`. /// _(INTERNALS)_ Get the next token from the `stream`.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// # WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[inline] #[inline]