Update comments with links.

This commit is contained in:
Stephen Chung 2020-11-20 16:52:28 +08:00
parent 2afcecc6ba
commit 783803ec46
40 changed files with 698 additions and 644 deletions

View File

@ -7,6 +7,8 @@ Version 0.19.6
This version adds the `switch` statement. This version adds the `switch` statement.
It also allows exposing selected module functions (usually methods) to the global namespace. It also allows exposing selected module functions (usually methods) to the global namespace.
This is very convenient when encapsulating the API of a custom Rust type into a module while having methods
and iterators registered on the custom type work normally.
Breaking changes Breaking changes
---------------- ----------------
@ -26,7 +28,7 @@ New features
Enhancements Enhancements
------------ ------------
* New constant `Dynamic::UNIT`. * New constants under `Dynamic` including `UNIT`, `TRUE`, `FALSE`, `ZERO`, `ONE` etc.
Version 0.19.5 Version 0.19.5

View File

@ -296,7 +296,7 @@ engine.register_custom_syntax_raw(
"cleanup" => Ok(None), "cleanup" => Ok(None),
cmd => Err(ParseError(Box::new(ParseErrorType::BadInput( cmd => Err(ParseError(Box::new(ParseErrorType::BadInput(
LexError::ImproperSymbol(format!("Improper command: {}", cmd)) LexError::ImproperSymbol(format!("Improper command: {}", cmd))
)), NO_POS)), )), Position::NONE)),
}, },
// perform command arg ... // perform command arg ...
3 => match (stream[1].as_str(), stream[2].as_str()) { 3 => match (stream[1].as_str(), stream[2].as_str()) {
@ -311,7 +311,7 @@ engine.register_custom_syntax_raw(
LexError::ImproperSymbol( LexError::ImproperSymbol(
format!("Invalid argument for command {}: {}", cmd, arg) format!("Invalid argument for command {}: {}", cmd, arg)
) )
)), NO_POS)), )), Position::NONE)),
}, },
_ => unreachable!(), _ => unreachable!(),
}, },
@ -336,8 +336,8 @@ where:
The return value is `Result<Option<String>, ParseError>` where: The return value is `Result<Option<String>, ParseError>` where:
| Value | Description | | Value | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Ok(None)` | parsing complete and there are no more symbols to match | | `Ok(None)` | parsing complete and there are no more symbols to match |
| `Ok(Some(symbol))` | next symbol to match, which can also be `"$expr$"`, `"$ident$"` or `"$block$"` | | `Ok(Some(symbol))` | next symbol to match, which can also be `"$expr$"`, `"$ident$"` or `"$block$"` |
| `Err(ParseError)` | error that is reflected back to the [`Engine`].<br/>Normally this is `ParseError(ParseErrorType::BadInput(LexError::ImproperSymbol(message)), NO_POS)` to indicate that there is a syntax error, but it can be any `ParseError`. | | `Err(ParseError)` | error that is reflected back to the [`Engine`].<br/>Normally this is `ParseError(ParseErrorType::BadInput(LexError::ImproperSymbol(message)), Position::NONE)` to indicate that there is a syntax error, but it can be any `ParseError`. |

View File

@ -21,11 +21,11 @@ engine.on_var(|name, index, context| {
"MYSTIC_NUMBER" => Ok(Some((42 as INT).into())), "MYSTIC_NUMBER" => Ok(Some((42 as INT).into())),
// Override a variable - make it not found even if it exists! // Override a variable - make it not found even if it exists!
"DO_NOT_USE" => Err(Box::new( "DO_NOT_USE" => Err(Box::new(
EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS) EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE)
)), )),
// Silently maps 'chameleon' into 'innocent'. // Silently maps 'chameleon' into 'innocent'.
"chameleon" => context.scope.get_value("innocent").map(Some).ok_or_else(|| Box::new( "chameleon" => context.scope.get_value("innocent").map(Some).ok_or_else(|| Box::new(
EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS) EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE)
)), )),
// Return Ok(None) to continue with the normal variable resolution process. // Return Ok(None) to continue with the normal variable resolution process.
_ => Ok(None) _ => Ok(None)
@ -83,8 +83,8 @@ where:
The return value is `Result<Option<Dynamic>, Box<EvalAltResult>>` where: The return value is `Result<Option<Dynamic>, Box<EvalAltResult>>` where:
| Value | Description | | Value | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Ok(None)` | normal variable resolution process should continue, i.e. continue searching through the [`Scope`] | | `Ok(None)` | normal variable resolution process should continue, i.e. continue searching through the [`Scope`] |
| `Ok(Some(Dynamic))` | value of the variable, treated as a constant | | `Ok(Some(Dynamic))` | value of the variable, treated as a constant |
| `Err(Box<EvalAltResult>)` | error that is reflected back to the [`Engine`].<br/>Normally this is `EvalAltResult::ErrorVariableNotFound(var_name, NO_POS)` to indicate that the variable does not exist, but it can be any `EvalAltResult`. | | `Err(Box<EvalAltResult>)` | error that is reflected back to the [`Engine`].<br/>Normally this is `EvalAltResult::ErrorVariableNotFound(var_name, Position::NONE)` to indicate that the variable does not exist, but it can be any `EvalAltResult`. |

View File

@ -118,7 +118,7 @@ pub fn greet(context: NativeCallContext, callback: FnPtr)
The native call context is also useful in another scenario: protecting a function from malicious scripts. The native call context is also useful in another scenario: protecting a function from malicious scripts.
```rust ```rust
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, NO_POS}; use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
use rhai::plugin::*; // a "prelude" import for macros use rhai::plugin::*; // a "prelude" import for macros
// This function builds an array of arbitrary size, but is protected // This function builds an array of arbitrary size, but is protected
@ -138,7 +138,7 @@ pub fn grow(context: NativeCallContext, size: i64)
"Size to grow".to_string(), "Size to grow".to_string(),
context.engine().max_array_size(), context.engine().max_array_size(),
size as usize, size as usize,
NO_POS, Position::NONE,
).into(); ).into();
} }

View File

@ -428,7 +428,7 @@ mod my_module {
The native call context is also useful in another scenario: protecting a function from malicious scripts. The native call context is also useful in another scenario: protecting a function from malicious scripts.
```rust ```rust
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, NO_POS}; use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
use rhai::plugin::*; // a "prelude" import for macros use rhai::plugin::*; // a "prelude" import for macros
#[export_module] #[export_module]
@ -449,7 +449,7 @@ mod my_module {
"Size to grow".to_string(), "Size to grow".to_string(),
context.engine().max_array_size(), context.engine().max_array_size(),
size as usize, size as usize,
NO_POS, Position::NONE,
).into(); ).into();
} }

View File

@ -19,7 +19,7 @@ use crate::syntax::FnCustomSyntaxEval;
use crate::token::Token; use crate::token::Token;
use crate::utils::StraightHasherBuilder; use crate::utils::StraightHasherBuilder;
use crate::{ use crate::{
Dynamic, FnNamespace, FnPtr, ImmutableString, Module, Position, Shared, StaticVec, INT, NO_POS, Dynamic, FnNamespace, FnPtr, ImmutableString, Module, Position, Shared, StaticVec, INT,
}; };
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
@ -59,7 +59,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
@ -109,7 +109,7 @@ impl fmt::Display for ScriptFnDef {
/// ///
/// # Thread Safety /// # Thread Safety
/// ///
/// Currently, `AST` is neither `Send` nor `Sync`. Turn on the `sync` feature to make it `Send + Sync`. /// Currently, [`AST`] is neither `Send` nor `Sync`. Turn on the `sync` feature to make it `Send + Sync`.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AST( pub struct AST(
/// Global statements. /// Global statements.
@ -125,7 +125,7 @@ impl Default for AST {
} }
impl AST { impl AST {
/// Create a new `AST`. /// Create a new [`AST`].
#[inline(always)] #[inline(always)]
pub fn new(statements: impl IntoIterator<Item = Stmt>, lib: impl Into<Shared<Module>>) -> Self { pub fn new(statements: impl IntoIterator<Item = Stmt>, lib: impl Into<Shared<Module>>) -> Self {
Self(statements.into_iter().collect(), lib.into()) Self(statements.into_iter().collect(), lib.into())
@ -136,7 +136,7 @@ impl AST {
pub(crate) fn statements(&self) -> &[Stmt] { pub(crate) fn statements(&self) -> &[Stmt] {
&self.0 &self.0
} }
/// _[INTERNALS]_ Get the statements. /// _(INTERNALS)_ Get the statements.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated(note = "this method is volatile and may change")] #[deprecated(note = "this method is volatile and may change")]
@ -150,18 +150,18 @@ impl AST {
pub(crate) fn statements_mut(&mut self) -> &mut Vec<Stmt> { pub(crate) fn statements_mut(&mut self) -> &mut Vec<Stmt> {
&mut self.0 &mut self.0
} }
/// Get the internal shared `Module` containing all script-defined functions. /// Get the internal shared [`Module`] containing all script-defined functions.
#[inline(always)] #[inline(always)]
pub(crate) fn shared_lib(&self) -> Shared<Module> { pub(crate) fn shared_lib(&self) -> Shared<Module> {
self.1.clone() self.1.clone()
} }
/// Get the internal `Module` containing all script-defined functions. /// Get the internal [`Module`] containing all script-defined functions.
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
#[inline(always)] #[inline(always)]
pub(crate) fn lib(&self) -> &Module { pub(crate) fn lib(&self) -> &Module {
&self.1 &self.1
} }
/// _[INTERNALS]_ Get the internal `Module` containing all script-defined functions. /// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated(note = "this method is volatile and may change")] #[deprecated(note = "this method is volatile and may change")]
@ -169,7 +169,7 @@ impl AST {
pub fn lib(&self) -> &Module { pub fn lib(&self) -> &Module {
&self.1 &self.1
} }
/// Clone the `AST`'s functions into a new `AST`. /// Clone the [`AST`]'s functions into a new [`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.
@ -178,7 +178,7 @@ impl AST {
pub fn clone_functions_only(&self) -> Self { pub fn clone_functions_only(&self) -> Self {
self.clone_functions_only_filtered(|_, _, _, _, _| true) self.clone_functions_only_filtered(|_, _, _, _, _| true)
} }
/// Clone the `AST`'s functions into a new `AST` based on a filter predicate. /// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate.
/// No statements are cloned. /// No statements are cloned.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
@ -192,22 +192,22 @@ impl AST {
functions.merge_filtered(&self.1, &mut filter); functions.merge_filtered(&self.1, &mut filter);
Self(Default::default(), functions.into()) Self(Default::default(), functions.into())
} }
/// Clone the `AST`'s script statements into a new `AST`. /// Clone the [`AST`]'s script statements into a new [`AST`].
/// No functions are cloned. /// No functions are cloned.
#[inline(always)] #[inline(always)]
pub fn clone_statements_only(&self) -> Self { pub fn clone_statements_only(&self) -> Self {
Self(self.0.clone(), Default::default()) Self(self.0.clone(), Default::default())
} }
/// Merge two `AST` into one. Both `AST`'s are untouched and a new, merged, version /// Merge two [`AST`] into one. Both [`AST`]'s are untouched and a new, merged, version
/// is returned. /// is returned.
/// ///
/// Statements in the second `AST` are simply appended to the end of the first _without any processing_. /// Statements in the second [`AST`] are simply appended to the end of the first _without any processing_.
/// Thus, the return value of the first `AST` (if using expression-statement syntax) is buried. /// Thus, the return value of the first [`AST`] (if using expression-statement syntax) is buried.
/// Of course, if the first `AST` uses a `return` statement at the end, then /// Of course, if the first [`AST`] uses a `return` statement at the end, then
/// the second `AST` will essentially be dead code. /// the second [`AST`] will essentially be dead code.
/// ///
/// All script-defined functions in the second `AST` overwrite similarly-named functions /// All script-defined functions in the second [`AST`] overwrite similarly-named functions
/// in the first `AST` with the same number of parameters. /// in the first [`AST`] with the same number of parameters.
/// ///
/// # Example /// # Example
/// ///
@ -251,15 +251,15 @@ impl AST {
pub fn merge(&self, other: &Self) -> Self { pub fn merge(&self, other: &Self) -> Self {
self.merge_filtered(other, |_, _, _, _, _| true) self.merge_filtered(other, |_, _, _, _, _| true)
} }
/// Combine one `AST` with another. The second `AST` is consumed. /// Combine one [`AST`] with another. The second [`AST`] is consumed.
/// ///
/// Statements in the second `AST` are simply appended to the end of the first _without any processing_. /// Statements in the second [`AST`] are simply appended to the end of the first _without any processing_.
/// Thus, the return value of the first `AST` (if using expression-statement syntax) is buried. /// Thus, the return value of the first [`AST`] (if using expression-statement syntax) is buried.
/// Of course, if the first `AST` uses a `return` statement at the end, then /// Of course, if the first [`AST`] uses a `return` statement at the end, then
/// the second `AST` will essentially be dead code. /// the second [`AST`] will essentially be dead code.
/// ///
/// All script-defined functions in the second `AST` overwrite similarly-named functions /// All script-defined functions in the second [`AST`] overwrite similarly-named functions
/// in the first `AST` with the same number of parameters. /// in the first [`AST`] with the same number of parameters.
/// ///
/// # Example /// # Example
/// ///
@ -303,16 +303,16 @@ impl AST {
pub fn combine(&mut self, other: Self) -> &mut Self { pub fn combine(&mut self, other: Self) -> &mut Self {
self.combine_filtered(other, |_, _, _, _, _| true) self.combine_filtered(other, |_, _, _, _, _| true)
} }
/// Merge two `AST` into one. Both `AST`'s are untouched and a new, merged, version /// Merge two [`AST`] into one. Both [`AST`]'s are untouched and a new, merged, version
/// is returned. /// is returned.
/// ///
/// Statements in the second `AST` are simply appended to the end of the first _without any processing_. /// Statements in the second [`AST`] are simply appended to the end of the first _without any processing_.
/// Thus, the return value of the first `AST` (if using expression-statement syntax) is buried. /// Thus, the return value of the first [`AST`] (if using expression-statement syntax) is buried.
/// Of course, if the first `AST` uses a `return` statement at the end, then /// Of course, if the first [`AST`] uses a `return` statement at the end, then
/// the second `AST` will essentially be dead code. /// the second [`AST`] will essentially be dead code.
/// ///
/// All script-defined functions in the second `AST` are first selected based on a filter /// All script-defined functions in the second [`AST`] are first selected based on a filter
/// predicate, then overwrite similarly-named functions in the first `AST` with the /// predicate, then overwrite similarly-named functions in the first [`AST`] with the
/// same number of parameters. /// same number of parameters.
/// ///
/// # Example /// # Example
@ -379,15 +379,15 @@ impl AST {
Self::new(ast, functions) Self::new(ast, functions)
} }
/// Combine one `AST` with another. The second `AST` is consumed. /// Combine one [`AST`] with another. The second [`AST`] is consumed.
/// ///
/// Statements in the second `AST` are simply appended to the end of the first _without any processing_. /// Statements in the second [`AST`] are simply appended to the end of the first _without any processing_.
/// Thus, the return value of the first `AST` (if using expression-statement syntax) is buried. /// Thus, the return value of the first [`AST`] (if using expression-statement syntax) is buried.
/// Of course, if the first `AST` uses a `return` statement at the end, then /// Of course, if the first [`AST`] uses a `return` statement at the end, then
/// the second `AST` will essentially be dead code. /// the second [`AST`] will essentially be dead code.
/// ///
/// All script-defined functions in the second `AST` are first selected based on a filter /// All script-defined functions in the second [`AST`] are first selected based on a filter
/// predicate, then overwrite similarly-named functions in the first `AST` with the /// predicate, then overwrite similarly-named functions in the first [`AST`] with the
/// same number of parameters. /// same number of parameters.
/// ///
/// # Example /// # Example
@ -484,13 +484,13 @@ impl AST {
) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a { ) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a {
self.1.iter_script_fn() self.1.iter_script_fn()
} }
/// Clear all function definitions in the `AST`. /// Clear all function definitions in the [`AST`].
#[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) {
self.1 = Default::default(); self.1 = Default::default();
} }
/// Clear all statements in the `AST`, leaving only function definitions. /// Clear all statements in the [`AST`], leaving only function definitions.
#[inline(always)] #[inline(always)]
pub fn clear_statements(&mut self) { pub fn clear_statements(&mut self) {
self.0 = vec![]; self.0 = vec![];
@ -567,7 +567,7 @@ impl IdentX {
} }
} }
/// _[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
@ -581,7 +581,7 @@ pub enum ReturnType {
Exception, Exception,
} }
/// _[INTERNALS]_ A statement. /// _(INTERNALS)_ A statement.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -591,42 +591,42 @@ pub enum ReturnType {
pub enum Stmt { pub enum Stmt {
/// No-op. /// No-op.
Noop(Position), Noop(Position),
/// if expr { stmt } else { stmt } /// `if` expr `{` stmt `}` `else` `{` stmt `}`
If(Expr, Box<(Stmt, Option<Stmt>)>, Position), If(Expr, Box<(Stmt, Option<Stmt>)>, Position),
/// switch expr { literal or _ => stmt, ... } /// `switch` expr `{` literal or _ `=>` stmt `,` ... `}`
Switch( Switch(
Expr, Expr,
Box<(HashMap<u64, Stmt, StraightHasherBuilder>, Option<Stmt>)>, Box<(HashMap<u64, Stmt, StraightHasherBuilder>, Option<Stmt>)>,
Position, Position,
), ),
/// while expr { stmt } /// `while` expr `{` stmt `}`
While(Expr, Box<Stmt>, Position), While(Expr, Box<Stmt>, Position),
/// loop { stmt } /// `loop` `{` stmt `}`
Loop(Box<Stmt>, Position), Loop(Box<Stmt>, Position),
/// for id in expr { stmt } /// `for` id `in` expr `{` stmt `}`
For(Expr, Box<(String, Stmt)>, Position), For(Expr, Box<(String, Stmt)>, Position),
/// [export] let id = expr /// \[`export`\] `let` id `=` expr
Let(Box<Ident>, Option<Expr>, bool, Position), Let(Box<Ident>, Option<Expr>, bool, Position),
/// [export] const id = expr /// \[`export`\] `const` id `=` expr
Const(Box<Ident>, Option<Expr>, bool, Position), Const(Box<Ident>, Option<Expr>, bool, Position),
/// expr op= expr /// expr op`=` expr
Assignment(Box<(Expr, Cow<'static, str>, Expr)>, Position), Assignment(Box<(Expr, Cow<'static, str>, Expr)>, Position),
/// { stmt; ... } /// `{` stmt`;` ... `}`
Block(Vec<Stmt>, Position), Block(Vec<Stmt>, Position),
/// try { stmt; ... } catch ( var ) { stmt; ... } /// `try` `{` stmt; ... `}` `catch` `(` var `)` `{` stmt; ... `}`
TryCatch(Box<(Stmt, Option<Ident>, Stmt)>, Position, Position), TryCatch(Box<(Stmt, Option<Ident>, Stmt)>, Position, Position),
/// expr /// [expression][Expr]
Expr(Expr), Expr(Expr),
/// continue /// `continue`
Continue(Position), Continue(Position),
/// break /// `break`
Break(Position), Break(Position),
/// return/throw /// `return`/`throw`
Return((ReturnType, Position), Option<Expr>, Position), Return((ReturnType, Position), Option<Expr>, Position),
/// import expr as var /// `import` expr `as` var
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
Import(Expr, Option<Box<IdentX>>, Position), Import(Expr, Option<Box<IdentX>>, Position),
/// export var as var, ... /// `export` var `as` var `,` ...
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
Export(Vec<(IdentX, Option<IdentX>)>, Position), Export(Vec<(IdentX, Option<IdentX>)>, Position),
/// Convert a variable to shared. /// Convert a variable to shared.
@ -637,19 +637,19 @@ pub enum Stmt {
impl Default for Stmt { impl Default for Stmt {
#[inline(always)] #[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::Noop(NO_POS) Self::Noop(Position::NONE)
} }
} }
impl Stmt { impl Stmt {
/// Is this statement `Noop`? /// Is this statement [`Noop`][Stmt::Noop]?
pub fn is_noop(&self) -> bool { pub fn is_noop(&self) -> bool {
match self { match self {
Self::Noop(_) => true, Self::Noop(_) => true,
_ => false, _ => false,
} }
} }
/// Get the `Position` of this statement. /// Get the [`Position`] of this statement.
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
Self::Noop(pos) Self::Noop(pos)
@ -678,7 +678,7 @@ impl Stmt {
Self::Share(x) => x.pos, Self::Share(x) => x.pos,
} }
} }
/// Override the `Position` of this statement. /// Override the [`Position`] of this statement.
pub fn set_position(&mut self, new_pos: Position) -> &mut Self { pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
match self { match self {
Self::Noop(pos) Self::Noop(pos)
@ -774,7 +774,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
@ -796,19 +796,19 @@ impl fmt::Debug for CustomExpr {
} }
impl CustomExpr { impl CustomExpr {
/// Get the keywords for this `CustomExpr`. /// Get the keywords for this custom syntax.
#[inline(always)] #[inline(always)]
pub fn keywords(&self) -> &[Expr] { pub fn keywords(&self) -> &[Expr] {
&self.keywords &self.keywords
} }
/// Get the implementation function for this `CustomExpr`. /// Get the implementation function for this custom syntax.
#[inline(always)] #[inline(always)]
pub fn func(&self) -> &FnCustomSyntaxEval { pub fn func(&self) -> &FnCustomSyntaxEval {
self.func.as_ref() self.func.as_ref()
} }
} }
/// _[INTERNALS]_ A binary expression. /// _(INTERNALS)_ A binary expression.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -822,7 +822,7 @@ pub struct BinaryExpr {
pub rhs: Expr, pub rhs: Expr,
} }
/// _[INTERNALS]_ A function call. /// _(INTERNALS)_ A function call.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -832,25 +832,24 @@ pub struct BinaryExpr {
pub struct FnCallExpr { pub struct FnCallExpr {
/// Pre-calculated hash for a script-defined function of the same name and number of parameters. /// Pre-calculated hash for a script-defined function of the same name and number of parameters.
pub hash: u64, pub hash: u64,
/// Call native functions only? Set to `true` to skip searching for script-defined function overrides /// Call native functions only? Set to [`true`] to skip searching for script-defined function overrides
/// when it is certain that the function must be native (e.g. an operator). /// when it is certain that the function must be native (e.g. an operator).
pub native_only: bool, pub native_only: bool,
/// Does this function call capture the parent scope? /// Does this function call capture the parent scope?
pub capture: bool, pub capture: bool,
/// Default value when the function is not found, mostly used to provide a default for comparison functions. /// Default value when the function is not found, mostly used to provide a default for comparison functions.
/// Type is `bool` in order for `FnCallInfo` to be `Hash` pub def_value: Option<Dynamic>,
pub def_value: Option<bool>,
/// Namespace of the function, if any. Boxed because it occurs rarely. /// Namespace of the function, if any. Boxed because it occurs rarely.
pub namespace: Option<Box<NamespaceRef>>, pub namespace: Option<Box<NamespaceRef>>,
/// Function name. /// Function name.
/// Use `Cow<'static, str>` because a lot of operators (e.g. `==`, `>=`) are implemented as function calls /// Use [`Cow<'static, str>`][Cow] because a lot of operators (e.g. `==`, `>=`) are implemented as
/// and the function names are predictable, so no need to allocate a new `String`. /// function calls and the function names are predictable, so no need to allocate a new [`String`].
pub name: Cow<'static, str>, pub name: Cow<'static, str>,
/// List of function call arguments. /// List of function call arguments.
pub args: StaticVec<Expr>, pub args: StaticVec<Expr>,
} }
/// _[INTERNALS]_ An expression sub-tree. /// _(INTERNALS)_ An expression sub-tree.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -859,7 +858,7 @@ pub struct FnCallExpr {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Expr { pub enum Expr {
/// Dynamic constant. /// Dynamic constant.
/// Used to hold either an Array or Map literal for quick cloning. /// Used to hold either an [`Array`] or [`Map`] literal for quick cloning.
/// All other primitive data types should use the appropriate variants for better speed. /// All other primitive data types should use the appropriate variants for better speed.
DynamicConstant(Box<Dynamic>, Position), DynamicConstant(Box<Dynamic>, Position),
/// Boolean constant. /// Boolean constant.
@ -871,9 +870,9 @@ pub enum Expr {
FloatConstant(FLOAT, Position), FloatConstant(FLOAT, Position),
/// Character constant. /// Character constant.
CharConstant(char, Position), CharConstant(char, Position),
/// String constant. /// [String][ImmutableString] constant.
StringConstant(ImmutableString, Position), StringConstant(ImmutableString, Position),
/// FnPtr constant. /// [`FnPtr`] constant.
FnPointer(ImmutableString, Position), FnPointer(ImmutableString, Position),
/// [ expr, ... ] /// [ expr, ... ]
Array(Box<StaticVec<Expr>>, Position), Array(Box<StaticVec<Expr>>, Position),
@ -885,21 +884,21 @@ pub enum Expr {
Variable(Box<(Option<NonZeroUsize>, Option<Box<NamespaceRef>>, u64, IdentX)>), Variable(Box<(Option<NonZeroUsize>, Option<Box<NamespaceRef>>, u64, IdentX)>),
/// Property access - (getter, setter), prop /// Property access - (getter, setter), prop
Property(Box<((ImmutableString, ImmutableString), IdentX)>), Property(Box<((ImmutableString, ImmutableString), IdentX)>),
/// { stmt } /// { [statement][Stmt] }
Stmt(Box<StaticVec<Stmt>>, Position), Stmt(Box<StaticVec<Stmt>>, Position),
/// Wrapped expression - should not be optimized away. /// Wrapped [expression][`Expr`] - should not be optimized away.
Expr(Box<Expr>), Expr(Box<Expr>),
/// func(expr, ... ) /// func `(` expr `,` ... `)`
FnCall(Box<FnCallExpr>, Position), FnCall(Box<FnCallExpr>, Position),
/// lhs.rhs /// lhs `.` rhs
Dot(Box<BinaryExpr>, Position), Dot(Box<BinaryExpr>, Position),
/// expr[expr] /// expr `[` expr `]`
Index(Box<BinaryExpr>, Position), Index(Box<BinaryExpr>, Position),
/// lhs in rhs /// lhs `in` rhs
In(Box<BinaryExpr>, Position), In(Box<BinaryExpr>, Position),
/// lhs && rhs /// lhs `&&` rhs
And(Box<BinaryExpr>, Position), And(Box<BinaryExpr>, Position),
/// lhs || rhs /// lhs `||` rhs
Or(Box<BinaryExpr>, Position), Or(Box<BinaryExpr>, Position),
/// Custom syntax /// Custom syntax
Custom(Box<CustomExpr>, Position), Custom(Box<CustomExpr>, Position),
@ -908,14 +907,14 @@ pub enum Expr {
impl Default for Expr { impl Default for Expr {
#[inline(always)] #[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::Unit(NO_POS) Self::Unit(Position::NONE)
} }
} }
impl Expr { impl Expr {
/// Get the `Dynamic` value of a constant expression. /// Get the [`Dynamic`] value of a constant expression.
/// ///
/// Returns `None` if the expression is not constant. /// Returns [`None`] if the expression is not constant.
pub fn get_constant_value(&self) -> Option<Dynamic> { pub fn get_constant_value(&self) -> Option<Dynamic> {
Some(match self { Some(match self {
Self::Expr(x) => return x.get_constant_value(), Self::Expr(x) => return x.get_constant_value(),
@ -966,7 +965,7 @@ impl Expr {
_ => None, _ => None,
} }
} }
/// Get the `Position` of the expression. /// Get the [`Position`] of the expression.
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
Self::Expr(x) => x.position(), Self::Expr(x) => x.position(),
@ -996,7 +995,7 @@ impl Expr {
Self::Custom(_, pos) => *pos, Self::Custom(_, pos) => *pos,
} }
} }
/// Override the `Position` of the expression. /// Override the [`Position`] of the expression.
pub fn set_position(&mut self, new_pos: Position) -> &mut Self { pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
match self { match self {
Self::Expr(x) => { Self::Expr(x) => {

View File

@ -1,4 +1,4 @@
//! Helper module which defines the `Any` trait to to allow dynamic value handling. //! Helper module which defines the [`Any`] trait to to allow dynamic value handling.
use crate::fn_native::SendSync; use crate::fn_native::SendSync;
use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast}; use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast};
@ -35,8 +35,6 @@ mod private {
use crate::stdlib::any::Any; use crate::stdlib::any::Any;
/// A sealed trait that prevents other crates from implementing [`Variant`]. /// A sealed trait that prevents other crates from implementing [`Variant`].
///
/// [`Variant`]: super::Variant
pub trait Sealed {} pub trait Sealed {}
impl<T: Any + Clone + SendSync> Sealed for T {} impl<T: Any + Clone + SendSync> Sealed for T {}
@ -44,51 +42,48 @@ mod private {
/// Trait to represent any type. /// Trait to represent any type.
/// ///
/// Currently, `Variant` is not `Send` nor `Sync`, so it can practically be any type. /// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type.
/// Turn on the `sync` feature to restrict it to only types that implement `Send + Sync`. /// Turn on the [`Sync`] feature to restrict it to only types that implement [`Send`] `+` [`Sync`].
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub trait Variant: Any + private::Sealed { pub trait Variant: Any + private::Sealed {
/// Convert this `Variant` trait object to `&dyn Any`. /// Convert this [`Variant`] trait object to [`&dyn Any`][Any].
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
/// Convert this `Variant` trait object to `&mut dyn Any`. /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any].
fn as_mut_any(&mut self) -> &mut dyn Any; fn as_mut_any(&mut self) -> &mut dyn Any;
/// Convert this `Variant` trait object to an `Any` trait object. /// Convert this [`Variant`] trait object to an [`Any`] trait object.
fn as_box_any(self: Box<Self>) -> Box<dyn Any>; fn as_box_any(self: Box<Self>) -> Box<dyn Any>;
/// Get the name of this type. /// Get the name of this type.
fn type_name(&self) -> &'static str; fn type_name(&self) -> &'static str;
/// Convert into `Dynamic`. /// Convert into [`Dynamic`].
fn into_dynamic(self) -> Dynamic; fn into_dynamic(self) -> Dynamic;
/// Clone into `Dynamic`. /// Clone into [`Dynamic`].
fn clone_into_dynamic(&self) -> Dynamic; fn clone_into_dynamic(&self) -> Dynamic;
} }
/// Trait to represent any type. /// Trait to represent any type.
///
/// `From<_>` is implemented for `i64` (`i32` if `only_i32`), `f64` (if not `no_float`),
/// `bool`, `String`, `char`, `Vec<T>` (into `Array`) and `HashMap<String, T>` (into `Map`).
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub trait Variant: Any + Send + Sync + private::Sealed { pub trait Variant: Any + Send + Sync + private::Sealed {
/// Convert this `Variant` trait object to `&dyn Any`. /// Convert this [`Variant`] trait object to [`&dyn Any`][Any].
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
/// Convert this `Variant` trait object to `&mut dyn Any`. /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any].
fn as_mut_any(&mut self) -> &mut dyn Any; fn as_mut_any(&mut self) -> &mut dyn Any;
/// Convert this `Variant` trait object to an `Any` trait object. /// Convert this [`Variant`] trait object to an [`Any`] trait object.
fn as_box_any(self: Box<Self>) -> Box<dyn Any>; fn as_box_any(self: Box<Self>) -> Box<dyn Any>;
/// Get the name of this type. /// Get the name of this type.
fn type_name(&self) -> &'static str; fn type_name(&self) -> &'static str;
/// Convert into `Dynamic`. /// Convert into [`Dynamic`].
fn into_dynamic(self) -> Dynamic; fn into_dynamic(self) -> Dynamic;
/// Clone into `Dynamic`. /// Clone into [`Dynamic`].
fn clone_into_dynamic(&self) -> Dynamic; fn clone_into_dynamic(&self) -> Dynamic;
} }
@ -114,7 +109,7 @@ impl<T: Any + Clone + SendSync> Variant for T {
} }
impl dyn Variant { impl dyn Variant {
/// Is this `Variant` a specific type? /// Is this [`Variant`] a specific type?
#[inline(always)] #[inline(always)]
pub fn is<T: Any>(&self) -> bool { pub fn is<T: Any>(&self) -> bool {
TypeId::of::<T>() == self.type_id() TypeId::of::<T>() == self.type_id()
@ -124,7 +119,7 @@ impl dyn Variant {
/// Dynamic type containing any value. /// Dynamic type containing any value.
pub struct Dynamic(pub(crate) Union); pub struct Dynamic(pub(crate) Union);
/// Internal `Dynamic` representation. /// Internal [`Dynamic`] representation.
/// ///
/// Most variants are boxed to reduce the size. /// Most variants are boxed to reduce the size.
pub enum Union { pub enum Union {
@ -149,14 +144,14 @@ pub enum Union {
Shared(crate::Shared<crate::Locked<Dynamic>>), Shared(crate::Shared<crate::Locked<Dynamic>>),
} }
/// Underlying `Variant` read guard for `Dynamic`. /// Underlying [`Variant`] read guard for [`Dynamic`].
/// ///
/// This data structure provides transparent interoperability between /// This data structure provides transparent interoperability between
/// normal `Dynamic` and shared Dynamic values. /// normal [`Dynamic`] and shared [`Dynamic`] values.
#[derive(Debug)] #[derive(Debug)]
pub struct DynamicReadLock<'d, T: Variant + Clone>(DynamicReadLockInner<'d, T>); pub struct DynamicReadLock<'d, T: Variant + Clone>(DynamicReadLockInner<'d, T>);
/// Different types of read guards for `DynamicReadLock`. /// Different types of read guards for [`DynamicReadLock`].
#[derive(Debug)] #[derive(Debug)]
enum DynamicReadLockInner<'d, T: Variant + Clone> { enum DynamicReadLockInner<'d, T: Variant + Clone> {
/// A simple reference to a non-shared value. /// A simple reference to a non-shared value.
@ -166,7 +161,7 @@ enum DynamicReadLockInner<'d, T: Variant + Clone> {
#[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>),
/// A read guard to a shared `RwLock`. /// A read guard to a shared [`RwLock`][std::sync::RwLock].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Guard(crate::stdlib::sync::RwLockReadGuard<'d, Dynamic>), Guard(crate::stdlib::sync::RwLockReadGuard<'d, Dynamic>),
@ -186,14 +181,14 @@ impl<'d, T: Variant + Clone> Deref for DynamicReadLock<'d, T> {
} }
} }
/// Underlying `Variant` write guard for `Dynamic`. /// Underlying [`Variant`] write guard for [`Dynamic`].
/// ///
/// This data structure provides transparent interoperability between /// This data structure provides transparent interoperability between
/// normal `Dynamic` and shared Dynamic values. /// normal [`Dynamic`] and shared [`Dynamic`] values.
#[derive(Debug)] #[derive(Debug)]
pub struct DynamicWriteLock<'d, T: Variant + Clone>(DynamicWriteLockInner<'d, T>); pub struct DynamicWriteLock<'d, T: Variant + Clone>(DynamicWriteLockInner<'d, T>);
/// Different types of write guards for `DynamicReadLock`. /// Different types of write guards for [`DynamicReadLock`].
#[derive(Debug)] #[derive(Debug)]
enum DynamicWriteLockInner<'d, T: Variant + Clone> { enum DynamicWriteLockInner<'d, T: Variant + Clone> {
/// A simple mutable reference to a non-shared value. /// A simple mutable reference to a non-shared value.
@ -203,7 +198,7 @@ enum DynamicWriteLockInner<'d, T: Variant + Clone> {
#[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>),
/// A write guard to a shared `RwLock`. /// A write guard to a shared [`RwLock`][std::sync::RwLock].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Guard(crate::stdlib::sync::RwLockWriteGuard<'d, Dynamic>), Guard(crate::stdlib::sync::RwLockWriteGuard<'d, Dynamic>),
@ -236,7 +231,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 support system primitive types?
#[inline(always)] #[inline(always)]
pub fn is_variant(&self) -> bool { pub fn is_variant(&self) -> bool {
@ -245,7 +240,7 @@ impl Dynamic {
_ => false, _ => false,
} }
} }
/// Does this `Dynamic` hold a shared data type /// Does this [`Dynamic`] hold a shared data type
/// instead of one of the supported system primitive types? /// 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 {
@ -255,9 +250,9 @@ impl Dynamic {
_ => false, _ => false,
} }
} }
/// 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 it's internal value.
#[inline(always)] #[inline(always)]
pub fn is<T: Variant + Clone>(&self) -> bool { pub fn is<T: Variant + Clone>(&self) -> bool {
@ -269,11 +264,11 @@ impl Dynamic {
self.type_id() == target_type_id self.type_id() == target_type_id
} }
/// Get the TypeId of the value held by this `Dynamic`. /// Get the [`TypeId`] of the value held by this [`Dynamic`].
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
pub fn type_id(&self) -> TypeId { pub fn type_id(&self) -> TypeId {
match &self.0 { match &self.0 {
@ -302,11 +297,11 @@ impl Dynamic {
Union::Shared(cell) => (*cell.read().unwrap()).type_id(), Union::Shared(cell) => (*cell.read().unwrap()).type_id(),
} }
} }
/// Get the name of the type of the value held by this `Dynamic`. /// Get the name of the type of the value held by this [`Dynamic`].
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
pub fn type_name(&self) -> &'static str { pub fn type_name(&self) -> &'static str {
match &self.0 { match &self.0 {
@ -518,29 +513,29 @@ impl Default for Dynamic {
} }
impl Dynamic { impl Dynamic {
/// A `Dynamic` containing a `()`. /// A [`Dynamic`] containing a `()`.
pub const UNIT: Dynamic = Self(Union::Unit(())); pub const UNIT: Dynamic = Self(Union::Unit(()));
/// A `Dynamic` containing a `true`. /// A [`Dynamic`] containing a `true`.
pub const TRUE: Dynamic = Self(Union::Bool(true)); pub const TRUE: Dynamic = Self(Union::Bool(true));
/// A `Dynamic` containing a `false`. /// A [`Dynamic`] containing a [`false`].
pub const FALSE: Dynamic = Self(Union::Bool(false)); pub const FALSE: Dynamic = Self(Union::Bool(false));
/// A `Dynamic` containing the integer zero. /// A [`Dynamic`] containing the integer zero.
pub const ZERO: Dynamic = Self(Union::Int(0)); pub const ZERO: Dynamic = Self(Union::Int(0));
/// A `Dynamic` containing the integer one. /// A [`Dynamic`] containing the integer one.
pub const ONE: Dynamic = Self(Union::Int(1)); pub const ONE: Dynamic = Self(Union::Int(1));
/// A `Dynamic` containing the integer negative one. /// A [`Dynamic`] containing the integer negative one.
pub const NEGATIVE_ONE: Dynamic = Self(Union::Int(-1)); pub const NEGATIVE_ONE: Dynamic = Self(Union::Int(-1));
/// A `Dynamic` containing the floating-point zero. /// A [`Dynamic`] containing the floating-point zero.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
pub const FLOAT_ZERO: Dynamic = Self(Union::Float(0.0)); pub const FLOAT_ZERO: Dynamic = Self(Union::Float(0.0));
/// A `Dynamic` containing the floating-point one. /// A [`Dynamic`] containing the floating-point one.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
pub const FLOAT_ONE: Dynamic = Self(Union::Float(1.0)); pub const FLOAT_ONE: Dynamic = Self(Union::Float(1.0));
/// A `Dynamic` containing the floating-point negative one. /// A [`Dynamic`] containing the floating-point negative one.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
pub const FLOAT_NEGATIVE_ONE: Dynamic = Self(Union::Float(-1.0)); pub const FLOAT_NEGATIVE_ONE: Dynamic = Self(Union::Float(-1.0));
/// Create a `Dynamic` from any type. A `Dynamic` value is simply returned as is. /// Create a [`Dynamic`] from any type. A [`Dynamic`] value is simply returned as is.
/// ///
/// # Safety /// # Safety
/// ///
@ -548,11 +543,12 @@ impl Dynamic {
/// ///
/// # Notes /// # Notes
/// ///
/// Beware that you need to pass in an `Array` type for it to be recognized as an `Array`. /// Beware that you need to pass in an [`Array`] type for it to be recognized as an [`Array`].
/// A `Vec<T>` does not get automatically converted to an `Array`, but will be a generic /// A [`Vec<T>`][Vec] does not get automatically converted to an [`Array`], but will be a generic
/// restricted trait object instead, because `Vec<T>` is not a supported standard type. /// restricted trait object instead, because [`Vec<T>`][Vec] is not a supported standard type.
/// ///
/// Similarly, passing in a `HashMap<String, T>` will not get a `Map` but a trait object. /// Similarly, passing in a [`HashMap<String, T>`][std::collections::HashMap] will not get a [`Map`]
/// but a trait object.
/// ///
/// # Examples /// # Examples
/// ///
@ -657,15 +653,15 @@ impl Dynamic {
Self(Union::Variant(Box::new(boxed))) Self(Union::Variant(Box::new(boxed)))
} }
/// Turn the `Dynamic` value into a shared `Dynamic` value backed by an `Rc<RefCell<Dynamic>>` /// Turn the [`Dynamic`] value into a shared [`Dynamic`] value backed by an [`Rc`][std::rc::Rc]`<`[`RefCell`][std::cell::RefCell]`<`[`Dynamic`]`>>`
/// or `Arc<RwLock<Dynamic>>` depending on the `sync` feature. /// or [`Arc`][std::sync::Arc]`<`[`RwLock`][std::sync::RwLock]`<`[`Dynamic`]`>>` depending on the [`Sync`] feature.
/// ///
/// Shared `Dynamic` values are relatively cheap to clone as they simply increment the /// Shared [`Dynamic`] values are relatively cheap to clone as they simply increment the
/// reference counts. /// reference counts.
/// ///
/// Shared `Dynamic` values can be converted seamlessly to and from ordinary `Dynamic` values. /// Shared [`Dynamic`] values can be converted seamlessly to and from ordinary [`Dynamic`] values.
/// ///
/// If the `Dynamic` value is already shared, this method returns itself. /// If the [`Dynamic`] value is already shared, this method returns itself.
/// ///
/// # Panics /// # Panics
/// ///
@ -681,16 +677,16 @@ impl Dynamic {
#[cfg(feature = "no_closure")] #[cfg(feature = "no_closure")]
panic!("converting into a shared value is not supported under 'no_closure'"); panic!("converting into a shared value is not supported under 'no_closure'");
} }
/// Convert the `Dynamic` value into specific type. /// Convert the [`Dynamic`] value into specific type.
/// ///
/// Casting to a `Dynamic` just returns as is, but if it contains a shared value, /// Casting to a [`Dynamic`] just returns as is, but if it contains a shared value,
/// it is cloned into a `Dynamic` with a normal value. /// it is cloned into a [`Dynamic`] with a normal value.
/// ///
/// Returns `None` if types mismatched. /// Returns [`None`] if types mismatched.
/// ///
/// # Panics or Deadlocks /// # Panics or Deadlocks
/// ///
/// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
/// ///
/// These normally shouldn't occur since most operations in Rhai is single-threaded. /// These normally shouldn't occur since most operations in Rhai is single-threaded.
@ -811,19 +807,19 @@ impl Dynamic {
_ => None, _ => None,
} }
} }
/// Convert the `Dynamic` value into a specific type. /// Convert the [`Dynamic`] value into a specific type.
/// ///
/// Casting to a `Dynamic` just returns as is, but if it contains a shared value, /// Casting to a [`Dynamic`] just returns as is, but if it contains a shared value,
/// it is cloned into a `Dynamic` with a normal value. /// it is cloned into a [`Dynamic`] with a normal value.
/// ///
/// Returns `None` if types mismatched. /// Returns [`None`] if types mismatched.
/// ///
/// # Panics or Deadlocks /// # Panics or Deadlocks
/// ///
/// Panics if the cast fails (e.g. the type of the actual value is not the /// Panics if the cast fails (e.g. the type of the actual value is not the
/// same as the specified type). /// same as the specified type).
/// ///
/// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
/// ///
/// These normally shouldn't occur since most operations in Rhai is single-threaded. /// These normally shouldn't occur since most operations in Rhai is single-threaded.
@ -854,11 +850,11 @@ impl Dynamic {
) )
}) })
} }
/// Flatten the `Dynamic` and clone it. /// Flatten the [`Dynamic`] and clone it.
/// ///
/// If the `Dynamic` is not a shared value, it returns a cloned copy. /// If the [`Dynamic`] is not a shared value, it returns a cloned copy.
/// ///
/// If the `Dynamic` is a shared value, it a cloned copy of the shared value. /// If the [`Dynamic`] is a shared value, it a cloned copy of the shared value.
#[inline(always)] #[inline(always)]
pub fn flatten_clone(&self) -> Self { pub fn flatten_clone(&self) -> Self {
match &self.0 { match &self.0 {
@ -873,11 +869,11 @@ impl Dynamic {
_ => self.clone(), _ => self.clone(),
} }
} }
/// Flatten the `Dynamic`. /// Flatten the [`Dynamic`].
/// ///
/// If the `Dynamic` is not a shared value, it returns itself. /// If the [`Dynamic`] is not a shared value, it returns itself.
/// ///
/// If the `Dynamic` is a shared value, it returns the shared value if there are /// If the [`Dynamic`] is a shared value, it returns the shared value if there are
/// no outstanding references, or a cloned copy. /// no outstanding references, or a cloned copy.
#[inline(always)] #[inline(always)]
pub fn flatten(self) -> Self { pub fn flatten(self) -> Self {
@ -900,13 +896,13 @@ impl Dynamic {
_ => self, _ => self,
} }
} }
/// Is the `Dynamic` a shared value that is locked? /// Is the [`Dynamic`] a shared value that is locked?
/// ///
/// ## Note /// ## Note
/// ///
/// Under the `sync` feature, shared values use `RwLock` and they are never locked. /// Under the [`Sync`] feature, shared values use [`RwLock`][std::sync::RwLock] and they are never locked.
/// Access just waits until the `RwLock` is released. /// Access just waits until the [`RwLock`][std::sync::RwLock] is released.
/// So this method always returns `false` under `sync`. /// So this method always returns [`false`] under [`Sync`].
#[inline(always)] #[inline(always)]
pub fn is_locked(&self) -> bool { pub fn is_locked(&self) -> bool {
match self.0 { match self.0 {
@ -921,14 +917,14 @@ impl Dynamic {
_ => false, _ => false,
} }
} }
/// Get a reference of a specific type to the `Dynamic`. /// Get a reference of a specific type to the [`Dynamic`].
/// Casting to `Dynamic` just returns a reference to it. /// Casting to [`Dynamic`] just returns a reference to it.
/// ///
/// Returns `None` if the cast fails. /// Returns [`None`] if the cast fails.
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
#[inline(always)] #[inline(always)]
pub fn read_lock<T: Variant + Clone>(&self) -> Option<DynamicReadLock<T>> { pub fn read_lock<T: Variant + Clone>(&self) -> Option<DynamicReadLock<T>> {
@ -953,14 +949,14 @@ impl Dynamic {
.map(|r| DynamicReadLock(DynamicReadLockInner::Reference(r))), .map(|r| DynamicReadLock(DynamicReadLockInner::Reference(r))),
} }
} }
/// Get a mutable reference of a specific type to the `Dynamic`. /// Get a mutable reference of a specific type to the [`Dynamic`].
/// Casting to `Dynamic` just returns a mutable reference to it. /// Casting to [`Dynamic`] just returns a mutable reference to it.
/// ///
/// Returns `None` if the cast fails. /// Returns [`None`] if the cast fails.
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
#[inline(always)] #[inline(always)]
pub fn write_lock<T: Variant + Clone>(&mut self) -> Option<DynamicWriteLock<T>> { pub fn write_lock<T: Variant + Clone>(&mut self) -> Option<DynamicWriteLock<T>> {
@ -985,10 +981,10 @@ impl Dynamic {
.map(|r| DynamicWriteLock(DynamicWriteLockInner::Reference(r))), .map(|r| DynamicWriteLock(DynamicWriteLockInner::Reference(r))),
} }
} }
/// Get a reference of a specific type to the `Dynamic`. /// Get a reference of a specific type to the [`Dynamic`].
/// Casting to `Dynamic` just returns a reference to it. /// Casting to [`Dynamic`] just returns a reference to it.
/// ///
/// Returns `None` if the cast fails, or if the value is shared. /// Returns [`None`] if the cast fails, or if the value is shared.
#[inline(always)] #[inline(always)]
pub(crate) fn downcast_ref<T: Variant + Clone>(&self) -> Option<&T> { pub(crate) fn downcast_ref<T: Variant + Clone>(&self) -> Option<&T> {
// Coded this way in order to maximally leverage potentials for dead-code removal. // Coded this way in order to maximally leverage potentials for dead-code removal.
@ -1074,10 +1070,10 @@ impl Dynamic {
_ => None, _ => None,
} }
} }
/// Get a mutable reference of a specific type to the `Dynamic`. /// Get a mutable reference of a specific type to the [`Dynamic`].
/// Casting to `Dynamic` just returns a mutable reference to it. /// Casting to [`Dynamic`] just returns a mutable reference to it.
/// ///
/// Returns `None` if the cast fails, or if the value is shared. /// Returns [`None`] if the cast fails, or if the value is shared.
#[inline(always)] #[inline(always)]
pub(crate) fn downcast_mut<T: Variant + Clone>(&mut self) -> Option<&mut T> { pub(crate) fn downcast_mut<T: Variant + Clone>(&mut self) -> Option<&mut T> {
// Coded this way in order to maximally leverage potentials for dead-code removal. // Coded this way in order to maximally leverage potentials for dead-code removal.
@ -1157,7 +1153,7 @@ impl Dynamic {
_ => None, _ => None,
} }
} }
/// Cast the `Dynamic` as the system integer type `INT` and return it. /// Cast the [`Dynamic`] as the system integer type [`INT`] and return it.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
#[inline(always)] #[inline(always)]
pub fn as_int(&self) -> Result<INT, &'static str> { pub fn as_int(&self) -> Result<INT, &'static str> {
@ -1168,7 +1164,7 @@ impl Dynamic {
_ => Err(self.type_name()), _ => Err(self.type_name()),
} }
} }
/// Cast the `Dynamic` as the system floating-point type `FLOAT` and return it. /// Cast the [`Dynamic`] as the system floating-point type [`FLOAT`] and return it.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
#[inline(always)] #[inline(always)]
@ -1180,7 +1176,7 @@ impl Dynamic {
_ => Err(self.type_name()), _ => Err(self.type_name()),
} }
} }
/// Cast the `Dynamic` as a `bool` and return it. /// Cast the [`Dynamic`] as a [`bool`] and return it.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
#[inline(always)] #[inline(always)]
pub fn as_bool(&self) -> Result<bool, &'static str> { pub fn as_bool(&self) -> Result<bool, &'static str> {
@ -1191,7 +1187,7 @@ impl Dynamic {
_ => Err(self.type_name()), _ => Err(self.type_name()),
} }
} }
/// Cast the `Dynamic` as a `char` and return it. /// Cast the [`Dynamic`] as a [`char`] and return it.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
#[inline(always)] #[inline(always)]
pub fn as_char(&self) -> Result<char, &'static str> { pub fn as_char(&self) -> Result<char, &'static str> {
@ -1202,7 +1198,7 @@ impl Dynamic {
_ => Err(self.type_name()), _ => Err(self.type_name()),
} }
} }
/// Cast the `Dynamic` as a string and return the string slice. /// Cast the [`Dynamic`] as a [`String`] and return the string slice.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
/// ///
/// Cast is failing if `self` is Shared Dynamic /// Cast is failing if `self` is Shared Dynamic
@ -1214,7 +1210,7 @@ impl Dynamic {
_ => Err(self.type_name()), _ => Err(self.type_name()),
} }
} }
/// Convert the `Dynamic` into `String` and return it. /// Convert the [`Dynamic`] into a [`String`] and return it.
/// If there are other references to the same string, a cloned copy is returned. /// If there are other references to the same string, a cloned copy is returned.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
#[inline(always)] #[inline(always)]
@ -1222,7 +1218,7 @@ impl Dynamic {
self.take_immutable_string() self.take_immutable_string()
.map(ImmutableString::into_owned) .map(ImmutableString::into_owned)
} }
/// Convert the `Dynamic` into `ImmutableString` and return it. /// Convert the [`Dynamic`] into an [`ImmutableString`] and return it.
/// Returns the name of the actual type if the cast fails. /// Returns the name of the actual type if the cast fails.
#[inline] #[inline]
pub fn take_immutable_string(self) -> Result<ImmutableString, &'static str> { pub fn take_immutable_string(self) -> Result<ImmutableString, &'static str> {

View File

@ -1,4 +1,4 @@
//! Main module defining the script evaluation `Engine`. //! Main module defining the script evaluation [`Engine`].
use crate::ast::{Expr, FnCallExpr, Ident, IdentX, ReturnType, Stmt}; use crate::ast::{Expr, FnCallExpr, Ident, IdentX, ReturnType, Stmt};
use crate::dynamic::{map_std_type_name, Union, Variant}; use crate::dynamic::{map_std_type_name, Union, Variant};
@ -25,7 +25,7 @@ use crate::syntax::CustomSyntax;
use crate::utils::get_hasher; use crate::utils::get_hasher;
use crate::{ use crate::{
calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, Scope, calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, Scope,
Shared, StaticVec, NO_POS, Shared, StaticVec,
}; };
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
@ -40,7 +40,7 @@ use crate::Map;
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical
/// _[INTERNALS]_ A stack of imported modules. /// _(INTERNALS)_ A stack of imported modules.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -369,7 +369,7 @@ impl<'a> Target<'a> {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Self::StringChar(_, _, ch) => { Self::StringChar(_, _, ch) => {
let char_value = ch.clone(); let char_value = ch.clone();
self.set_value((char_value, NO_POS)).unwrap(); self.set_value((char_value, Position::NONE)).unwrap();
} }
} }
} }
@ -463,7 +463,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
@ -492,7 +492,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
@ -542,12 +542,12 @@ pub struct EvalContext<'e, 'x, 'px: 'x, 'a, 's, 'm, 'pm: 'm, 't, 'pt: 't> {
} }
impl<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> EvalContext<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> { impl<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> EvalContext<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> {
/// The current `Engine`. /// The current [`Engine`].
#[inline(always)] #[inline(always)]
pub fn engine(&self) -> &'e Engine { pub fn engine(&self) -> &'e Engine {
self.engine self.engine
} }
/// _[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.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
@ -576,9 +576,10 @@ impl<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> EvalContext<'e, 'x, 'px, 'a, 's, 'm,
/// ///
/// # Thread Safety /// # Thread Safety
/// ///
/// `Engine` is re-entrant. /// [`Engine`] is re-entrant.
/// ///
/// Currently, `Engine` is neither `Send` nor `Sync`. Use the `sync` feature to make it `Send + Sync`. /// Currently, [`Engine`] is neither [`Send`] nor [`Sync`].
/// Use the [`Sync`] feature to make it [`Send`] `+` [`Sync`].
/// ///
/// # Example /// # Example
/// ///
@ -595,7 +596,7 @@ impl<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> EvalContext<'e, 'x, 'px, 'a, 's, 'm,
/// # } /// # }
/// ``` /// ```
pub struct Engine { pub struct Engine {
/// A unique ID identifying this scripting `Engine`. /// A unique ID identifying this scripting [`Engine`].
pub id: String, pub id: String,
/// A module containing all functions directly loaded into the Engine. /// A module containing all functions directly loaded into the Engine.
@ -684,7 +685,7 @@ fn default_print(_s: &str) {
} }
/// Search for a module within an imports stack. /// Search for a module within an imports stack.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
pub fn search_imports( pub fn search_imports(
mods: &Imports, mods: &Imports,
state: &mut State, state: &mut State,
@ -710,7 +711,7 @@ pub fn search_imports(
} }
impl Engine { impl Engine {
/// Create a new `Engine` /// Create a new [`Engine`]
#[inline] #[inline]
pub fn new() -> Self { pub fn new() -> Self {
// Create the new scripting Engine // Create the new scripting Engine
@ -773,8 +774,8 @@ impl Engine {
engine engine
} }
/// Create a new `Engine` with minimal built-in functions. /// Create a new [`Engine`] with minimal built-in functions.
/// Use the `load_package` method to load additional packages of functions. /// Use the [`load_package`][Engine::load_package] method to load additional packages of functions.
#[inline] #[inline]
pub fn new_raw() -> Self { pub fn new_raw() -> Self {
Self { Self {
@ -929,7 +930,7 @@ impl Engine {
} }
/// Chain-evaluate a dot/index chain. /// Chain-evaluate a dot/index chain.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
fn eval_dot_index_chain_helper( fn eval_dot_index_chain_helper(
&self, &self,
@ -1020,7 +1021,7 @@ impl Engine {
{ {
EvalAltResult::ErrorIndexingType( EvalAltResult::ErrorIndexingType(
self.map_type_name(val_type_name).into(), self.map_type_name(val_type_name).into(),
NO_POS, Position::NONE,
) )
} }
err => err, err => err,
@ -1052,7 +1053,7 @@ impl Engine {
def_value, def_value,
.. ..
} = x.as_ref(); } = x.as_ref();
let def_value = def_value.map(Into::<Dynamic>::into); let def_value = def_value.as_ref();
let args = idx_val.as_fn_call_args(); let args = idx_val.as_fn_call_args();
self.make_method_call( self.make_method_call(
mods, state, lib, name, *hash, target, args, def_value, *native, false, mods, state, lib, name, *hash, target, args, def_value, *native, false,
@ -1126,7 +1127,7 @@ impl Engine {
def_value, def_value,
.. ..
} = x.as_ref(); } = x.as_ref();
let def_value = def_value.map(Into::<Dynamic>::into); let def_value = def_value.as_ref();
let args = idx_val.as_fn_call_args(); let args = idx_val.as_fn_call_args();
let (val, _) = self let (val, _) = self
.make_method_call( .make_method_call(
@ -1210,7 +1211,7 @@ impl Engine {
def_value, def_value,
.. ..
} = f.as_ref(); } = f.as_ref();
let def_value = def_value.map(Into::<Dynamic>::into); let def_value = def_value.as_ref();
let args = idx_val.as_fn_call_args(); let args = idx_val.as_fn_call_args();
let (mut val, _) = self let (mut val, _) = self
.make_method_call( .make_method_call(
@ -1314,8 +1315,8 @@ impl Engine {
} }
} }
/// Evaluate a chain of indexes and store the results in a StaticVec. /// Evaluate a chain of indexes and store the results in a [`StaticVec`].
/// StaticVec is used to avoid an allocation in the overwhelming cases of just a few levels of indexing. /// [`StaticVec`] is used to avoid an allocation in the overwhelming cases of just a few levels of indexing.
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
fn eval_indexed_chain( fn eval_indexed_chain(
&self, &self,
@ -1389,8 +1390,8 @@ impl Engine {
Ok(()) Ok(())
} }
/// Get the value at the indexed position of a base type /// Get the value at the indexed position of a base type.
/// Position in `EvalAltResult` may be None and should be set afterwards. /// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards.
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
fn get_indexed_mut<'t>( fn get_indexed_mut<'t>(
&self, &self,
@ -1479,7 +1480,10 @@ impl Engine {
.map(|(v, _)| v.into()) .map(|(v, _)| v.into())
.map_err(|err| match *err { .map_err(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) if fn_sig.ends_with(']') => { EvalAltResult::ErrorFunctionNotFound(fn_sig, _) if fn_sig.ends_with(']') => {
Box::new(EvalAltResult::ErrorIndexingType(type_name.into(), NO_POS)) Box::new(EvalAltResult::ErrorIndexingType(
type_name.into(),
Position::NONE,
))
} }
_ => err, _ => err,
}) })
@ -1487,13 +1491,13 @@ impl Engine {
_ => EvalAltResult::ErrorIndexingType( _ => EvalAltResult::ErrorIndexingType(
self.map_type_name(target.type_name()).into(), self.map_type_name(target.type_name()).into(),
NO_POS, Position::NONE,
) )
.into(), .into(),
} }
} }
// Evaluate an 'in' expression // Evaluate an 'in' expression.
fn eval_in_expr( fn eval_in_expr(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1516,10 +1520,10 @@ impl Engine {
Dynamic(Union::Array(mut rhs_value)) => { Dynamic(Union::Array(mut rhs_value)) => {
// Call the `==` operator to compare each value // Call the `==` operator to compare each value
let def_value = Some(false.into()); let def_value = Some(false.into());
let def_value = def_value.as_ref();
for value in rhs_value.iter_mut() { for value in rhs_value.iter_mut() {
let args = &mut [&mut lhs_value.clone(), value]; let args = &mut [&mut lhs_value.clone(), value];
let def_value = def_value.clone();
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s. // Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
let hash = let hash =
@ -1557,7 +1561,7 @@ impl Engine {
} }
} }
/// Get a `Target` from an expression. /// Get a [`Target`] from an expression.
pub(crate) fn eval_expr_as_target<'s>( pub(crate) fn eval_expr_as_target<'s>(
&self, &self,
scope: &'s mut Scope, scope: &'s mut Scope,
@ -1670,7 +1674,7 @@ impl Engine {
} }
} }
/// Evaluate an expression /// Evaluate an expression.
pub(crate) fn eval_expr( pub(crate) fn eval_expr(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1759,7 +1763,7 @@ impl Engine {
def_value, def_value,
.. ..
} = x.as_ref(); } = x.as_ref();
let def_value = def_value.map(Into::<Dynamic>::into); let def_value = def_value.as_ref();
self.make_function_call( self.make_function_call(
scope, mods, state, lib, this_ptr, name, args, def_value, *hash, *native, scope, mods, state, lib, this_ptr, name, args, def_value, *hash, *native,
false, *cap_scope, level, false, *cap_scope, level,
@ -1778,8 +1782,9 @@ impl Engine {
.. ..
} = x.as_ref(); } = x.as_ref();
let namespace = namespace.as_ref().map(|v| v.as_ref()); let namespace = namespace.as_ref().map(|v| v.as_ref());
let def_value = def_value.as_ref();
self.make_qualified_function_call( self.make_qualified_function_call(
scope, mods, state, lib, this_ptr, namespace, name, args, *def_value, *hash, scope, mods, state, lib, this_ptr, namespace, name, args, def_value, *hash,
level, level,
) )
.map_err(|err| err.fill_position(*pos)) .map_err(|err| err.fill_position(*pos))
@ -1843,6 +1848,7 @@ impl Engine {
.map_err(|err| err.fill_position(expr.position())) .map_err(|err| err.fill_position(expr.position()))
} }
/// Evaluate a list of statements.
pub(crate) fn eval_statements<'a>( pub(crate) fn eval_statements<'a>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1874,7 +1880,7 @@ impl Engine {
result result
} }
/// Evaluate a statement /// Evaluate a statement.
/// ///
/// ///
/// # Safety /// # Safety
@ -2210,7 +2216,7 @@ impl Engine {
let value = if let EvalAltResult::ErrorRuntime(ref x, _) = err { let value = if let EvalAltResult::ErrorRuntime(ref x, _) = err {
x.clone() x.clone()
} else { } else {
err.set_position(NO_POS); err.set_position(Position::NONE);
err.to_string().into() err.to_string().into()
}; };
@ -2389,7 +2395,7 @@ impl Engine {
} }
/// Check a result to ensure that the data size is within allowable limit. /// Check a result to ensure that the data size is within allowable limit.
/// Position in `EvalAltResult` may be None and should be set afterwards. /// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards.
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
#[inline(always)] #[inline(always)]
fn check_data_size( fn check_data_size(
@ -2400,7 +2406,7 @@ impl Engine {
} }
/// Check a result to ensure that the data size is within allowable limit. /// Check a result to ensure that the data size is within allowable limit.
/// Position in `EvalAltResult` may be None and should be set afterwards. /// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
fn check_data_size( fn check_data_size(
&self, &self,
@ -2493,39 +2499,47 @@ impl Engine {
let (_arr, _map, s) = calc_size(result.as_ref().unwrap()); let (_arr, _map, s) = calc_size(result.as_ref().unwrap());
if s > self.max_string_size() { if s > self.max_string_size() {
return EvalAltResult::ErrorDataTooLarge("Length of string".to_string(), NO_POS).into(); return EvalAltResult::ErrorDataTooLarge(
"Length of string".to_string(),
Position::NONE,
)
.into();
} }
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
if _arr > self.max_array_size() { if _arr > self.max_array_size() {
return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), NO_POS).into(); return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), Position::NONE)
.into();
} }
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
if _map > self.max_map_size() { if _map > self.max_map_size() {
return EvalAltResult::ErrorDataTooLarge("Size of object map".to_string(), NO_POS) return EvalAltResult::ErrorDataTooLarge(
.into(); "Size of object map".to_string(),
Position::NONE,
)
.into();
} }
result result
} }
/// Check if the number of operations stay within limit. /// Check if the number of operations stay within limit.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
pub(crate) fn inc_operations(&self, state: &mut State) -> Result<(), Box<EvalAltResult>> { pub(crate) fn inc_operations(&self, state: &mut State) -> Result<(), Box<EvalAltResult>> {
state.operations += 1; state.operations += 1;
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
// Guard against too many operations // Guard against too many operations
if self.max_operations() > 0 && state.operations > self.max_operations() { if self.max_operations() > 0 && state.operations > self.max_operations() {
return EvalAltResult::ErrorTooManyOperations(NO_POS).into(); return EvalAltResult::ErrorTooManyOperations(Position::NONE).into();
} }
// Report progress - only in steps // Report progress - only in steps
if let Some(progress) = &self.progress { if let Some(progress) = &self.progress {
if let Some(token) = progress(&state.operations) { if let Some(token) = progress(&state.operations) {
// Terminate script if progress returns a termination token // Terminate script if progress returns a termination token
return EvalAltResult::ErrorTerminated(token, NO_POS).into(); return EvalAltResult::ErrorTerminated(token, Position::NONE).into();
} }
} }
@ -2541,7 +2555,7 @@ impl Engine {
.unwrap_or_else(|| map_std_type_name(name)) .unwrap_or_else(|| map_std_type_name(name))
} }
/// Make a Box<EvalAltResult<ErrorMismatchDataType>>. /// Make a `Box<`[`EvalAltResult<ErrorMismatchDataType>`][EvalAltResult::ErrorMismatchDataType]`>`.
#[inline(always)] #[inline(always)]
pub(crate) fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> Box<EvalAltResult> { pub(crate) fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> Box<EvalAltResult> {
EvalAltResult::ErrorMismatchDataType( EvalAltResult::ErrorMismatchDataType(

View File

@ -1,4 +1,4 @@
//! Module that defines the extern API of `Engine`. //! Module that defines the extern API of [`Engine`].
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::engine::{EvalContext, Imports}; use crate::engine::{EvalContext, Imports};
@ -13,7 +13,7 @@ use crate::stdlib::{
use crate::utils::get_hasher; use crate::utils::get_hasher;
use crate::{ use crate::{
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, NativeCallContext, scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, NativeCallContext,
ParseError, AST, NO_POS, ParseError, Position, AST,
}; };
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
@ -31,14 +31,14 @@ fn calc_hash_for_scripts<'a>(scripts: impl IntoIterator<Item = &'a &'a str>) ->
/// Engine public API /// Engine public API
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`'s indicating the actual types of the parameters. /// This function is very low level. It takes a list of [`TypeId`]'s indicating the actual types of the parameters.
/// ///
/// 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],
/// The arguments are guaranteed to be of the correct types matching the `TypeId`'s. /// The arguments are guaranteed to be of the correct types matching the [`TypeId`]'s.
/// ///
/// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::<T>()` /// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::<T>()`
/// ///
@ -65,8 +65,8 @@ impl Engine {
); );
self self
} }
/// Register a custom type for use with the `Engine`. /// Register a custom type for use with the [`Engine`].
/// The type must implement `Clone`. /// The type must implement [`Clone`].
/// ///
/// # Example /// # Example
/// ///
@ -106,8 +106,8 @@ impl Engine {
pub fn register_type<T: Variant + Clone>(&mut self) -> &mut Self { pub fn register_type<T: Variant + Clone>(&mut self) -> &mut Self {
self.register_type_with_name::<T>(type_name::<T>()) self.register_type_with_name::<T>(type_name::<T>())
} }
/// Register a custom type for use with the `Engine`, with a pretty-print name /// Register a custom type for use with the [`Engine`], with a pretty-print name
/// for the `type_of` function. The type must implement `Clone`. /// for the `type_of` function. The type must implement [`Clone`].
/// ///
/// # Example /// # Example
/// ///
@ -156,7 +156,7 @@ impl Engine {
self.type_names.insert(type_name::<T>().into(), name.into()); self.type_names.insert(type_name::<T>().into(), name.into());
self self
} }
/// Register an iterator adapter for an iterable type with the `Engine`. /// Register an iterator adapter for an iterable type with the [`Engine`].
/// This is an advanced feature. /// This is an advanced feature.
#[inline(always)] #[inline(always)]
pub fn register_iterator<T>(&mut self) -> &mut Self pub fn register_iterator<T>(&mut self) -> &mut Self
@ -167,7 +167,7 @@ impl Engine {
self.global_namespace.set_iterable::<T>(); self.global_namespace.set_iterable::<T>();
self self
} }
/// Register a getter function for a member of a registered type with the `Engine`. /// Register a getter function for a member of a registered type with the [`Engine`].
/// ///
/// The function signature must start with `&mut self` and not `&self`. /// The function signature must start with `&mut self` and not `&self`.
/// ///
@ -211,8 +211,7 @@ impl Engine {
) -> &mut Self { ) -> &mut Self {
crate::RegisterFn::register_fn(self, &crate::engine::make_getter(name), callback) crate::RegisterFn::register_fn(self, &crate::engine::make_getter(name), callback)
} }
/// Register a getter function for a member of a registered type with the `Engine`. /// Register a getter function for a member of a registered type with the [`Engine`].
/// Returns `Result<Dynamic, Box<EvalAltResult>>`.
/// ///
/// The function signature must start with `&mut self` and not `&self`. /// The function signature must start with `&mut self` and not `&self`.
/// ///
@ -262,7 +261,7 @@ impl Engine {
callback, callback,
) )
} }
/// Register a setter function for a member of a registered type with the `Engine`. /// Register a setter function for a member of a registered type with the [`Engine`].
/// ///
/// # Example /// # Example
/// ///
@ -307,8 +306,7 @@ impl Engine {
) -> &mut Self { ) -> &mut Self {
crate::RegisterFn::register_fn(self, &crate::engine::make_setter(name), callback) crate::RegisterFn::register_fn(self, &crate::engine::make_setter(name), callback)
} }
/// Register a setter function for a member of a registered type with the `Engine`. /// Register a setter function for a member of a registered type with the [`Engine`].
/// Returns `Result<(), Box<EvalAltResult>>`.
/// ///
/// # Example /// # Example
/// ///
@ -361,7 +359,7 @@ impl Engine {
) )
} }
/// Short-hand for registering both getter and setter functions /// Short-hand for registering both getter and setter functions
/// of a registered type with the `Engine`. /// of a registered type with the [`Engine`].
/// ///
/// All function signatures must start with `&mut self` and not `&self`. /// All function signatures must start with `&mut self` and not `&self`.
/// ///
@ -408,13 +406,13 @@ impl Engine {
) -> &mut Self { ) -> &mut Self {
self.register_get(name, get_fn).register_set(name, set_fn) self.register_get(name, get_fn).register_set(name, set_fn)
} }
/// Register an index getter for a custom type with the `Engine`. /// Register an index getter for a custom type with the [`Engine`].
/// ///
/// The function signature must start with `&mut self` and not `&self`. /// The function signature must start with `&mut self` and not `&self`.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`], [`Map`], [`String`], [`ImmutableString`][crate::ImmutableString] or `&str`.
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -471,14 +469,13 @@ impl Engine {
crate::RegisterFn::register_fn(self, crate::engine::FN_IDX_GET, callback) crate::RegisterFn::register_fn(self, crate::engine::FN_IDX_GET, callback)
} }
/// Register an index getter for a custom type with the `Engine`. /// Register an index getter for a custom type with the [`Engine`].
/// Returns `Result<Dynamic, Box<EvalAltResult>>`.
/// ///
/// The function signature must start with `&mut self` and not `&self`. /// The function signature must start with `&mut self` and not `&self`.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`], [`Map`], [`String`], [`ImmutableString`][crate::ImmutableString] or `&str`.
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -537,11 +534,11 @@ impl Engine {
crate::RegisterResultFn::register_result_fn(self, crate::engine::FN_IDX_GET, callback) crate::RegisterResultFn::register_result_fn(self, crate::engine::FN_IDX_GET, callback)
} }
/// Register an index setter for a custom type with the `Engine`. /// Register an index setter for a custom type with the [`Engine`].
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`], [`Map`], [`String`], [`ImmutableString`][crate::ImmutableString] or `&str`.
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -600,12 +597,11 @@ impl Engine {
crate::RegisterFn::register_fn(self, crate::engine::FN_IDX_SET, callback) crate::RegisterFn::register_fn(self, crate::engine::FN_IDX_SET, callback)
} }
/// Register an index setter for a custom type with the `Engine`. /// Register an index setter for a custom type with the [`Engine`].
/// Returns `Result<(), Box<EvalAltResult>>`.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`], [`Map`], [`String`], [`ImmutableString`][crate::ImmutableString] or `&str`.
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -675,11 +671,11 @@ impl Engine {
move |obj: &mut T, index: X, value: U| callback(obj, index, value).map(Into::into), move |obj: &mut T, index: X, value: U| callback(obj, index, value).map(Into::into),
) )
} }
/// Short-hand for register both index getter and setter functions for a custom type with the `Engine`. /// Short-hand for register both index getter and setter functions for a custom type with the [`Engine`].
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`], [`Map`], [`String`], [`ImmutableString`][crate::ImmutableString] or `&str`.
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -725,7 +721,7 @@ impl Engine {
self.register_indexer_get(getter) self.register_indexer_get(getter)
.register_indexer_set(setter) .register_indexer_set(setter)
} }
/// Register a `Module` as a fixed module namespace with the `Engine`. /// Register a [`Module`][crate::Module] as a fixed module namespace with the [`Engine`].
/// ///
/// # Example /// # Example
/// ///
@ -764,7 +760,7 @@ impl Engine {
} }
self self
} }
/// Compile a string into an `AST`, which can be used later for evaluation. /// Compile a string into an [`AST`], which can be used later for evaluation.
/// ///
/// # Example /// # Example
/// ///
@ -787,10 +783,10 @@ impl Engine {
pub fn compile(&self, script: &str) -> Result<AST, ParseError> { pub fn compile(&self, script: &str) -> Result<AST, ParseError> {
self.compile_with_scope(&Default::default(), script) self.compile_with_scope(&Default::default(), script)
} }
/// Compile a string into an `AST` using own scope, which can be used later for evaluation. /// Compile a string into an [`AST`] using own scope, which can be used later for evaluation.
/// ///
/// 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`].
/// ///
/// # Example /// # Example
/// ///
@ -830,10 +826,10 @@ impl Engine {
self.compile_scripts_with_scope(scope, &[script]) self.compile_scripts_with_scope(scope, &[script])
} }
/// When passed a list of strings, first join the strings into one large script, /// When passed a list of strings, first join the strings into one large script,
/// and then compile them into an `AST` using own scope, which can be used later for evaluation. /// and then compile them into an [`AST`] using own scope, which can be used later for evaluation.
/// ///
/// 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`].
/// ///
/// ## Note /// ## Note
/// ///
@ -883,7 +879,7 @@ impl Engine {
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level) self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level)
} }
/// Join a list of strings and compile into an `AST` using own scope at a specific optimization level. /// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level.
#[inline(always)] #[inline(always)]
pub(crate) fn compile_with_scope_and_optimization_level( pub(crate) fn compile_with_scope_and_optimization_level(
&self, &self,
@ -920,7 +916,7 @@ impl Engine {
Ok(contents) Ok(contents)
} }
/// 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.
/// ///
/// # Example /// # Example
/// ///
@ -949,10 +945,10 @@ impl Engine {
) -> Result<AST, Box<EvalAltResult>> { ) -> Result<AST, Box<EvalAltResult>> {
self.compile_file_with_scope(&Default::default(), path) self.compile_file_with_scope(&Default::default(), path)
} }
/// 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.
/// ///
/// 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`].
/// ///
/// # Example /// # Example
/// ///
@ -1030,7 +1026,7 @@ impl Engine {
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub fn parse_json(&self, json: &str, has_null: bool) -> Result<Map, Box<EvalAltResult>> { pub fn parse_json(&self, json: &str, has_null: bool) -> Result<Map, Box<EvalAltResult>> {
use crate::token::{Position, Token}; use crate::token::Token;
let mut scope = Default::default(); let mut scope = Default::default();
@ -1076,7 +1072,7 @@ impl Engine {
self.eval_ast_with_scope(&mut scope, &ast) self.eval_ast_with_scope(&mut scope, &ast)
} }
/// Compile a string containing an expression into an `AST`, /// Compile a string containing an expression into an [`AST`],
/// which can be used later for evaluation. /// which can be used later for evaluation.
/// ///
/// # Example /// # Example
@ -1100,11 +1096,11 @@ impl Engine {
pub fn compile_expression(&self, script: &str) -> Result<AST, ParseError> { pub fn compile_expression(&self, script: &str) -> Result<AST, ParseError> {
self.compile_expression_with_scope(&Default::default(), script) self.compile_expression_with_scope(&Default::default(), script)
} }
/// Compile a string containing an expression into an `AST` using own scope, /// Compile a string containing an expression into an [`AST`] using own scope,
/// which can be used later for evaluation. /// which can be used later for evaluation.
/// ///
/// 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`].
/// ///
/// # Example /// # Example
/// ///
@ -1313,7 +1309,7 @@ impl Engine {
self.eval_ast_with_scope(scope, &ast) self.eval_ast_with_scope(scope, &ast)
} }
/// Evaluate an `AST`. /// Evaluate an [`AST`].
/// ///
/// # Example /// # Example
/// ///
@ -1335,7 +1331,7 @@ impl Engine {
pub fn eval_ast<T: Variant + Clone>(&self, ast: &AST) -> Result<T, Box<EvalAltResult>> { pub fn eval_ast<T: Variant + Clone>(&self, ast: &AST) -> Result<T, Box<EvalAltResult>> {
self.eval_ast_with_scope(&mut Default::default(), ast) self.eval_ast_with_scope(&mut Default::default(), ast)
} }
/// Evaluate an `AST` with own scope. /// Evaluate an [`AST`] with own scope.
/// ///
/// # Example /// # Example
/// ///
@ -1380,12 +1376,12 @@ impl Engine {
EvalAltResult::ErrorMismatchOutputType( EvalAltResult::ErrorMismatchOutputType(
self.map_type_name(type_name::<T>()).into(), self.map_type_name(type_name::<T>()).into(),
typ.into(), typ.into(),
NO_POS, Position::NONE,
) )
.into() .into()
}); });
} }
/// Evaluate an `AST` with own scope. /// Evaluate an [`AST`] with own scope.
#[inline(always)] #[inline(always)]
pub(crate) fn eval_ast_with_scope_raw<'a>( pub(crate) fn eval_ast_with_scope_raw<'a>(
&self, &self,
@ -1444,7 +1440,7 @@ impl Engine {
pub fn consume_ast(&self, ast: &AST) -> Result<(), Box<EvalAltResult>> { pub fn consume_ast(&self, ast: &AST) -> Result<(), Box<EvalAltResult>> {
self.consume_ast_with_scope(&mut Default::default(), ast) self.consume_ast_with_scope(&mut Default::default(), ast)
} }
/// Evaluate an `AST` with own scope, but throw away the result and only return error (if any). /// Evaluate an [`AST`] 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.
#[inline(always)] #[inline(always)]
pub fn consume_ast_with_scope( pub fn consume_ast_with_scope(
@ -1457,7 +1453,7 @@ impl Engine {
self.eval_statements_raw(scope, &mut mods, ast.statements(), &[ast.lib()]) self.eval_statements_raw(scope, &mut mods, ast.statements(), &[ast.lib()])
.map(|_| ()) .map(|_| ())
} }
/// Call a script function defined in an `AST` with multiple arguments. /// Call a script function defined in an [`AST`] with multiple arguments.
/// Arguments are passed as a tuple. /// Arguments are passed as a tuple.
/// ///
/// # Example /// # Example
@ -1514,13 +1510,13 @@ impl Engine {
EvalAltResult::ErrorMismatchOutputType( EvalAltResult::ErrorMismatchOutputType(
self.map_type_name(type_name::<T>()).into(), self.map_type_name(type_name::<T>()).into(),
typ.into(), typ.into(),
NO_POS, Position::NONE,
) )
.into() .into()
}); });
} }
/// 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
/// ///
@ -1582,7 +1578,7 @@ impl Engine {
self.call_fn_dynamic_raw(scope, &[lib.as_ref()], name, &mut this_ptr, args.as_mut()) self.call_fn_dynamic_raw(scope, &[lib.as_ref()], name, &mut this_ptr, args.as_mut())
} }
/// 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
/// ///
@ -1603,7 +1599,7 @@ impl Engine {
let fn_def = lib let fn_def = lib
.iter() .iter()
.find_map(|&m| m.get_script_fn(name, args.len(), true)) .find_map(|&m| m.get_script_fn(name, args.len(), true))
.ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), NO_POS))?; .ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), Position::NONE))?;
let mut state = Default::default(); let mut state = Default::default();
let mut mods = self.global_sub_modules.clone(); let mut mods = self.global_sub_modules.clone();
@ -1615,17 +1611,19 @@ impl Engine {
self.call_script_fn(scope, &mut mods, &mut state, lib, this_ptr, fn_def, args, 0) self.call_script_fn(scope, &mut mods, &mut state, lib, this_ptr, fn_def, args, 0)
} }
/// Optimize the `AST` with constants defined in an external Scope. /// Optimize the [`AST`] with constants defined in an external Scope.
/// An optimized copy of the `AST` is returned while the original `AST` is consumed. /// An optimized copy of the [`AST`] is returned while the original [`AST`] is consumed.
/// ///
/// Although optimization is performed by default during compilation, sometimes it is necessary to /// Although optimization is performed by default during compilation, sometimes it is necessary to
/// _re_-optimize an AST. For example, when working with constants that are passed in via an /// _re_-optimize an [`AST`]. For example, when working with constants that are passed in via an
/// external scope, it will be more efficient to optimize the `AST` once again to take advantage /// external scope, it will be more efficient to optimize the [`AST`] once again to take advantage
/// of the new constants. /// of the new constants.
/// ///
/// With this method, it is no longer necessary to recompile a large script. The script `AST` can be /// With this method, it is no longer necessary to recompile a large script.
/// compiled just once. Before evaluation, constants are passed into the `Engine` via an external scope /// The script [`AST`] can be compiled just once. Before evaluation,
/// (i.e. with `scope.push_constant(...)`). Then, the `AST is cloned and the copy re-optimized before running. /// constants are passed into the [`Engine`] via an external scope
/// (i.e. with [`scope.push_constant(...)`][crate::Scope::push_constant]).
/// Then, the [`AST`] is cloned and the copy re-optimized before running.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline] #[inline]
pub fn optimize_ast( pub fn optimize_ast(
@ -1732,7 +1730,7 @@ impl Engine {
self.progress = Some(Box::new(callback)); self.progress = Some(Box::new(callback));
self self
} }
/// Override default action of `print` (print to stdout using `println!`) /// Override default action of `print` (print to stdout using [`println!`])
/// ///
/// # Example /// # Example
/// ///
@ -1761,7 +1759,7 @@ impl Engine {
self.print = Box::new(callback); self.print = Box::new(callback);
self self
} }
/// Override default action of `debug` (print to stdout using `println!`) /// Override default action of `debug` (print to stdout using [`println!`])
/// ///
/// # Example /// # Example
/// ///

View File

@ -1,4 +1,4 @@
//! Configuration settings for `Engine`. //! Configuration settings for [`Engine`].
use crate::packages::PackageLibrary; use crate::packages::PackageLibrary;
use crate::stdlib::{format, string::String}; use crate::stdlib::{format, string::String};
@ -9,8 +9,8 @@ use crate::Engine;
use crate::stdlib::boxed::Box; use crate::stdlib::boxed::Box;
impl Engine { impl Engine {
/// Load a new package into the `Engine`. /// Load a new package into the [`Engine`].
/// Anything that can be converted into a `PackageLibrary` is accepted, including a simple `Module`. /// A simple [`Module`][crate::Module] is automatically converted into a package.
/// ///
/// When searching for functions, packages loaded later are preferred. /// When searching for functions, packages loaded later are preferred.
/// In other words, loaded packages are searched in reverse order. /// In other words, loaded packages are searched in reverse order.
@ -19,7 +19,7 @@ impl Engine {
self.packages.add(package.into()); self.packages.add(package.into());
self self
} }
/// Control whether and how the `Engine` will optimize an 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 the `no_optimize` feature.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
@ -32,7 +32,7 @@ impl Engine {
self self
} }
/// The current optimization level. /// The current optimization level.
/// It controls whether and how the `Engine` will optimize an 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 the `no_optimize` feature.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
@ -166,7 +166,7 @@ impl Engine {
pub fn max_map_size(&self) -> usize { pub fn max_map_size(&self) -> usize {
self.limits.max_map_size self.limits.max_map_size
} }
/// 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 the `no_module` feature.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]

View File

@ -1,4 +1,4 @@
//! Helper module which defines `FuncArgs` to make function calling easier. //! Helper module which defines [`FuncArgs`] to make function calling easier.
#![allow(non_snake_case)] #![allow(non_snake_case)]
@ -9,12 +9,12 @@ use crate::{Dynamic, StaticVec};
/// Any data type that can be converted into a `Vec<Dynamic>` can be used /// Any data type that can be converted into a `Vec<Dynamic>` can be used
/// as arguments to a function call. /// as arguments to a function call.
pub trait FuncArgs { pub trait FuncArgs {
/// Convert to a `StaticVec<Dynamic>` of the function call arguments. /// Convert to a [`StaticVec`]`<`[`Dynamic`]`>` of the function call arguments.
fn into_vec(self) -> StaticVec<Dynamic>; fn into_vec(self) -> StaticVec<Dynamic>;
} }
/// Macro to implement `FuncArgs` for tuples of standard types (each can be /// Macro to implement [`FuncArgs`] for tuples of standard types (each can be
/// converted into `Dynamic`). /// converted into a [`Dynamic`]).
macro_rules! impl_args { macro_rules! impl_args {
($($p:ident),*) => { ($($p:ident),*) => {
impl<$($p: Variant + Clone),*> FuncArgs for ($($p,)*) impl<$($p: Variant + Clone),*> FuncArgs for ($($p,)*)

View File

@ -1,4 +1,4 @@
//! Implement function-calling mechanism for `Engine`. //! Implement function-calling mechanism for [`Engine`].
use crate::ast::{Expr, Stmt}; use crate::ast::{Expr, Stmt};
use crate::engine::{ use crate::engine::{
@ -23,7 +23,7 @@ use crate::stdlib::{
}; };
use crate::{ use crate::{
calc_native_fn_hash, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, FnPtr, calc_native_fn_hash, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, FnPtr,
ImmutableString, Module, ParseErrorType, Scope, StaticVec, INT, NO_POS, ImmutableString, Module, ParseErrorType, Position, Scope, StaticVec, INT,
}; };
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
@ -140,7 +140,7 @@ pub fn ensure_no_data_race(
{ {
return EvalAltResult::ErrorDataRace( return EvalAltResult::ErrorDataRace(
format!("argument #{} of function '{}'", n + 1 + skip, fn_name), format!("argument #{} of function '{}'", n + 1 + skip, fn_name),
NO_POS, Position::NONE,
) )
.into(); .into();
} }
@ -150,8 +150,8 @@ 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`].
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
/// ///
/// ## WARNING /// ## WARNING
/// ///
@ -168,7 +168,7 @@ impl Engine {
args: &mut FnCallArgs, args: &mut FnCallArgs,
is_ref: bool, is_ref: bool,
pub_only: bool, pub_only: bool,
def_val: Option<Dynamic>, def_val: Option<&Dynamic>,
) -> Result<(Dynamic, bool), Box<EvalAltResult>> { ) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
self.inc_operations(state)?; self.inc_operations(state)?;
@ -206,7 +206,7 @@ impl Engine {
EvalAltResult::ErrorMismatchOutputType( EvalAltResult::ErrorMismatchOutputType(
self.map_type_name(type_name::<ImmutableString>()).into(), self.map_type_name(type_name::<ImmutableString>()).into(),
typ.into(), typ.into(),
NO_POS, Position::NONE,
) )
})?) })?)
.into(), .into(),
@ -217,7 +217,7 @@ impl Engine {
EvalAltResult::ErrorMismatchOutputType( EvalAltResult::ErrorMismatchOutputType(
self.map_type_name(type_name::<ImmutableString>()).into(), self.map_type_name(type_name::<ImmutableString>()).into(),
typ.into(), typ.into(),
NO_POS, Position::NONE,
) )
})?) })?)
.into(), .into(),
@ -237,7 +237,7 @@ impl Engine {
// Return default value (if any) // Return default value (if any)
if let Some(val) = def_val { if let Some(val) = def_val {
return Ok((val, false)); return Ok((val.clone(), false));
} }
// Getter function not found? // Getter function not found?
@ -249,7 +249,7 @@ impl Engine {
prop, prop,
self.map_type_name(args[0].type_name()) self.map_type_name(args[0].type_name())
), ),
NO_POS, Position::NONE,
) )
.into(); .into();
} }
@ -264,7 +264,7 @@ impl Engine {
self.map_type_name(args[0].type_name()), self.map_type_name(args[0].type_name()),
self.map_type_name(args[1].type_name()), self.map_type_name(args[1].type_name()),
), ),
NO_POS, Position::NONE,
) )
.into(); .into();
} }
@ -278,7 +278,7 @@ impl Engine {
self.map_type_name(args[0].type_name()), self.map_type_name(args[0].type_name()),
self.map_type_name(args[1].type_name()), self.map_type_name(args[1].type_name()),
), ),
NO_POS, Position::NONE,
) )
.into(); .into();
} }
@ -292,7 +292,7 @@ impl Engine {
self.map_type_name(args[0].type_name()), self.map_type_name(args[0].type_name()),
self.map_type_name(args[1].type_name()), self.map_type_name(args[1].type_name()),
), ),
NO_POS, Position::NONE,
) )
.into(); .into();
} }
@ -311,13 +311,13 @@ impl Engine {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
), ),
NO_POS, Position::NONE,
) )
.into() .into()
} }
/// Call a script-defined function. /// Call a script-defined function.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
/// ///
/// ## WARNING /// ## WARNING
/// ///
@ -342,7 +342,7 @@ impl Engine {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if level > self.max_call_levels() { if level > self.max_call_levels() {
return Err(Box::new(EvalAltResult::ErrorStackOverflow(NO_POS))); return Err(Box::new(EvalAltResult::ErrorStackOverflow(Position::NONE)));
} }
let orig_scope_level = state.scope_level; let orig_scope_level = state.scope_level;
@ -385,25 +385,27 @@ impl Engine {
// Evaluate the function at one higher level of call depth // Evaluate the function at one higher level of call depth
let stmt = &fn_def.body; let stmt = &fn_def.body;
let result = let result = self
self.eval_stmt(scope, mods, state, unified_lib, this_ptr, stmt, level + 1) .eval_stmt(scope, mods, state, unified_lib, this_ptr, stmt, level + 1)
.or_else(|err| match *err { .or_else(|err| match *err {
// Convert return statement to return value // Convert return statement to return value
EvalAltResult::Return(x, _) => Ok(x), EvalAltResult::Return(x, _) => Ok(x),
EvalAltResult::ErrorInFunctionCall(name, err, _) => { EvalAltResult::ErrorInFunctionCall(name, err, _) => {
EvalAltResult::ErrorInFunctionCall( EvalAltResult::ErrorInFunctionCall(
format!("{} > {}", fn_def.name, name), format!("{} > {}", fn_def.name, name),
err, err,
NO_POS, Position::NONE,
) )
.into()
}
// System errors are passed straight-through
err if err.is_system_exception() => Err(Box::new(err)),
// Other errors are wrapped in `ErrorInFunctionCall`
_ => {
EvalAltResult::ErrorInFunctionCall(fn_def.name.to_string(), err, Position::NONE)
.into() .into()
} }
// System errors are passed straight-through });
err if err.is_system_exception() => Err(Box::new(err)),
// Other errors are wrapped in `ErrorInFunctionCall`
_ => EvalAltResult::ErrorInFunctionCall(fn_def.name.to_string(), err, NO_POS)
.into(),
});
// Remove all local variables // Remove all local variables
scope.rewind(prev_scope_len); scope.rewind(prev_scope_len);
@ -457,7 +459,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.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
/// ///
/// ## WARNING /// ## WARNING
/// ///
@ -476,7 +478,7 @@ impl Engine {
_is_method: bool, _is_method: bool,
pub_only: bool, pub_only: bool,
_capture_scope: Option<Scope>, _capture_scope: Option<Scope>,
def_val: Option<Dynamic>, def_val: Option<&Dynamic>,
_level: usize, _level: usize,
) -> Result<(Dynamic, bool), Box<EvalAltResult>> { ) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
// Check for data race. // Check for data race.
@ -512,7 +514,7 @@ impl Engine {
fn_name, fn_name fn_name, fn_name
) )
.into(), .into(),
NO_POS, Position::NONE,
) )
.into() .into()
} }
@ -606,7 +608,7 @@ impl Engine {
} }
/// Evaluate a list of statements with an empty state and no `this` pointer. /// Evaluate a list of statements with an empty state and no `this` pointer.
/// This is commonly used to evaluate a list of statements in an `AST` or a script function body. /// This is commonly used to evaluate a list of statements in an [`AST`] or a script function body.
#[inline] #[inline]
pub(crate) fn eval_statements_raw<'a>( pub(crate) fn eval_statements_raw<'a>(
&self, &self,
@ -631,7 +633,7 @@ impl Engine {
} }
/// Evaluate a text string as a script - used primarily for 'eval'. /// Evaluate a text string as a script - used primarily for 'eval'.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
fn eval_script_expr( fn eval_script_expr(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -652,7 +654,7 @@ impl Engine {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if _level > self.max_call_levels() { if _level > self.max_call_levels() {
return Err(Box::new(EvalAltResult::ErrorStackOverflow(NO_POS))); return Err(Box::new(EvalAltResult::ErrorStackOverflow(Position::NONE)));
} }
// Compile the script text // Compile the script text
@ -678,7 +680,7 @@ impl Engine {
} }
/// Call a dot method. /// Call a dot method.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub(crate) fn make_method_call( pub(crate) fn make_method_call(
&self, &self,
@ -689,7 +691,7 @@ impl Engine {
hash_script: u64, hash_script: u64,
target: &mut crate::engine::Target, target: &mut crate::engine::Target,
mut call_args: StaticVec<Dynamic>, mut call_args: StaticVec<Dynamic>,
def_val: Option<Dynamic>, def_val: Option<&Dynamic>,
native: bool, native: bool,
pub_only: bool, pub_only: bool,
level: usize, level: usize,
@ -830,7 +832,7 @@ impl Engine {
} }
/// Call a function in normal function-call style. /// Call a function in normal function-call style.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
pub(crate) fn make_function_call( pub(crate) fn make_function_call(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -840,7 +842,7 @@ impl Engine {
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
fn_name: &str, fn_name: &str,
args_expr: impl AsRef<[Expr]>, args_expr: impl AsRef<[Expr]>,
def_val: Option<Dynamic>, def_val: Option<&Dynamic>,
mut hash_script: u64, mut hash_script: u64,
native: bool, native: bool,
pub_only: bool, pub_only: bool,
@ -1075,7 +1077,7 @@ impl Engine {
} }
/// Call a namespace-qualified function in normal function-call style. /// Call a namespace-qualified function in normal function-call style.
/// Position in `EvalAltResult` is `None` and must be set afterwards. /// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
pub(crate) fn make_qualified_function_call( pub(crate) fn make_qualified_function_call(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1086,7 +1088,7 @@ impl Engine {
namespace: Option<&NamespaceRef>, namespace: Option<&NamespaceRef>,
fn_name: &str, fn_name: &str,
args_expr: impl AsRef<[Expr]>, args_expr: impl AsRef<[Expr]>,
def_val: Option<bool>, def_val: Option<&Dynamic>,
hash_script: u64, hash_script: u64,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
@ -1202,7 +1204,7 @@ impl Engine {
f.get_native_fn().clone()((self, &*mods, lib).into(), args.as_mut()) f.get_native_fn().clone()((self, &*mods, lib).into(), args.as_mut())
} }
Some(_) => unreachable!(), Some(_) => unreachable!(),
None if def_val.is_some() => Ok(def_val.unwrap().into()), None if def_val.is_some() => Ok(def_val.unwrap().clone()),
None => EvalAltResult::ErrorFunctionNotFound( None => EvalAltResult::ErrorFunctionNotFound(
format!( format!(
"{}{} ({})", "{}{} ({})",
@ -1217,7 +1219,7 @@ impl Engine {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
), ),
NO_POS, Position::NONE,
) )
.into(), .into(),
} }

View File

@ -11,8 +11,8 @@ use crate::{Engine, EvalAltResult, ParseError, Scope, AST};
pub trait Func<ARGS, RET> { 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,7 +43,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

@ -7,7 +7,7 @@ use crate::stdlib::{boxed::Box, convert::TryFrom, fmt, iter::empty, mem, string:
use crate::token::is_valid_identifier; use crate::token::is_valid_identifier;
use crate::{ use crate::{
calc_script_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module,
StaticVec, NO_POS, Position, StaticVec,
}; };
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
@ -78,7 +78,7 @@ impl<'e, 'm, 'pm: 'm, M: AsRef<[&'pm Module]> + ?Sized> From<(&'e Engine, &'m M)
} }
impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> { impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
/// Create a new `NativeCallContext`. /// Create a new [`NativeCallContext`].
#[inline(always)] #[inline(always)]
pub fn new(engine: &'e Engine, lib: &'m impl AsRef<[&'pm Module]>) -> Self { pub fn new(engine: &'e Engine, lib: &'m impl AsRef<[&'pm Module]>) -> Self {
Self { Self {
@ -87,7 +87,7 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
lib: lib.as_ref(), lib: lib.as_ref(),
} }
} }
/// _[INTERNALS]_ Create a new `NativeCallContext`. /// _(INTERNALS)_ Create a new [`NativeCallContext`].
/// Available under the `internals` feature only. /// Available under the `internals` feature only.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
@ -103,12 +103,12 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
lib: lib.as_ref(), lib: lib.as_ref(),
} }
} }
/// The current `Engine`. /// The current [`Engine`].
#[inline(always)] #[inline(always)]
pub fn engine(&self) -> &'e Engine { pub fn engine(&self) -> &'e Engine {
self.engine self.engine
} }
/// _[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.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
@ -127,10 +127,11 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
/// ///
/// 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.
///
/// Do not use the arguments after this call. If they are needed afterwards, /// Do not use the arguments after this call. If they are needed afterwards,
/// clone them _before_ calling this function. /// clone them _before_ calling this function.
/// ///
/// If `is_method` is `true`, the first argument is assumed to be passed /// If `is_method` is [`true`], the first argument is assumed to be passed
/// by reference and is not consumed. /// by reference and is not consumed.
pub fn call_fn_dynamic_raw( pub fn call_fn_dynamic_raw(
&mut self, &mut self,
@ -138,7 +139,7 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
is_method: bool, is_method: bool,
public_only: bool, public_only: bool,
args: &mut [&mut Dynamic], args: &mut [&mut Dynamic],
def_value: Option<Dynamic>, def_value: Option<&Dynamic>,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
let mut mods = self.mods.cloned().unwrap_or_default(); let mut mods = self.mods.cloned().unwrap_or_default();
@ -171,7 +172,7 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
} }
} }
/// Consume a `Shared` resource and return a mutable reference to the wrapped value. /// Consume a [`Shared`] resource and return a mutable reference to the wrapped value.
/// If the resource is shared (i.e. has other outstanding references), a cloned copy is used. /// If the resource is shared (i.e. has other outstanding references), a cloned copy is used.
#[inline(always)] #[inline(always)]
pub fn shared_make_mut<T: Clone>(value: &mut Shared<T>) -> &mut T { pub fn shared_make_mut<T: Clone>(value: &mut Shared<T>) -> &mut T {
@ -181,13 +182,13 @@ pub fn shared_make_mut<T: Clone>(value: &mut Shared<T>) -> &mut T {
return Arc::make_mut(value); return Arc::make_mut(value);
} }
/// Consume a `Shared` resource if is unique (i.e. not shared), or clone it otherwise. /// Consume a [`Shared`] resource if is unique (i.e. not shared), or clone it otherwise.
#[inline(always)] #[inline(always)]
pub fn shared_take_or_clone<T: Clone>(value: Shared<T>) -> T { pub fn shared_take_or_clone<T: Clone>(value: Shared<T>) -> T {
shared_try_take(value).unwrap_or_else(|v| v.as_ref().clone()) shared_try_take(value).unwrap_or_else(|v| v.as_ref().clone())
} }
/// Consume a `Shared` resource if is unique (i.e. not shared). /// Consume a [`Shared`] resource if is unique (i.e. not shared).
#[inline(always)] #[inline(always)]
pub fn shared_try_take<T>(value: Shared<T>) -> Result<T, Shared<T>> { pub fn shared_try_take<T>(value: Shared<T>) -> Result<T, Shared<T>> {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
@ -196,7 +197,7 @@ pub fn shared_try_take<T>(value: Shared<T>) -> Result<T, Shared<T>> {
return Arc::try_unwrap(value); return Arc::try_unwrap(value);
} }
/// Consume a `Shared` resource, assuming that it is unique (i.e. not shared). /// Consume a [`Shared`] resource, assuming that it is unique (i.e. not shared).
/// ///
/// # Panics /// # Panics
/// ///
@ -300,7 +301,7 @@ impl TryFrom<ImmutableString> for FnPtr {
if is_valid_identifier(value.chars()) { if is_valid_identifier(value.chars()) {
Ok(Self(value, Default::default())) Ok(Self(value, Default::default()))
} else { } else {
EvalAltResult::ErrorFunctionNotFound(value.into(), NO_POS).into() EvalAltResult::ErrorFunctionNotFound(value.into(), Position::NONE).into()
} }
} }
} }
@ -485,7 +486,8 @@ impl CallableFunction {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the `CallableFunction` is not `Pure` or `Method`. /// Panics if the [`CallableFunction`] is not [`Pure`][CallableFunction::Pure] or
/// [`Method`][CallableFunction::Method].
pub fn get_native_fn(&self) -> &Shared<FnAny> { pub fn get_native_fn(&self) -> &Shared<FnAny> {
match self { match self {
Self::Pure(f) | Self::Method(f) => f, Self::Pure(f) | Self::Method(f) => f,
@ -499,7 +501,7 @@ impl CallableFunction {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the `CallableFunction` is not `Script`. /// Panics if the [`CallableFunction`] is not [`Script`][CallableFunction::Script].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub fn get_fn_def(&self) -> &Shared<ScriptFnDef> { pub fn get_fn_def(&self) -> &Shared<ScriptFnDef> {
match self { match self {
@ -511,7 +513,7 @@ impl CallableFunction {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the `CallableFunction` is not `Iterator`. /// Panics if the [`CallableFunction`] is not [`Iterator`][CallableFunction::Iterator].
pub fn get_iter_fn(&self) -> IteratorFn { pub fn get_iter_fn(&self) -> IteratorFn {
match self { match self {
Self::Iterator(f) => *f, Self::Iterator(f) => *f,
@ -525,7 +527,7 @@ impl CallableFunction {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the `CallableFunction` is not `Plugin`. /// Panics if the [`CallableFunction`] is not [`Plugin`][CallableFunction::Plugin].
pub fn get_plugin_fn<'s>(&'s self) -> &Shared<FnPlugin> { pub fn get_plugin_fn<'s>(&'s self) -> &Shared<FnPlugin> {
match self { match self {
Self::Plugin(f) => f, Self::Plugin(f) => f,
@ -535,17 +537,17 @@ impl CallableFunction {
Self::Script(_) => unreachable!(), Self::Script(_) => unreachable!(),
} }
} }
/// Create a new `CallableFunction::Pure`. /// Create a new [`CallableFunction::Pure`].
#[inline(always)] #[inline(always)]
pub fn from_pure(func: Box<FnAny>) -> Self { pub fn from_pure(func: Box<FnAny>) -> Self {
Self::Pure(func.into()) Self::Pure(func.into())
} }
/// Create a new `CallableFunction::Method`. /// Create a new [`CallableFunction::Method`].
#[inline(always)] #[inline(always)]
pub fn from_method(func: Box<FnAny>) -> Self { pub fn from_method(func: Box<FnAny>) -> Self {
Self::Method(func.into()) Self::Method(func.into())
} }
/// Create a new `CallableFunction::Plugin`. /// Create a new [`CallableFunction::Plugin`].
#[inline(always)] #[inline(always)]
pub fn from_plugin(func: impl PluginFunction + 'static + SendSync) -> Self { pub fn from_plugin(func: impl PluginFunction + 'static + SendSync) -> Self {
Self::Plugin((Box::new(func) as Box<FnPlugin>).into()) Self::Plugin((Box::new(func) as Box<FnPlugin>).into())

View File

@ -50,7 +50,7 @@
//! //!
//! # Documentation //! # Documentation
//! //!
//! See [The Rhai Book](https://schungx.github.io/rhai) for details on the Rhai script engine and language. //! See [The Rhai Book](https://schungx.github.io/rhai) for details on the Rhai scripting engine and language.
#![cfg_attr(feature = "no_std", no_std)] #![cfg_attr(feature = "no_std", no_std)]
@ -121,7 +121,7 @@ pub use parse_error::{LexError, ParseError, ParseErrorType};
pub use result::EvalAltResult; pub use result::EvalAltResult;
pub use scope::Scope; pub use scope::Scope;
pub use syntax::Expression; pub use syntax::Expression;
pub use token::{Position, NO_POS}; pub use token::Position;
pub use utils::ImmutableString; pub use utils::ImmutableString;
#[allow(dead_code)] #[allow(dead_code)]
@ -157,7 +157,7 @@ pub use module::ModuleResolver;
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
pub use crate::module::resolvers as module_resolvers; pub use crate::module::resolvers as module_resolvers;
/// _[SERDE]_ Serialization and deserialization support for [`serde`](https://crates.io/crates/serde). /// _(SERDE)_ Serialization and deserialization support for [`serde`](https://crates.io/crates/serde).
/// Exported under the `serde` feature. /// Exported under the `serde` feature.
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
pub mod serde { pub mod serde {
@ -187,13 +187,13 @@ pub use engine::{Imports, Limits, State as EvalState};
#[deprecated(note = "this type is volatile and may change")] #[deprecated(note = "this type is volatile and may change")]
pub use module::NamespaceRef; pub use module::NamespaceRef;
/// _[INTERNALS]_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec), /// _(INTERNALS)_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec),
/// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored. /// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
type StaticVec<T> = smallvec::SmallVec<[T; 4]>; type StaticVec<T> = smallvec::SmallVec<[T; 4]>;
/// _[INTERNALS]_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec), /// _(INTERNALS)_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec),
/// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored. /// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]

View File

@ -20,7 +20,7 @@ use crate::stdlib::{
use crate::token::Token; use crate::token::Token;
use crate::utils::StraightHasherBuilder; use crate::utils::StraightHasherBuilder;
use crate::{ use crate::{
Dynamic, EvalAltResult, ImmutableString, NativeCallContext, Shared, StaticVec, NO_POS, Dynamic, EvalAltResult, ImmutableString, NativeCallContext, Position, Shared, StaticVec,
}; };
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
@ -264,7 +264,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`][crate::Dynamic].
/// ///
/// # Example /// # Example
/// ///
@ -303,15 +303,15 @@ 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 must be set afterwards. /// Name and Position in `EvalAltResult` are None and must be set afterwards.
/// ///
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash`. /// The [`u64`] hash is calculated by the function [`crate::calc_native_fn_hash`].
#[inline(always)] #[inline(always)]
pub(crate) fn get_qualified_var(&self, hash_var: u64) -> Result<&Dynamic, Box<EvalAltResult>> { pub(crate) fn get_qualified_var(&self, hash_var: u64) -> Result<&Dynamic, Box<EvalAltResult>> {
if hash_var == 0 { if hash_var == 0 {
Err(EvalAltResult::ErrorVariableNotFound(String::new(), NO_POS).into()) Err(EvalAltResult::ErrorVariableNotFound(String::new(), Position::NONE).into())
} else { } else {
self.all_variables self.all_variables.get(&hash_var).ok_or_else(|| {
.get(&hash_var) EvalAltResult::ErrorVariableNotFound(String::new(), Position::NONE).into()
.ok_or_else(|| EvalAltResult::ErrorVariableNotFound(String::new(), NO_POS).into()) })
} }
} }
@ -443,7 +443,7 @@ impl Module {
/// Does the particular Rust function exist in the module? /// Does the particular Rust function exist in the module?
/// ///
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash`. /// The [`u64`] hash is calculated by the function [`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
@ -517,12 +517,13 @@ impl Module {
hash_fn hash_fn
} }
/// Set a Rust function taking a reference to the scripting `Engine`, the current set of functions, /// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine],
/// plus a list of mutable `Dynamic` references into the module, returning a hash key. /// the current set of functions, plus a list of mutable [`Dynamic`][crate::Dynamic] references
/// 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` (e.g. to prevent growing an array beyond the allowed maximum size), or to call a /// [`Engine`][crate::Engine] (e.g. to prevent growing an array beyond the allowed maximum size),
/// script-defined function in the current evaluation context. /// or to call a script-defined function in the current evaluation context.
/// ///
/// If there is a similar existing Rust function, it is replaced. /// If there is a similar existing Rust function, it is replaced.
/// ///
@ -530,9 +531,9 @@ impl Module {
/// ///
/// 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`][crate::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.
@ -843,7 +844,7 @@ impl Module {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`] or [`Map`].
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -979,7 +980,7 @@ impl Module {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`] or [`Map`].
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -1032,13 +1033,14 @@ impl Module {
} }
/// Set a pair of Rust index getter and setter functions, returning both hash keys. /// Set a pair of Rust index getter and setter functions, returning both hash keys.
/// This is a short-hand for `set_indexer_get_fn` and `set_indexer_set_fn`. /// This is a short-hand for [`set_indexer_get_fn`][Module::set_indexer_get_fn] and
/// [`set_indexer_set_fn`][Module::set_indexer_set_fn].
/// ///
/// If there are similar existing Rust functions, they are replaced. /// If there are similar existing Rust functions, they are replaced.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if the type is `Array` or `Map`. /// Panics if the type is [`Array`] or [`Map`].
/// Indexers for arrays, object maps and strings cannot be registered. /// Indexers for arrays, object maps and strings cannot be registered.
/// ///
/// # Example /// # Example
@ -1179,7 +1181,7 @@ impl Module {
/// Get a Rust function. /// Get a Rust function.
/// ///
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash`. /// The [`u64`] hash is calculated by the function [`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(&self, hash_fn: u64, public_only: bool) -> Option<&CallableFunction> { pub(crate) fn get_fn(&self, hash_fn: u64, public_only: bool) -> Option<&CallableFunction> {
@ -1198,8 +1200,8 @@ impl Module {
/// Does the particular namespace-qualified function exist in the module? /// Does the particular namespace-qualified function exist in the module?
/// ///
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash` and must match /// The [`u64`] hash is calculated by the function [`crate::calc_native_fn_hash`] and must match
/// the hash calculated by `build_index`. /// the hash calculated by [`build_index`][Module::build_index].
#[inline] #[inline]
pub fn contains_qualified_fn(&self, hash_fn: u64) -> bool { pub fn contains_qualified_fn(&self, hash_fn: u64) -> bool {
self.all_functions.contains_key(&hash_fn) self.all_functions.contains_key(&hash_fn)
@ -1208,8 +1210,8 @@ impl Module {
/// Get a namespace-qualified function. /// Get a namespace-qualified function.
/// Name and Position in `EvalAltResult` are None and must be set afterwards. /// Name and Position in `EvalAltResult` are None and must be set afterwards.
/// ///
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash` and must match /// The [`u64`] hash is calculated by the function [`crate::calc_native_fn_hash`] and must match
/// the hash calculated by `build_index`. /// the hash calculated by [`build_index`][Module::build_index].
#[inline(always)] #[inline(always)]
pub(crate) fn get_qualified_fn(&self, hash_qualified_fn: u64) -> Option<&CallableFunction> { pub(crate) fn get_qualified_fn(&self, hash_qualified_fn: u64) -> Option<&CallableFunction> {
self.all_functions.get(&hash_qualified_fn) self.all_functions.get(&hash_qualified_fn)
@ -1394,10 +1396,11 @@ 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) Access mode (`FnAccess::Public` or `FnAccess::Private`). /// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]).
/// 2) Function name (as string slice). /// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]).
/// 3) Number of parameters. /// 3) Function name (as string slice).
/// 4) Shared reference to function definition `ScriptFnDef`. /// 4) Number of parameters.
/// 5) Shared reference to function definition [`ScriptFnDef`][crate::ScriptFnDef].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub(crate) fn iter_script_fn<'a>( pub(crate) fn iter_script_fn<'a>(
@ -1426,9 +1429,10 @@ 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) Access mode (`FnAccess::Public` or `FnAccess::Private`). /// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]).
/// 2) Function name (as string slice). /// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]).
/// 3) Number of parameters. /// 3) Function name (as string slice).
/// 4) Number of parameters.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
#[inline(always)] #[inline(always)]
@ -1449,11 +1453,12 @@ 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) Access mode (`FnAccess::Public` or `FnAccess::Private`). /// 1) Namespace ([`FnNamespace::Global`] or [`FnNamespace::Internal`]).
/// 2) Function name (as string slice). /// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]).
/// 3) Number of parameters. /// 3) Function name (as string slice).
/// 4) _[INTERNALS]_ Shared reference to function definition `ScriptFnDef`. /// 4) Number of parameters.
/// Exported under the internals feature only. /// 5) _(INTERNALS)_ Shared reference to function definition [`ScriptFnDef`][crate::ScriptFnDef].
/// Exported under the `internals` feature only.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[inline(always)] #[inline(always)]
@ -1463,9 +1468,9 @@ impl Module {
self.iter_script_fn() self.iter_script_fn()
} }
/// Create a new `Module` by evaluating an `AST`. /// Create a new module by evaluating an [`AST`][crate::AST].
/// ///
/// The entire `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.
@ -1602,7 +1607,7 @@ impl Module {
// 1) Calculate a hash in a similar manner to script-defined functions, // 1) Calculate a hash in a similar manner to script-defined functions,
// i.e. qualifiers + function name + number of arguments. // i.e. qualifiers + function name + number of arguments.
// 2) Calculate a second hash with no qualifiers, empty function name, // 2) Calculate a second hash with no qualifiers, empty function name,
// and the actual list of argument `TypeId`'.s // and the actual list of argument [`TypeId`]'.s
let hash_fn_args = crate::calc_native_fn_hash( let hash_fn_args = crate::calc_native_fn_hash(
empty(), empty(),
"", "",
@ -1692,13 +1697,13 @@ impl Module {
} }
} }
/// _[INTERNALS]_ A chain of module names to namespace-qualify a variable or function call. /// _(INTERNALS)_ A chain of module names to namespace-qualify a variable or function call.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// A `u64` hash key is cached for quick search purposes. /// A [`u64`] hash key is cached for quick search purposes.
/// ///
/// 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
/// ///

View File

@ -22,7 +22,7 @@ use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
pub struct ModuleResolversCollection(Vec<Box<dyn ModuleResolver>>); pub struct ModuleResolversCollection(Vec<Box<dyn ModuleResolver>>);
impl ModuleResolversCollection { impl ModuleResolversCollection {
/// Create a new `ModuleResolversCollection`. /// Create a new [`ModuleResolversCollection`].
/// ///
/// # Example /// # Example
/// ///
@ -62,18 +62,18 @@ impl ModuleResolversCollection {
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.0.clear(); self.0.clear();
} }
/// Is this `ModuleResolversCollection` empty? /// Is this [`ModuleResolversCollection`] empty?
#[inline(always)] #[inline(always)]
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 in this [`ModuleResolversCollection`].
#[inline(always)] #[inline(always)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.0.len() self.0.len()
} }
/// Add another `ModuleResolversCollection` to the end of this collection. /// Add another [`ModuleResolversCollection`] to the end of this collection.
/// The other `ModuleResolversCollection` is consumed. /// The other [`ModuleResolversCollection`] is consumed.
#[inline(always)] #[inline(always)]
pub fn append(&mut self, other: Self) { pub fn append(&mut self, other: Self) {
self.0.extend(other.0.into_iter()); self.0.extend(other.0.into_iter());

View File

@ -7,7 +7,8 @@ use crate::{Engine, EvalAltResult, Locked, Module, ModuleResolver, Position, Sha
/// ///
/// 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` and `new_with_path_and_extension` constructor functions /// 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 /// 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 /// to the base directory. The script file is then forced to be in a specified extension
/// (default `.rhai`). /// (default `.rhai`).
@ -47,7 +48,7 @@ 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.
/// ///
/// # Example /// # Example
/// ///
@ -67,7 +68,7 @@ impl FileModuleResolver {
Self::new_with_path_and_extension(path, "rhai") Self::new_with_path_and_extension(path, "rhai")
} }
/// 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`. /// The default extension is `.rhai`.
/// ///
@ -96,7 +97,7 @@ impl FileModuleResolver {
} }
} }
/// Create a new `FileModuleResolver` with the current directory as base path. /// Create a new [`FileModuleResolver`] with the current directory as base path.
/// ///
/// # Example /// # Example
/// ///

View File

@ -22,7 +22,7 @@ use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
pub struct StaticModuleResolver(HashMap<String, Shared<Module>>); pub struct StaticModuleResolver(HashMap<String, Shared<Module>>);
impl StaticModuleResolver { impl StaticModuleResolver {
/// Create a new `StaticModuleResolver`. /// Create a new [`StaticModuleResolver`].
/// ///
/// # Example /// # Example
/// ///
@ -83,18 +83,18 @@ impl StaticModuleResolver {
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.0.clear(); self.0.clear();
} }
/// Is this `StaticModuleResolver` empty? /// Is this [`StaticModuleResolver`] empty?
#[inline(always)] #[inline(always)]
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 in this [`StaticModuleResolver`].
#[inline(always)] #[inline(always)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.0.len() self.0.len()
} }
/// Merge another `StaticModuleResolver` into this. /// Merge another [`StaticModuleResolver`] into this.
/// The other `StaticModuleResolver` is consumed. /// The other [`StaticModuleResolver`] is consumed.
#[inline(always)] #[inline(always)]
pub fn merge(&mut self, other: Self) { pub fn merge(&mut self, other: Self) {
if !other.is_empty() { if !other.is_empty() {

View File

@ -18,9 +18,7 @@ use crate::stdlib::{
}; };
use crate::token::is_valid_identifier; use crate::token::is_valid_identifier;
use crate::utils::get_hasher; use crate::utils::get_hasher;
use crate::{ use crate::{calc_native_fn_hash, Dynamic, Engine, Module, Position, Scope, StaticVec, AST};
calc_native_fn_hash, Dynamic, Engine, Module, Position, Scope, StaticVec, AST, NO_POS,
};
/// Level of optimization performed. /// Level of optimization performed.
/// ///
@ -703,7 +701,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
Some(arg_for_type_of.to_string().into()) Some(arg_for_type_of.to_string().into())
} else { } else {
// Otherwise use the default value, if any // Otherwise use the default value, if any
x.def_value.map(|v| v.into()) x.def_value.clone()
} }
}) })
.and_then(|result| map_dynamic_to_expr(result, *pos)) .and_then(|result| map_dynamic_to_expr(result, *pos))
@ -759,7 +757,7 @@ fn optimize(
.iter() .iter()
.filter(|(_, typ, _)| *typ) .filter(|(_, typ, _)| *typ)
.for_each(|(name, _, value)| { .for_each(|(name, _, value)| {
if let Some(val) = map_dynamic_to_expr(value, NO_POS) { if let Some(val) = map_dynamic_to_expr(value, Position::NONE) {
state.push_constant(name, val); state.push_constant(name, val);
} }
}); });

View File

@ -2,7 +2,7 @@
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::{format, string::String}; use crate::stdlib::{format, string::String};
use crate::{def_package, EvalAltResult, INT, NO_POS}; use crate::{def_package, EvalAltResult, Position, INT};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
@ -13,7 +13,7 @@ use num_traits::float::Float;
#[inline(always)] #[inline(always)]
pub fn make_err(msg: impl Into<String>) -> Box<EvalAltResult> { pub fn make_err(msg: impl Into<String>) -> Box<EvalAltResult> {
EvalAltResult::ErrorArithmetic(msg.into(), NO_POS).into() EvalAltResult::ErrorArithmetic(msg.into(), Position::NONE).into()
} }
macro_rules! gen_arithmetic_functions { macro_rules! gen_arithmetic_functions {

View File

@ -5,8 +5,8 @@ use crate::engine::{OP_EQUALS, TYPICAL_ARRAY_SIZE};
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::{any::TypeId, boxed::Box, cmp::max, cmp::Ordering, string::ToString}; use crate::stdlib::{any::TypeId, boxed::Box, cmp::max, cmp::Ordering, string::ToString};
use crate::{ use crate::{
def_package, Array, Dynamic, EvalAltResult, FnPtr, ImmutableString, NativeCallContext, INT, def_package, Array, Dynamic, EvalAltResult, FnPtr, ImmutableString, NativeCallContext,
NO_POS, Position, INT,
}; };
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
@ -42,7 +42,7 @@ macro_rules! gen_array_functions {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_array_size() > 0 && len > 0 && (len as usize) > _ctx.engine().max_array_size() { if _ctx.engine().max_array_size() > 0 && len > 0 && (len as usize) > _ctx.engine().max_array_size() {
return EvalAltResult::ErrorDataTooLarge( return EvalAltResult::ErrorDataTooLarge(
"Size of array".to_string(), NO_POS "Size of array".to_string(), Position::NONE
).into(); ).into();
} }
@ -215,7 +215,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"map".to_string(), "map".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?, })?,
); );
@ -246,7 +246,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"filter".to_string(), "filter".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})? })?
.as_bool() .as_bool()
@ -279,7 +279,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"index_of".to_string(), "index_of".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})? })?
.as_bool() .as_bool()
@ -312,7 +312,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"some".to_string(), "some".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})? })?
.as_bool() .as_bool()
@ -345,7 +345,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"all".to_string(), "all".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})? })?
.as_bool() .as_bool()
@ -380,7 +380,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce".to_string(), "reduce".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?; })?;
} }
@ -398,7 +398,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce".to_string(), "reduce".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?; })?;
@ -417,7 +417,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce".to_string(), "reduce".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?; })?;
} }
@ -447,7 +447,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce_rev".to_string(), "reduce_rev".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?; })?;
} }
@ -465,7 +465,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce_rev".to_string(), "reduce_rev".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?; })?;
@ -484,7 +484,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce_rev".to_string(), "reduce_rev".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})?; })?;
} }
@ -554,7 +554,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"drain".to_string(), "drain".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})? })?
.as_bool() .as_bool()
@ -613,7 +613,7 @@ mod array_functions {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"retain".to_string(), "retain".to_string(),
err, err,
NO_POS, Position::NONE,
)) ))
})? })?
.as_bool() .as_bool()
@ -665,7 +665,7 @@ mod array_functions {
for (a1, a2) in arr1.iter_mut().zip(arr2.iter_mut()) { for (a1, a2) in arr1.iter_mut().zip(arr2.iter_mut()) {
let equals = ctx let equals = ctx
.call_fn_dynamic_raw(OP_EQUALS, true, false, &mut [a1, a2], def_value.clone()) .call_fn_dynamic_raw(OP_EQUALS, true, false, &mut [a1, a2], def_value.as_ref())
.map(|v| v.as_bool().unwrap_or(false))?; .map(|v| v.as_bool().unwrap_or(false))?;
if !equals { if !equals {

View File

@ -61,7 +61,7 @@ mod map_functions {
for (m1, v1) in map1.iter_mut() { for (m1, v1) in map1.iter_mut() {
if let Some(v2) = map2.get_mut(m1) { if let Some(v2) = map2.get_mut(m1) {
let equals = ctx let equals = ctx
.call_fn_dynamic_raw(OP_EQUALS, true, false, &mut [v1, v2], def_value.clone()) .call_fn_dynamic_raw(OP_EQUALS, true, false, &mut [v1, v2], def_value.as_ref())
.map(|v| v.as_bool().unwrap_or(false))?; .map(|v| v.as_bool().unwrap_or(false))?;
if !equals { if !equals {

View File

@ -1,7 +1,7 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::plugin::*; use crate::plugin::*;
use crate::{def_package, INT, NO_POS}; use crate::{def_package, Position, INT};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
@ -83,8 +83,11 @@ mod int_functions {
#[rhai_fn(name = "parse_int", return_raw)] #[rhai_fn(name = "parse_int", return_raw)]
pub fn parse_int_radix(s: &str, radix: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn parse_int_radix(s: &str, radix: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if radix < 2 || radix > 36 { if radix < 2 || radix > 36 {
return EvalAltResult::ErrorArithmetic(format!("Invalid radix: '{}'", radix), NO_POS) return EvalAltResult::ErrorArithmetic(
.into(); format!("Invalid radix: '{}'", radix),
Position::NONE,
)
.into();
} }
INT::from_str_radix(s.trim(), radix as u32) INT::from_str_radix(s.trim(), radix as u32)
@ -92,7 +95,7 @@ mod int_functions {
.map_err(|err| { .map_err(|err| {
EvalAltResult::ErrorArithmetic( EvalAltResult::ErrorArithmetic(
format!("Error parsing integer number '{}': {}", s, err), format!("Error parsing integer number '{}': {}", s, err),
NO_POS, Position::NONE,
) )
.into() .into()
}) })
@ -201,8 +204,11 @@ mod float_functions {
#[rhai_fn(name = "to_int", return_raw)] #[rhai_fn(name = "to_int", return_raw)]
pub fn f32_to_int(x: f32) -> Result<Dynamic, Box<EvalAltResult>> { pub fn f32_to_int(x: f32) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f32) { if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f32) {
EvalAltResult::ErrorArithmetic(format!("Integer overflow: to_int({})", x), NO_POS) EvalAltResult::ErrorArithmetic(
.into() format!("Integer overflow: to_int({})", x),
Position::NONE,
)
.into()
} else { } else {
Ok((x.trunc() as INT).into()) Ok((x.trunc() as INT).into())
} }
@ -210,8 +216,11 @@ mod float_functions {
#[rhai_fn(name = "to_int", return_raw)] #[rhai_fn(name = "to_int", return_raw)]
pub fn f64_to_int(x: f64) -> Result<Dynamic, Box<EvalAltResult>> { pub fn f64_to_int(x: f64) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f64) { if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f64) {
EvalAltResult::ErrorArithmetic(format!("Integer overflow: to_int({})", x), NO_POS) EvalAltResult::ErrorArithmetic(
.into() format!("Integer overflow: to_int({})", x),
Position::NONE,
)
.into()
} else { } else {
Ok((x.trunc() as INT).into()) Ok((x.trunc() as INT).into())
} }
@ -224,7 +233,7 @@ mod float_functions {
.map_err(|err| { .map_err(|err| {
EvalAltResult::ErrorArithmetic( EvalAltResult::ErrorArithmetic(
format!("Error parsing floating-point number '{}': {}", s, err), format!("Error parsing floating-point number '{}': {}", s, err),
NO_POS, Position::NONE,
) )
.into() .into()
}) })

View File

@ -44,16 +44,16 @@ pub trait Package {
fn get(&self) -> PackageLibrary; fn get(&self) -> PackageLibrary;
} }
/// A sharable `Module` to facilitate sharing library instances. /// A sharable [`Module`][crate::Module] to facilitate sharing library instances.
pub type PackageLibrary = Shared<Module>; pub type PackageLibrary = Shared<Module>;
/// Type containing a collection of `PackageLibrary` instances. /// Type containing a collection of [`PackageLibrary`] instances.
/// All function and type iterator keys in the loaded packages are indexed for fast access. /// All function and type iterator keys in the loaded packages are indexed for fast access.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub(crate) struct PackagesCollection(Option<StaticVec<PackageLibrary>>); pub(crate) struct PackagesCollection(Option<StaticVec<PackageLibrary>>);
impl PackagesCollection { impl PackagesCollection {
/// Add a `PackageLibrary` into the `PackagesCollection`. /// Add a [`PackageLibrary`] into the [`PackagesCollection`].
/// ///
/// Packages are searched in reverse order. /// Packages are searched in reverse order.
pub fn add(&mut self, package: PackageLibrary) { pub fn add(&mut self, package: PackageLibrary) {
@ -63,7 +63,7 @@ impl PackagesCollection {
// Later packages override previous ones. // Later packages override previous ones.
self.0.as_mut().unwrap().insert(0, package); self.0.as_mut().unwrap().insert(0, package);
} }
/// Does the specified function hash key exist in the `PackagesCollection`? /// Does the specified function hash key exist in the [`PackagesCollection`]?
#[allow(dead_code)] #[allow(dead_code)]
pub fn contains_fn(&self, hash: u64) -> bool { pub fn contains_fn(&self, hash: u64) -> bool {
self.0 self.0
@ -76,14 +76,14 @@ impl PackagesCollection {
.as_ref() .as_ref()
.and_then(|x| x.iter().find_map(|p| p.get_fn(hash, false))) .and_then(|x| x.iter().find_map(|p| p.get_fn(hash, false)))
} }
/// Does the specified TypeId iterator exist in the `PackagesCollection`? /// Does the specified [`TypeId`] iterator exist in the [`PackagesCollection`]?
#[allow(dead_code)] #[allow(dead_code)]
pub fn contains_iter(&self, id: TypeId) -> bool { pub fn contains_iter(&self, id: TypeId) -> bool {
self.0 self.0
.as_ref() .as_ref()
.map_or(false, |x| x.iter().any(|p| p.contains_iter(id))) .map_or(false, |x| x.iter().any(|p| p.contains_iter(id)))
} }
/// Get the specified TypeId iterator. /// Get the specified [`TypeId`] iterator.
pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> { pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
self.0 self.0
.as_ref() .as_ref()
@ -95,7 +95,7 @@ impl PackagesCollection {
/// and register functions into it. /// and register functions into it.
/// ///
/// Functions can be added to the package using the standard module methods such as /// Functions can be added to the package using the standard module methods such as
/// `set_fn_2`, `set_fn_3_mut`, `set_fn_0` etc. /// [`set_fn_2`][Module::set_fn_2], [`set_fn_3_mut`][Module::set_fn_3_mut], [`set_fn_0`][Module::set_fn_0] etc.
/// ///
/// # Example /// # Example
/// ///

View File

@ -252,7 +252,7 @@ mod string_functions {
if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() { if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() {
return crate::EvalAltResult::ErrorDataTooLarge( return crate::EvalAltResult::ErrorDataTooLarge(
"Length of string".to_string(), "Length of string".to_string(),
crate::NO_POS, crate::Position::NONE,
) )
.into(); .into();
} }
@ -272,7 +272,7 @@ mod string_functions {
{ {
return crate::EvalAltResult::ErrorDataTooLarge( return crate::EvalAltResult::ErrorDataTooLarge(
"Length of string".to_string(), "Length of string".to_string(),
crate::NO_POS, crate::Position::NONE,
) )
.into(); .into();
} }
@ -293,7 +293,7 @@ mod string_functions {
if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() { if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() {
return crate::EvalAltResult::ErrorDataTooLarge( return crate::EvalAltResult::ErrorDataTooLarge(
"Length of string".to_string(), "Length of string".to_string(),
crate::NO_POS, crate::Position::NONE,
) )
.into(); .into();
} }
@ -320,7 +320,7 @@ mod string_functions {
{ {
return crate::EvalAltResult::ErrorDataTooLarge( return crate::EvalAltResult::ErrorDataTooLarge(
"Length of string".to_string(), "Length of string".to_string(),
crate::NO_POS, crate::Position::NONE,
) )
.into(); .into();
} }

View File

@ -6,9 +6,9 @@ use crate::stdlib::{
fmt, fmt,
string::{String, ToString}, string::{String, ToString},
}; };
use crate::{EvalAltResult, Position, NO_POS}; 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
@ -65,7 +65,7 @@ impl LexError {
Self::ImproperSymbol(_) => "Invalid symbol encountered", Self::ImproperSymbol(_) => "Invalid symbol encountered",
} }
} }
/// Convert a `&LexError` into a `ParseError`. /// Convert a `&LexError` into a [`ParseError`].
#[inline(always)] #[inline(always)]
pub fn into_err(&self, pos: Position) -> ParseError { pub fn into_err(&self, pos: Position) -> ParseError {
ParseError(Box::new(self.clone().into()), pos) ParseError(Box::new(self.clone().into()), pos)
@ -160,7 +160,7 @@ pub enum ParseErrorType {
} }
impl ParseErrorType { impl ParseErrorType {
/// Make a `ParseError` using the current type and position. /// Make a [`ParseError`] using the current type and position.
#[inline(always)] #[inline(always)]
pub(crate) fn into_err(self, pos: Position) -> ParseError { pub(crate) fn into_err(self, pos: Position) -> ParseError {
ParseError(Box::new(self), pos) ParseError(Box::new(self), pos)
@ -281,7 +281,7 @@ impl fmt::Display for ParseError {
impl From<ParseErrorType> for Box<EvalAltResult> { impl From<ParseErrorType> for Box<EvalAltResult> {
#[inline(always)] #[inline(always)]
fn from(err: ParseErrorType) -> Self { fn from(err: ParseErrorType) -> Self {
Box::new(EvalAltResult::ErrorParsing(err, NO_POS)) Box::new(EvalAltResult::ErrorParsing(err, Position::NONE))
} }
} }

View File

@ -26,7 +26,7 @@ use crate::token::{is_keyword_function, is_valid_identifier, Token, TokenStream}
use crate::utils::{get_hasher, StraightHasherBuilder}; use crate::utils::{get_hasher, StraightHasherBuilder};
use crate::{ use crate::{
calc_script_fn_hash, Dynamic, Engine, FnAccess, ImmutableString, LexError, ParseError, calc_script_fn_hash, Dynamic, Engine, FnAccess, ImmutableString, LexError, ParseError,
ParseErrorType, Position, Scope, StaticVec, AST, NO_POS, ParseErrorType, Position, Scope, StaticVec, AST,
}; };
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
@ -1195,7 +1195,7 @@ fn parse_unary(
native_only: true, native_only: true,
hash, hash,
args, args,
def_value: Some(false), // NOT operator, when operating on invalid operand, defaults to false def_value: Some(false.into()), // NOT operator, when operating on invalid operand, defaults to false
..Default::default() ..Default::default()
}), }),
pos, pos,
@ -1652,7 +1652,7 @@ fn parse_binary_op(
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
settings.ensure_level_within_max_limit(state.max_expr_depth)?; settings.ensure_level_within_max_limit(state.max_expr_depth)?;
let cmp_def = Some(false); let cmp_def = Some(false.into());
let op = op_token.syntax(); let op = op_token.syntax();
let hash = calc_script_fn_hash(empty(), &op, 2); let hash = calc_script_fn_hash(empty(), &op, 2);
@ -1692,7 +1692,7 @@ fn parse_binary_op(
Box::new(FnCallExpr { Box::new(FnCallExpr {
hash, hash,
args, args,
def_value: Some(true), def_value: Some(true.into()),
..op_base ..op_base
}), }),
pos, pos,
@ -2833,7 +2833,7 @@ impl Engine {
is_function_scope: false, is_function_scope: false,
is_breakable: false, is_breakable: false,
level: 0, level: 0,
pos: NO_POS, pos: Position::NONE,
}; };
let expr = parse_expr(input, &mut state, &mut functions, settings)?; let expr = parse_expr(input, &mut state, &mut functions, settings)?;
@ -2886,7 +2886,7 @@ impl Engine {
is_function_scope: false, is_function_scope: false,
is_breakable: false, is_breakable: false,
level: 0, level: 0,
pos: NO_POS, pos: Position::NONE,
}; };
let stmt = match parse_stmt(input, &mut state, &mut functions, settings)? { let stmt = match parse_stmt(input, &mut state, &mut functions, settings)? {

View File

@ -6,15 +6,16 @@ use crate::stdlib::{
fmt, fmt,
string::{String, ToString}, string::{String, ToString},
}; };
use crate::{Dynamic, ImmutableString, ParseErrorType, Position, INT, NO_POS}; use crate::{Dynamic, ImmutableString, ParseErrorType, Position, INT};
/// Evaluation result. /// Evaluation result.
/// ///
/// All wrapped `Position` values represent the location in the script where the error occurs. /// All wrapped [`Position`] values represent the location in the script where the error occurs.
/// ///
/// # Thread Safety /// # Thread Safety
/// ///
/// Currently, `EvalAltResult` is neither `Send` nor `Sync`. Turn on the `sync` feature to make it `Send + Sync`. /// Currently, [`EvalAltResult`] is neither [`Send`] nor [`Sync`].
/// Turn on the `sync` feature to make it [`Send`] `+` [`Sync`].
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum EvalAltResult { pub enum EvalAltResult {
@ -246,7 +247,7 @@ impl fmt::Display for EvalAltResult {
impl<T: AsRef<str>> From<T> for EvalAltResult { impl<T: AsRef<str>> From<T> for EvalAltResult {
#[inline(always)] #[inline(always)]
fn from(err: T) -> Self { fn from(err: T) -> Self {
Self::ErrorRuntime(err.as_ref().to_string().into(), NO_POS) Self::ErrorRuntime(err.as_ref().to_string().into(), Position::NONE)
} }
} }
@ -255,7 +256,7 @@ impl<T: AsRef<str>> From<T> for Box<EvalAltResult> {
fn from(err: T) -> Self { fn from(err: T) -> Self {
Box::new(EvalAltResult::ErrorRuntime( Box::new(EvalAltResult::ErrorRuntime(
err.as_ref().to_string().into(), err.as_ref().to_string().into(),
NO_POS, Position::NONE,
)) ))
} }
} }
@ -313,10 +314,10 @@ impl EvalAltResult {
_ => false, _ => false,
} }
} }
/// Get the `Position` of this error. /// Get the [`Position`] of this error.
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
Self::ErrorSystem(_, _) => NO_POS, Self::ErrorSystem(_, _) => Position::NONE,
Self::ErrorParsing(_, pos) Self::ErrorParsing(_, pos)
| Self::ErrorFunctionNotFound(_, pos) | Self::ErrorFunctionNotFound(_, pos)
@ -346,7 +347,7 @@ impl EvalAltResult {
| Self::Return(_, pos) => *pos, | Self::Return(_, pos) => *pos,
} }
} }
/// Override the `Position` of this error. /// Override the [`Position`] of this error.
pub fn set_position(&mut self, new_position: Position) { pub fn set_position(&mut self, new_position: Position) {
match self { match self {
Self::ErrorSystem(_, _) => (), Self::ErrorSystem(_, _) => (),
@ -379,8 +380,8 @@ impl EvalAltResult {
| Self::Return(_, pos) => *pos = new_position, | Self::Return(_, pos) => *pos = new_position,
} }
} }
/// Consume the current `EvalAltResult` and return a new one with the specified `Position` /// Consume the current [`EvalAltResult`] and return a new one with the specified [`Position`]
/// if the current position is `Position::None`. /// if the current position is [`Position::None`].
#[inline(always)] #[inline(always)]
pub(crate) fn fill_position(mut self: Box<Self>, new_position: Position) -> Box<Self> { pub(crate) fn fill_position(mut self: Box<Self>, new_position: Position) -> Box<Self> {
if self.position().is_none() { if self.position().is_none() {

View File

@ -1,4 +1,4 @@
//! Module that defines the `Scope` type representing a function call-stack scope. //! Module that defines the [`Scope`] type representing a function call-stack scope.
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::stdlib::{borrow::Cow, boxed::Box, iter, string::String, vec::Vec}; use crate::stdlib::{borrow::Cow, boxed::Box, iter, string::String, vec::Vec};
@ -25,11 +25,12 @@ impl EntryType {
} }
/// Type containing information about the current scope. /// Type containing information about the current scope.
/// Useful for keeping state between `Engine` evaluation runs. /// Useful for keeping state between [`Engine`][crate::Engine] evaluation runs.
/// ///
/// # Thread Safety /// # Thread Safety
/// ///
/// Currently, `Scope` is neither `Send` nor `Sync`. Turn on the `sync` feature to make it `Send + Sync`. /// Currently, [`Scope`] is neither [`Send`] nor [`Sync`].
/// Turn on the [`Sync`] feature to make it [`Send`] `+` [`Sync`].
/// ///
/// # Example /// # Example
/// ///
@ -57,12 +58,12 @@ impl EntryType {
// //
// # Implementation Notes // # Implementation Notes
// //
// `Scope` is implemented as three `Vec`'s of exactly the same length. Variables data (name, type, etc.) // [`Scope`] is implemented as three [`Vec`]'s of exactly the same length. Variables data (name, type, etc.)
// is manually split into three equal-length arrays. That's because variable names take up the most space, // is manually split into three equal-length arrays. That's because variable names take up the most space,
// with `Cow<str>` being four words long, but in the vast majority of cases the name is NOT used to look up // with [`Cow<str>`][Cow] being four words long, but in the vast majority of cases the name is NOT used to look up
// a variable's value. Variable lookup is usually via direct index, by-passing the name altogether. // a variable's value. Variable lookup is usually via direct index, by-passing the name altogether.
// //
// Since `Dynamic` is reasonably small, packing it tightly improves cache locality when variables are accessed. // Since [`Dynamic`] is reasonably small, packing it tightly improves cache locality when variables are accessed.
// The variable type is packed separately into another array because it is even smaller. // The variable type is packed separately into another array because it is even smaller.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Scope<'a> { pub struct Scope<'a> {
@ -85,7 +86,7 @@ impl Default for Scope<'_> {
} }
impl<'a> Scope<'a> { impl<'a> Scope<'a> {
/// Create a new Scope. /// Create a new [`Scope`].
/// ///
/// # Example /// # Example
/// ///
@ -101,7 +102,7 @@ impl<'a> Scope<'a> {
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
/// Empty the Scope. /// Empty the [`Scope`].
/// ///
/// # Example /// # Example
/// ///
@ -127,7 +128,7 @@ impl<'a> Scope<'a> {
self.values.clear(); self.values.clear();
self self
} }
/// Get the number of entries inside the Scope. /// Get the number of entries inside the [`Scope`].
/// ///
/// # Example /// # Example
/// ///
@ -144,7 +145,7 @@ impl<'a> Scope<'a> {
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.values.len() self.values.len()
} }
/// Is the Scope empty? /// Is the [`Scope`] empty?
/// ///
/// # Example /// # Example
/// ///
@ -161,7 +162,7 @@ impl<'a> Scope<'a> {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.values.len() == 0 self.values.len() == 0
} }
/// Add (push) a new entry to the Scope. /// Add (push) a new entry to the [`Scope`].
/// ///
/// # Example /// # Example
/// ///
@ -181,7 +182,7 @@ impl<'a> Scope<'a> {
) -> &mut Self { ) -> &mut Self {
self.push_dynamic_value(name, EntryType::Normal, Dynamic::from(value)) self.push_dynamic_value(name, EntryType::Normal, Dynamic::from(value))
} }
/// Add (push) a new `Dynamic` entry to the Scope. /// Add (push) a new [`Dynamic`] entry to the [`Scope`].
/// ///
/// # Example /// # Example
/// ///
@ -197,13 +198,10 @@ impl<'a> Scope<'a> {
pub fn push_dynamic(&mut self, name: impl Into<Cow<'a, str>>, value: Dynamic) -> &mut Self { pub fn push_dynamic(&mut self, name: impl Into<Cow<'a, str>>, value: Dynamic) -> &mut Self {
self.push_dynamic_value(name, EntryType::Normal, value) self.push_dynamic_value(name, EntryType::Normal, value)
} }
/// Add (push) a new constant to the Scope. /// Add (push) a new constant to the [`Scope`].
/// ///
/// Constants are immutable and cannot be assigned to. Their values never change. /// Constants are immutable and cannot be assigned to. Their values never change.
/// Constants propagation is a technique used to optimize an AST. /// Constants propagation is a technique used to optimize an [`AST`][crate::AST].
///
/// However, in order to be used for optimization, constants must be in one of the recognized types:
/// `INT` (default to `i64`, `i32` if `only_i32`), `f64`, `String`, `char` and `bool`.
/// ///
/// # Example /// # Example
/// ///
@ -223,14 +221,10 @@ impl<'a> Scope<'a> {
) -> &mut Self { ) -> &mut Self {
self.push_dynamic_value(name, EntryType::Constant, Dynamic::from(value)) self.push_dynamic_value(name, EntryType::Constant, Dynamic::from(value))
} }
/// Add (push) a new constant with a `Dynamic` value to the Scope. /// Add (push) a new constant with a [`Dynamic`] value to the Scope.
/// ///
/// Constants are immutable and cannot be assigned to. Their values never change. /// Constants are immutable and cannot be assigned to. Their values never change.
/// Constants propagation is a technique used to optimize an AST. /// Constants propagation is a technique used to optimize an [`AST`][crate::AST].
///
/// However, in order to be used for optimization, the `Dynamic` value must be in one of the
/// recognized types:
/// `INT` (default to `i64`, `i32` if `only_i32`), `f64`, `String`, `char` and `bool`.
/// ///
/// # Example /// # Example
/// ///
@ -250,7 +244,7 @@ impl<'a> Scope<'a> {
) -> &mut Self { ) -> &mut Self {
self.push_dynamic_value(name, EntryType::Constant, value) self.push_dynamic_value(name, EntryType::Constant, value)
} }
/// Add (push) a new entry with a `Dynamic` value to the Scope. /// Add (push) a new entry with a [`Dynamic`] value to the [`Scope`].
#[inline] #[inline]
pub(crate) fn push_dynamic_value( pub(crate) fn push_dynamic_value(
&mut self, &mut self,
@ -263,7 +257,7 @@ impl<'a> Scope<'a> {
self.values.push(value.into()); self.values.push(value.into());
self self
} }
/// Truncate (rewind) the Scope to a previous size. /// Truncate (rewind) the [`Scope`] to a previous size.
/// ///
/// # Example /// # Example
/// ///
@ -296,7 +290,7 @@ impl<'a> Scope<'a> {
self.values.truncate(size); self.values.truncate(size);
self self
} }
/// Does the scope contain the entry? /// Does the [`Scope`] contain the entry?
/// ///
/// # Example /// # Example
/// ///
@ -316,7 +310,7 @@ impl<'a> Scope<'a> {
.rev() // Always search a Scope in reverse order .rev() // Always search a Scope in reverse order
.any(|(key, _)| name == key.as_ref()) .any(|(key, _)| name == key.as_ref())
} }
/// Find an entry in the Scope, starting from the last. /// Find an entry in the [`Scope`], starting from the last.
#[inline(always)] #[inline(always)]
pub(crate) fn get_index(&self, name: &str) -> Option<(usize, EntryType)> { pub(crate) fn get_index(&self, name: &str) -> Option<(usize, EntryType)> {
self.names self.names
@ -331,7 +325,7 @@ impl<'a> Scope<'a> {
} }
}) })
} }
/// Get the value of an entry in the Scope, starting from the last. /// Get the value of an entry in the [`Scope`], starting from the last.
/// ///
/// # Example /// # Example
/// ///
@ -352,7 +346,8 @@ impl<'a> Scope<'a> {
.find(|(_, (key, _))| name == key.as_ref()) .find(|(_, (key, _))| name == key.as_ref())
.and_then(|(index, _)| self.values[index].flatten_clone().try_cast()) .and_then(|(index, _)| self.values[index].flatten_clone().try_cast())
} }
/// Update the value of the named entry. /// Update the value of the named entry in the [`Scope`].
///
/// Search starts backwards from the last, and only the first entry matching the specified name is updated. /// Search starts backwards from the last, and only the first entry matching the specified name is updated.
/// If no entry matching the specified name is found, a new one is added. /// If no entry matching the specified name is found, a new one is added.
/// ///
@ -386,7 +381,7 @@ impl<'a> Scope<'a> {
} }
self self
} }
/// Get a mutable reference to an entry in the Scope. /// Get a mutable reference to an entry in the [`Scope`].
#[inline(always)] #[inline(always)]
pub(crate) fn get_mut(&mut self, index: usize) -> (&mut Dynamic, EntryType) { pub(crate) fn get_mut(&mut self, index: usize) -> (&mut Dynamic, EntryType) {
( (
@ -394,7 +389,7 @@ impl<'a> Scope<'a> {
self.types[index], self.types[index],
) )
} }
/// Update the access type of an entry in the Scope. /// Update the access type of an entry in the [`Scope`].
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
pub(crate) fn add_entry_alias(&mut self, index: usize, alias: String) -> &mut Self { pub(crate) fn add_entry_alias(&mut self, index: usize, alias: String) -> &mut Self {
@ -404,7 +399,7 @@ impl<'a> Scope<'a> {
} }
self self
} }
/// Clone the Scope, keeping only the last instances of each variable name. /// Clone the [`Scope`], keeping only the last instances of each variable name.
/// Shadowed variables are omitted in the copy. /// Shadowed variables are omitted in the copy.
#[inline] #[inline]
pub(crate) fn clone_visible(&self) -> Self { pub(crate) fn clone_visible(&self) -> Self {
@ -424,7 +419,7 @@ impl<'a> Scope<'a> {
entries entries
} }
/// Get an iterator to entries in the Scope. /// Get an iterator to entries in the [`Scope`].
#[inline(always)] #[inline(always)]
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn into_iter( pub(crate) fn into_iter(
@ -435,7 +430,7 @@ impl<'a> Scope<'a> {
.zip(self.types.into_iter().zip(self.values.into_iter())) .zip(self.types.into_iter().zip(self.values.into_iter()))
.map(|((name, alias), (typ, value))| (name, typ, value, alias.to_vec())) .map(|((name, alias), (typ, value))| (name, typ, value, alias.to_vec()))
} }
/// Get an iterator to entries in the Scope. /// Get an iterator to entries in the [`Scope`].
/// Shared values are flatten-cloned. /// Shared values are flatten-cloned.
/// ///
/// # Example /// # Example
@ -465,7 +460,7 @@ impl<'a> Scope<'a> {
self.iter_raw() self.iter_raw()
.map(|(name, constant, value)| (name, constant, value.flatten_clone())) .map(|(name, constant, value)| (name, constant, value.flatten_clone()))
} }
/// Get an iterator to entries in the Scope. /// Get an iterator to entries in the [`Scope`].
/// Shared values are not expanded. /// Shared values are not expanded.
#[inline(always)] #[inline(always)]
pub fn iter_raw<'x: 'a>(&'x self) -> impl Iterator<Item = (&'a str, bool, &'x Dynamic)> + 'x { pub fn iter_raw<'x: 'a>(&'x self) -> impl Iterator<Item = (&'a str, bool, &'x Dynamic)> + 'x {

View File

@ -1,9 +1,9 @@
//! Implement deserialization support of `Dynamic` for [`serde`](https://crates.io/crates/serde). //! Implement deserialization support of [`Dynamic`][crate::Dynamic] for [`serde`].
use super::str::ImmutableStringDeserializer; use super::str::ImmutableStringDeserializer;
use crate::dynamic::Union; use crate::dynamic::Union;
use crate::stdlib::{any::type_name, boxed::Box, fmt, string::ToString}; use crate::stdlib::{any::type_name, boxed::Box, fmt, string::ToString};
use crate::{Dynamic, EvalAltResult, ImmutableString, LexError, ParseErrorType, NO_POS}; use crate::{Dynamic, EvalAltResult, ImmutableString, LexError, ParseErrorType, Position::NONE};
use serde::de::{ use serde::de::{
DeserializeSeed, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor, DeserializeSeed, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor,
}; };
@ -15,19 +15,19 @@ use crate::Array;
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use crate::Map; use crate::Map;
/// Deserializer for `Dynamic` which is kept as a reference. /// Deserializer for [`Dynamic`][crate::Dynamic] which is kept as a reference.
/// ///
/// The reference is necessary because the deserialized type may hold references /// The reference is necessary because the deserialized type may hold references
/// (especially `&str`) to the source `Dynamic`. /// (especially `&str`) to the source [`Dynamic`][crate::Dynamic].
pub struct DynamicDeserializer<'a> { pub struct DynamicDeserializer<'a> {
value: &'a Dynamic, value: &'a Dynamic,
} }
impl<'de> DynamicDeserializer<'de> { impl<'de> DynamicDeserializer<'de> {
/// Create a `DynamicDeserializer` from a reference to a `Dynamic` value. /// Create a [`DynamicDeserializer`] from a reference to a [`Dynamic`][crate::Dynamic] value.
/// ///
/// The reference is necessary because the deserialized type may hold references /// The reference is necessary because the deserialized type may hold references
/// (especially `&str`) to the source `Dynamic`. /// (especially `&str`) to the source [`Dynamic`][crate::Dynamic].
pub fn from_dynamic(value: &'de Dynamic) -> Self { pub fn from_dynamic(value: &'de Dynamic) -> Self {
Self { value } Self { value }
} }
@ -37,8 +37,12 @@ impl<'de> DynamicDeserializer<'de> {
} }
/// Shortcut for a type conversion error. /// Shortcut for a type conversion error.
fn type_error_str<T>(&self, error: &str) -> Result<T, Box<EvalAltResult>> { fn type_error_str<T>(&self, error: &str) -> Result<T, Box<EvalAltResult>> {
EvalAltResult::ErrorMismatchOutputType(error.into(), self.value.type_name().into(), NO_POS) EvalAltResult::ErrorMismatchOutputType(
.into() error.into(),
self.value.type_name().into(),
Position::NONE,
)
.into()
} }
fn deserialize_int<V: Visitor<'de>>( fn deserialize_int<V: Visitor<'de>>(
&mut self, &mut self,
@ -56,7 +60,7 @@ impl<'de> DynamicDeserializer<'de> {
} }
} }
/// Deserialize a `Dynamic` value into a Rust type that implements `serde::Deserialize`. /// Deserialize a [`Dynamic`][crate::Dynamic] value into a Rust type that implements [`serde::Deserialize`].
/// ///
/// # Example /// # Example
/// ///
@ -117,7 +121,7 @@ impl Error for Box<EvalAltResult> {
fn custom<T: fmt::Display>(err: T) -> Self { fn custom<T: fmt::Display>(err: T) -> Self {
EvalAltResult::ErrorParsing( EvalAltResult::ErrorParsing(
ParseErrorType::BadInput(LexError::ImproperSymbol(err.to_string())), ParseErrorType::BadInput(LexError::ImproperSymbol(err.to_string())),
NO_POS, Position::NONE,
) )
.into() .into()
} }
@ -445,7 +449,7 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
/// `SeqAccess` implementation for arrays. /// `SeqAccess` implementation for arrays.
struct IterateArray<'a, ITER: Iterator<Item = &'a Dynamic>> { struct IterateArray<'a, ITER: Iterator<Item = &'a Dynamic>> {
/// Iterator for a stream of `Dynamic` values. /// Iterator for a stream of [`Dynamic`][crate::Dynamic] values.
iter: ITER, iter: ITER,
} }
@ -479,9 +483,9 @@ where
KEYS: Iterator<Item = &'a ImmutableString>, KEYS: Iterator<Item = &'a ImmutableString>,
VALUES: Iterator<Item = &'a Dynamic>, VALUES: Iterator<Item = &'a Dynamic>,
{ {
// Iterator for a stream of `Dynamic` keys. // Iterator for a stream of [`Dynamic`][crate::Dynamic] keys.
keys: KEYS, keys: KEYS,
// Iterator for a stream of `Dynamic` values. // Iterator for a stream of [`Dynamic`][crate::Dynamic] values.
values: VALUES, values: VALUES,
} }

View File

@ -1,4 +1,4 @@
//! Helper module defining serialization/deserialization support for [`serde`](https://crates.io/crates/serde). //! Helper module defining serialization/deserialization support for [`serde`].
pub mod de; pub mod de;
pub mod ser; pub mod ser;

View File

@ -1,7 +1,7 @@
//! Implement serialization support of `Dynamic` for [`serde`](https://crates.io/crates/serde). //! Implement serialization support of [`Dynamic`][crate::Dynamic] for [`serde`].
use crate::stdlib::{boxed::Box, fmt, string::ToString}; use crate::stdlib::{boxed::Box, fmt, string::ToString};
use crate::{Dynamic, EvalAltResult, NO_POS}; use crate::{Dynamic, EvalAltResult, Position::NONE};
use serde::ser::{ use serde::ser::{
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct, Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct,
Serializer, Serializer,
@ -14,7 +14,7 @@ use crate::Array;
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use crate::Map; use crate::Map;
/// Serializer for `Dynamic` which is kept as a reference. /// Serializer for [`Dynamic`][crate::Dynamic] which is kept as a reference.
pub struct DynamicSerializer { pub struct DynamicSerializer {
/// Buffer to hold a temporary key. /// Buffer to hold a temporary key.
_key: Dynamic, _key: Dynamic,
@ -23,7 +23,7 @@ pub struct DynamicSerializer {
} }
impl DynamicSerializer { impl DynamicSerializer {
/// Create a `DynamicSerializer` from a `Dynamic` value. /// Create a [`DynamicSerializer`] from a [`Dynamic`][crate::Dynamic] value.
pub fn new(_value: Dynamic) -> Self { pub fn new(_value: Dynamic) -> Self {
Self { Self {
_key: Default::default(), _key: Default::default(),
@ -32,7 +32,7 @@ impl DynamicSerializer {
} }
} }
/// Serialize a Rust type that implements `serde::Serialize` into a `Dynamic`. /// Serialize a Rust type that implements [`serde::Serialize`] into a [`Dynamic`][crate::Dynamic].
/// ///
/// # Example /// # Example
/// ///
@ -87,7 +87,7 @@ pub fn to_dynamic<T: Serialize>(value: T) -> Result<Dynamic, Box<EvalAltResult>>
impl Error for Box<EvalAltResult> { impl Error for Box<EvalAltResult> {
fn custom<T: fmt::Display>(err: T) -> Self { fn custom<T: fmt::Display>(err: T) -> Self {
EvalAltResult::ErrorRuntime(err.to_string().into(), NO_POS).into() EvalAltResult::ErrorRuntime(err.to_string().into(), Position::NONE).into()
} }
} }
@ -283,16 +283,24 @@ impl Serializer for &mut DynamicSerializer {
make_variant(_variant, content) make_variant(_variant, content)
} }
#[cfg(feature = "no_object")] #[cfg(feature = "no_object")]
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "map".into(), NO_POS) return EvalAltResult::ErrorMismatchOutputType(
.into(); "Dynamic".into(),
"map".into(),
Position::NONE,
)
.into();
} }
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Box<EvalAltResult>> { fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Box<EvalAltResult>> {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
return Ok(DynamicSerializer::new(Array::new().into())); return Ok(DynamicSerializer::new(Array::new().into()));
#[cfg(feature = "no_index")] #[cfg(feature = "no_index")]
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "array".into(), NO_POS) return EvalAltResult::ErrorMismatchOutputType(
.into(); "Dynamic".into(),
"array".into(),
Position::NONE,
)
.into();
} }
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Box<EvalAltResult>> { fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Box<EvalAltResult>> {
@ -325,7 +333,12 @@ impl Serializer for &mut DynamicSerializer {
let err_type = "map"; let err_type = "map";
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
let err_type = "array"; let err_type = "array";
EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), err_type.into(), NO_POS).into() EvalAltResult::ErrorMismatchOutputType(
"Dynamic".into(),
err_type.into(),
Position::NONE,
)
.into()
} }
} }
@ -333,8 +346,12 @@ impl Serializer for &mut DynamicSerializer {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
return Ok(DynamicSerializer::new(Map::new().into())); return Ok(DynamicSerializer::new(Map::new().into()));
#[cfg(feature = "no_object")] #[cfg(feature = "no_object")]
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "map".into(), NO_POS) return EvalAltResult::ErrorMismatchOutputType(
.into(); "Dynamic".into(),
"map".into(),
Position::NONE,
)
.into();
} }
fn serialize_struct( fn serialize_struct(
@ -358,8 +375,12 @@ impl Serializer for &mut DynamicSerializer {
map: Map::with_capacity(_len), map: Map::with_capacity(_len),
}); });
#[cfg(feature = "no_object")] #[cfg(feature = "no_object")]
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "map".into(), NO_POS) return EvalAltResult::ErrorMismatchOutputType(
.into(); "Dynamic".into(),
"map".into(),
Position::NONE,
)
.into();
} }
} }
@ -468,7 +489,11 @@ impl SerializeMap for DynamicSerializer {
let key = crate::stdlib::mem::take(&mut self._key) let key = crate::stdlib::mem::take(&mut self._key)
.take_immutable_string() .take_immutable_string()
.map_err(|typ| { .map_err(|typ| {
EvalAltResult::ErrorMismatchOutputType("string".into(), typ.into(), NO_POS) EvalAltResult::ErrorMismatchOutputType(
"string".into(),
typ.into(),
Position::NONE,
)
})?; })?;
let _value = _value.serialize(&mut *self)?; let _value = _value.serialize(&mut *self)?;
let map = self._value.downcast_mut::<Map>().unwrap(); let map = self._value.downcast_mut::<Map>().unwrap();
@ -488,7 +513,7 @@ impl SerializeMap for DynamicSerializer {
{ {
let _key: Dynamic = _key.serialize(&mut *self)?; let _key: Dynamic = _key.serialize(&mut *self)?;
let _key = _key.take_immutable_string().map_err(|typ| { let _key = _key.take_immutable_string().map_err(|typ| {
EvalAltResult::ErrorMismatchOutputType("string".into(), typ.into(), NO_POS) EvalAltResult::ErrorMismatchOutputType("string".into(), typ.into(), Position::NONE)
})?; })?;
let _value = _value.serialize(&mut *self)?; let _value = _value.serialize(&mut *self)?;
let map = self._value.downcast_mut::<Map>().unwrap(); let map = self._value.downcast_mut::<Map>().unwrap();

View File

@ -1,7 +1,7 @@
//! Implement deserialization support of `ImmutableString` for [`serde`](https://crates.io/crates/serde). //! Implement deserialization support of [`ImmutableString`][crate::ImmutableString] for [`serde`].
use crate::stdlib::{any::type_name, boxed::Box}; use crate::stdlib::{any::type_name, boxed::Box};
use crate::{EvalAltResult, ImmutableString, NO_POS}; use crate::{EvalAltResult, ImmutableString, Position::NONE};
use serde::de::{Deserializer, Visitor}; use serde::de::{Deserializer, Visitor};
/// Deserializer for `ImmutableString`. /// Deserializer for `ImmutableString`.
@ -16,8 +16,12 @@ impl<'a> ImmutableStringDeserializer<'a> {
} }
/// Shortcut for a type conversion error. /// Shortcut for a type conversion error.
fn type_error<T>(&self) -> Result<T, Box<EvalAltResult>> { fn type_error<T>(&self) -> Result<T, Box<EvalAltResult>> {
EvalAltResult::ErrorMismatchOutputType(type_name::<T>().into(), "string".into(), NO_POS) EvalAltResult::ErrorMismatchOutputType(
.into() type_name::<T>().into(),
"string".into(),
Position::NONE,
)
.into()
} }
} }

View File

@ -1,4 +1,4 @@
//! Module implementing custom syntax for `Engine`. //! Module implementing custom syntax for [`Engine`].
use crate::ast::Expr; use crate::ast::Expr;
use crate::engine::{EvalContext, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT}; use crate::engine::{EvalContext, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
@ -11,7 +11,7 @@ use crate::stdlib::{
use crate::token::{is_valid_identifier, Token}; use crate::token::{is_valid_identifier, Token};
use crate::{ use crate::{
Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseError, Position, Shared, Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseError, Position, Shared,
StaticVec, NO_POS, StaticVec,
}; };
/// A general expression evaluation trait object. /// A general expression evaluation trait object.
@ -31,7 +31,7 @@ pub type FnCustomSyntaxParse = dyn Fn(&[String]) -> Result<Option<String>, Parse
pub type FnCustomSyntaxParse = pub type FnCustomSyntaxParse =
dyn Fn(&[String]) -> Result<Option<String>, ParseError> + Send + Sync; dyn Fn(&[String]) -> Result<Option<String>, ParseError> + Send + Sync;
/// An expression sub-tree in an AST. /// An expression sub-tree in an [`AST`][crate::AST].
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Expression<'a>(&'a Expr); pub struct Expression<'a>(&'a Expr);
@ -43,7 +43,7 @@ impl<'a> From<&'a Expr> for Expression<'a> {
} }
impl Expression<'_> { impl Expression<'_> {
/// If this expression is a variable name, return it. Otherwise `None`. /// If this expression is a variable name, return it. Otherwise [`None`].
#[inline(always)] #[inline(always)]
pub fn get_variable_name(&self) -> Option<&str> { pub fn get_variable_name(&self) -> Option<&str> {
self.0.get_variable_access(true) self.0.get_variable_access(true)
@ -65,7 +65,7 @@ impl EvalContext<'_, '_, '_, '_, '_, '_, '_, '_, '_> {
/// ///
/// ## WARNING - Low Level API /// ## WARNING - Low Level API
/// ///
/// This function is very low level. It evaluates an expression from an AST. /// This function is very low level. It evaluates an expression from an [`AST`][crate::AST].
#[inline(always)] #[inline(always)]
pub fn eval_expression_tree( pub fn eval_expression_tree(
&mut self, &mut self,
@ -95,10 +95,10 @@ pub struct CustomSyntax {
} }
impl Engine { impl Engine {
/// Register a custom syntax with the `Engine`. /// Register a custom syntax with the [`Engine`].
/// ///
/// * `keywords` holds a slice of strings that define the custom syntax. /// * `keywords` holds a slice of strings that define the custom syntax.
/// * `new_vars` is the number of new variables declared by this custom syntax, or the number of variables removed (if negative). /// * `new_vars` is the number of new variables declared by this custom syntax, or the number of variables removed (if negative).
/// * `func` is the implementation function. /// * `func` is the implementation function.
pub fn register_custom_syntax<S: AsRef<str> + ToString>( pub fn register_custom_syntax<S: AsRef<str> + ToString>(
&mut self, &mut self,
@ -142,7 +142,7 @@ impl Engine {
segments.len() + 1, segments.len() + 1,
s s
)) ))
.into_err(NO_POS) .into_err(Position::NONE)
.into()); .into());
} }
// Identifier in first position // Identifier in first position
@ -159,7 +159,7 @@ impl Engine {
segments.len() + 1, segments.len() + 1,
s s
)) ))
.into_err(NO_POS) .into_err(Position::NONE)
.into()); .into());
} }
}; };
@ -191,17 +191,17 @@ impl Engine {
Ok(self) Ok(self)
} }
/// 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.
/// ///
/// * `new_vars` is the number of new variables declared by this custom syntax, or the number of variables removed (if negative). /// * `new_vars` is the number of new variables declared by this custom syntax, or the number of variables removed (if negative).
/// * `parse` is the parsing function. /// * `parse` is the parsing function.
/// * `func` is the implementation function. /// * `func` is the implementation function.
/// ///
/// All custom keywords must be manually registered via `Engine::register_custom_operator`. /// All custom keywords must be manually registered via [`register_custom_operator`][Engine::register_custom_operator].
/// Otherwise, custom keywords won't be recognized. /// Otherwise, custom keywords won't be recognized.
pub fn register_custom_syntax_raw( pub fn register_custom_syntax_raw(
&mut self, &mut self,

View File

@ -37,19 +37,16 @@ pub struct Position {
pos: u16, pos: u16,
} }
/// No `Position`.
pub const NO_POS: Position = Position::NONE;
impl Position { impl Position {
/// A `Position` representing no position. /// A [`Position`] representing no position.
pub const NONE: Self = Self { line: 0, pos: 0 }; pub const NONE: Self = Self { line: 0, pos: 0 };
/// A `Position` representing the first position. /// A [`Position`] representing the first position.
pub const START: Self = Self { line: 1, pos: 0 }; pub const START: Self = Self { line: 1, pos: 0 };
/// Create a new `Position`. /// Create a new [`Position`].
/// ///
/// `line` must not be zero. /// `line` must not be zero.
/// If `position` is zero, then it is at the beginning of a line. /// If [`Position`] is zero, then it is at the beginning of a line.
/// ///
/// # Panics /// # Panics
/// ///
@ -63,7 +60,7 @@ impl Position {
pos: position, pos: position,
} }
} }
/// Get the line number (1-based), or `None` if there is no position. /// Get the line number (1-based), or [`None`] if there is no position.
#[inline(always)] #[inline(always)]
pub fn line(self) -> Option<usize> { pub fn line(self) -> Option<usize> {
if self.is_none() { if self.is_none() {
@ -72,7 +69,7 @@ impl Position {
Some(self.line as usize) Some(self.line as usize)
} }
} }
/// Get the character position (1-based), or `None` if at beginning of a line. /// Get the character position (1-based), or [`None`] if at beginning of a line.
#[inline(always)] #[inline(always)]
pub fn position(self) -> Option<usize> { pub fn position(self) -> Option<usize> {
if self.is_none() || self.pos == 0 { if self.is_none() || self.pos == 0 {
@ -113,12 +110,12 @@ impl Position {
self.pos = 0; self.pos = 0;
} }
} }
/// Is this `Position` at the beginning of a line? /// Is this [`Position`] at the beginning of a line?
#[inline(always)] #[inline(always)]
pub fn is_beginning_of_line(self) -> bool { pub fn is_beginning_of_line(self) -> bool {
self.line == 0 && !self.is_none() self.line == 0 && !self.is_none()
} }
/// Is there no `Position`? /// Is there no [`Position`]?
#[inline(always)] #[inline(always)]
pub fn is_none(self) -> bool { pub fn is_none(self) -> bool {
self == Self::NONE self == Self::NONE
@ -150,7 +147,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
@ -544,7 +541,7 @@ impl Token {
}) })
} }
// Is this token EOF? // Is this token [`EOF`][Token::EOF]?
#[inline(always)] #[inline(always)]
pub fn is_eof(&self) -> bool { pub fn is_eof(&self) -> bool {
use Token::*; use Token::*;
@ -556,7 +553,7 @@ impl Token {
} }
// If another operator is after these, it's probably an unary operator // If another operator is after these, it's probably an unary operator
// (not sure about fn name). // (not sure about `fn` name).
pub fn is_next_unary(&self) -> bool { pub fn is_next_unary(&self) -> bool {
use Token::*; use Token::*;
@ -736,7 +733,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
@ -750,13 +747,13 @@ pub struct TokenizeState {
pub non_unary: bool, pub non_unary: bool,
/// Is the tokenizer currently inside a block comment? /// Is the tokenizer currently inside a block comment?
pub comment_level: usize, pub comment_level: usize,
/// Return `None` at the end of the stream instead of `Some(Token::EOF)`? /// Return [`None`] at the end of the stream instead of [`Some(Token::EOF)`][Token::EOF]?
pub end_with_none: bool, pub end_with_none: bool,
/// Include comments? /// Include comments?
pub include_comments: bool, pub include_comments: bool,
} }
/// _[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
@ -770,7 +767,7 @@ pub trait InputStream {
fn peek_next(&mut self) -> Option<char>; fn peek_next(&mut self) -> Option<char>;
} }
/// _[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
@ -959,7 +956,7 @@ fn scan_comment(
} }
} }
/// _[INTERNALS]_ Get the next token from the `InputStream`. /// _(INTERNALS)_ Get the next token from the `stream`.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -1528,6 +1525,7 @@ pub fn can_override_keyword(name: &str) -> bool {
} }
} }
/// Is a text string a valid identifier?
pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool { pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool {
let mut first_alphabetic = false; let mut first_alphabetic = false;
@ -1568,7 +1566,7 @@ fn is_id_continue(x: char) -> bool {
x.is_ascii_alphanumeric() || x == '_' x.is_ascii_alphanumeric() || x == '_'
} }
/// A type that implements the `InputStream` trait. /// A type that implements the [`InputStream`] trait.
/// Multiple character streams are jointed together to form one single stream. /// Multiple character streams are jointed together to form one single stream.
pub struct MultiInputsStream<'a> { pub struct MultiInputsStream<'a> {
/// Buffered character, if any. /// Buffered character, if any.
@ -1625,7 +1623,7 @@ impl InputStream for MultiInputsStream<'_> {
} }
} }
/// An iterator on a `Token` stream. /// An iterator on a [`Token`] stream.
pub struct TokenIterator<'a, 'e> { pub struct TokenIterator<'a, 'e> {
/// Reference to the scripting `Engine`. /// Reference to the scripting `Engine`.
engine: &'e Engine, engine: &'e Engine,

View File

@ -44,11 +44,11 @@ pub fn unsafe_cast_box<X: Variant, T: Variant>(item: Box<X>) -> Result<Box<T>, B
/// ///
/// A dangerous function that blindly casts a `&str` from one lifetime to a `&str` of /// A dangerous function that blindly casts a `&str` from one lifetime to a `&str` of
/// another lifetime. This is mainly used to let us push a block-local variable into the /// another lifetime. This is mainly used to let us push a block-local variable into the
/// current `Scope` without cloning the variable name. Doing this is safe because all local /// current [`Scope`][crate::Scope] without cloning the variable name. Doing this is safe because all local
/// variables in the `Scope` are cleared out before existing the block. /// variables in the [`Scope`][crate::Scope] are cleared out before existing the block.
/// ///
/// Force-casting a local variable's lifetime to the current `Scope`'s larger lifetime saves /// Force-casting a local variable's lifetime to the current [`Scope`][crate::Scope]'s larger lifetime saves
/// on allocations and string cloning, thus avoids us having to maintain a chain of `Scope`'s. /// on allocations and string cloning, thus avoids us having to maintain a chain of [`Scope`][crate::Scope]'s.
#[inline] #[inline]
pub fn unsafe_cast_var_name_to_lifetime<'s>(name: &str) -> &'s str { pub fn unsafe_cast_var_name_to_lifetime<'s>(name: &str) -> &'s str {
// WARNING - force-cast the variable name into the scope's lifetime to avoid cloning it // WARNING - force-cast the variable name into the scope's lifetime to avoid cloning it

View File

@ -15,11 +15,11 @@ use crate::stdlib::{
}; };
use crate::Shared; use crate::Shared;
/// A hasher that only takes one single `u64` and returns it as a hash key. /// A hasher that only takes one single [`u64`] and returns it as a hash key.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics when hashing any data type other than a `u64`. /// Panics when hashing any data type other than a [`u64`].
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct StraightHasher(u64); pub struct StraightHasher(u64);
@ -49,11 +49,11 @@ impl BuildHasher for StraightHasherBuilder {
} }
} }
/// _[INTERNALS]_ Calculate a `u64` hash key from a namespace-qualified function name and parameter types. /// _(INTERNALS)_ Calculate a [`u64`] hash key from a namespace-qualified function name and parameter types.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// Module names are passed in via `&str` references from an iterator. /// Module names are passed in via `&str` references from an iterator.
/// Parameter types are passed in via `TypeId` values from an iterator. /// Parameter types are passed in via [`TypeId`] values from an iterator.
/// ///
/// # Note /// # Note
/// ///
@ -67,12 +67,12 @@ pub fn calc_native_fn_hash<'a>(
calc_fn_hash(modules, fn_name, None, params) calc_fn_hash(modules, fn_name, None, params)
} }
/// _[INTERNALS]_ Calculate a `u64` hash key from a namespace-qualified function name /// _(INTERNALS)_ Calculate a [`u64`] hash key from a namespace-qualified function name
/// and the number of parameters, but no parameter types. /// and the number of parameters, but no parameter types.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// Module names are passed in via `&str` references from an iterator. /// Module names are passed in via `&str` references from an iterator.
/// Parameter types are passed in via `TypeId` values from an iterator. /// Parameter types are passed in via [`TypeId`] values from an iterator.
/// ///
/// # Note /// # Note
/// ///
@ -96,10 +96,10 @@ pub fn get_hasher() -> impl Hasher {
s s
} }
/// Calculate a `u64` hash key from a namespace-qualified function name and parameter types. /// Calculate a [`u64`] hash key from a namespace-qualified function name and parameter types.
/// ///
/// Module names are passed in via `&str` references from an iterator. /// Module names are passed in via `&str` references from an iterator.
/// Parameter types are passed in via `TypeId` values from an iterator. /// Parameter types are passed in via [`TypeId`] values from an iterator.
/// ///
/// # Note /// # Note
/// ///
@ -127,7 +127,8 @@ fn calc_fn_hash<'a>(
/// The system immutable string type. /// The system immutable string type.
/// ///
/// An `ImmutableString` wraps an `Rc<String>` (or `Arc<String>` under the `sync` feature) /// An [`ImmutableString`] wraps an [`Rc`][std::rc::Rc]`<`[`String`]`>`
/// (or [`Arc`][std::sync::Arc]`<`[`String`]`>` under the `sync` feature)
/// so that it can be simply shared and not cloned. /// so that it can be simply shared and not cloned.
/// ///
/// # Example /// # Example
@ -469,15 +470,15 @@ impl PartialOrd<ImmutableString> for String {
} }
impl ImmutableString { impl ImmutableString {
/// Consume the `ImmutableString` and convert it into a `String`. /// Consume the [`ImmutableString`] and convert it into a [`String`].
/// If there are other references to the same string, a cloned copy is returned. /// If there are other references to the same string, a cloned copy is returned.
#[inline(always)] #[inline(always)]
pub fn into_owned(mut self) -> String { pub fn into_owned(mut self) -> String {
self.make_mut(); // Make sure it is unique reference self.make_mut(); // Make sure it is unique reference
shared_take(self.0) // Should succeed shared_take(self.0) // Should succeed
} }
/// Make sure that the `ImmutableString` is unique (i.e. no other outstanding references). /// Make sure that the [`ImmutableString`] is unique (i.e. no other outstanding references).
/// Then return a mutable reference to the `String`. /// Then return a mutable reference to the [`String`].
#[inline(always)] #[inline(always)]
pub fn make_mut(&mut self) -> &mut String { pub fn make_mut(&mut self) -> &mut String {
shared_make_mut(&mut self.0) shared_make_mut(&mut self.0)

View File

@ -1,4 +1,4 @@
use rhai::{Dynamic, Engine, EvalAltResult, LexError, ParseError, ParseErrorType, INT, NO_POS}; use rhai::{Dynamic, Engine, EvalAltResult, LexError, ParseError, ParseErrorType, Position, INT};
#[test] #[test]
fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> { fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
@ -91,7 +91,7 @@ fn test_custom_syntax_raw() -> Result<(), Box<EvalAltResult>> {
Box::new(ParseErrorType::BadInput(LexError::ImproperSymbol( Box::new(ParseErrorType::BadInput(LexError::ImproperSymbol(
s.to_string(), s.to_string(),
))), ))),
NO_POS, Position::NONE,
)), )),
}, },
_ => unreachable!(), _ => unreachable!(),

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, Scope, INT, NO_POS}; use rhai::{Engine, EvalAltResult, Position, Scope, INT};
#[test] #[test]
fn test_var_scope() -> Result<(), Box<EvalAltResult>> { fn test_var_scope() -> Result<(), Box<EvalAltResult>> {
@ -67,7 +67,7 @@ fn test_var_resolver() -> Result<(), Box<EvalAltResult>> {
"MYSTIC_NUMBER" => Ok(Some((42 as INT).into())), "MYSTIC_NUMBER" => Ok(Some((42 as INT).into())),
// Override a variable - make it not found even if it exists! // Override a variable - make it not found even if it exists!
"DO_NOT_USE" => { "DO_NOT_USE" => {
Err(EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS).into()) Err(EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE).into())
} }
// Silently maps 'chameleon' into 'innocent'. // Silently maps 'chameleon' into 'innocent'.
"chameleon" => context "chameleon" => context
@ -75,7 +75,7 @@ fn test_var_resolver() -> Result<(), Box<EvalAltResult>> {
.get_value("innocent") .get_value("innocent")
.map(Some) .map(Some)
.ok_or_else(|| { .ok_or_else(|| {
EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS).into() EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE).into()
}), }),
// Return Ok(None) to continue with the normal variable resolution process. // Return Ok(None) to continue with the normal variable resolution process.
_ => Ok(None), _ => Ok(None),