Add/remove #[inline] attributes.

This commit is contained in:
Stephen Chung 2020-10-08 22:25:50 +08:00
parent e34a370f33
commit 1272eeb81a
31 changed files with 328 additions and 114 deletions

View File

@ -22,6 +22,11 @@ New features
* `Dynamic::from(&str)` now constructs a `Dynamic` with a copy of the string as value. * `Dynamic::from(&str)` now constructs a `Dynamic` with a copy of the string as value.
* `AST::combine` and `AST::combine_filtered` allows combining two `AST`'s without creating a new one. * `AST::combine` and `AST::combine_filtered` allows combining two `AST`'s without creating a new one.
Enhancements
------------
* Many one-liners and few-liners are now marked `#[inline]` or `[inline(always)]`, just in case it helps when LTO is not turned on.
Version 0.19.0 Version 0.19.0
============== ==============

View File

@ -541,6 +541,8 @@ impl Dynamic {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn from<T: Variant + Clone>(value: T) -> Self { pub fn from<T: Variant + Clone>(value: T) -> Self {
// Coded this way in order to maximally leverage potentials for dead-code removal.
if TypeId::of::<T>() == TypeId::of::<INT>() { if TypeId::of::<T>() == TypeId::of::<INT>() {
return <dyn Any>::downcast_ref::<INT>(&value) return <dyn Any>::downcast_ref::<INT>(&value)
.unwrap() .unwrap()
@ -677,6 +679,8 @@ impl Dynamic {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn try_cast<T: Variant>(self) -> Option<T> { pub fn try_cast<T: Variant>(self) -> Option<T> {
// Coded this way in order to maximally leverage potentials for dead-code removal.
match self.0 { match self.0 {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
@ -964,6 +968,8 @@ impl Dynamic {
/// 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.
if TypeId::of::<T>() == TypeId::of::<INT>() { if TypeId::of::<T>() == TypeId::of::<INT>() {
return match &self.0 { return match &self.0 {
Union::Int(value) => <dyn Any>::downcast_ref::<T>(value), Union::Int(value) => <dyn Any>::downcast_ref::<T>(value),
@ -1052,6 +1058,8 @@ impl Dynamic {
/// 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.
if TypeId::of::<T>() == TypeId::of::<INT>() { if TypeId::of::<T>() == TypeId::of::<INT>() {
return match &mut self.0 { return match &mut self.0 {
Union::Int(value) => <dyn Any>::downcast_mut::<T>(value), Union::Int(value) => <dyn Any>::downcast_mut::<T>(value),

View File

@ -64,6 +64,7 @@ impl Engine {
/// ///
/// To access the first mutable parameter, use `args.get_mut(0).unwrap()` /// To access the first mutable parameter, use `args.get_mut(0).unwrap()`
#[deprecated(note = "this function is volatile and may change")] #[deprecated(note = "this function is volatile and may change")]
#[inline(always)]
pub fn register_raw_fn<T: Variant + Clone>( pub fn register_raw_fn<T: Variant + Clone>(
&mut self, &mut self,
name: &str, name: &str,
@ -111,6 +112,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
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>())
} }
@ -159,6 +161,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn register_type_with_name<T: Variant + Clone>(&mut self, name: &str) -> &mut Self { pub fn register_type_with_name<T: Variant + Clone>(&mut self, name: &str) -> &mut Self {
if self.type_names.is_none() { if self.type_names.is_none() {
self.type_names = Some(Default::default()); self.type_names = Some(Default::default());
@ -173,6 +176,7 @@ impl Engine {
/// Register an iterator adapter for a type with the `Engine`. /// Register an iterator adapter for a type with the `Engine`.
/// This is an advanced feature. /// This is an advanced feature.
#[inline(always)]
pub fn register_iterator<T: Variant + Clone>(&mut self, f: IteratorFn) -> &mut Self { pub fn register_iterator<T: Variant + Clone>(&mut self, f: IteratorFn) -> &mut Self {
self.global_module.set_iter(TypeId::of::<T>(), f); self.global_module.set_iter(TypeId::of::<T>(), f);
self self
@ -214,6 +218,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn register_get<T, U>( pub fn register_get<T, U>(
&mut self, &mut self,
name: &str, name: &str,
@ -265,6 +270,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn register_get_result<T: Variant + Clone>( pub fn register_get_result<T: Variant + Clone>(
&mut self, &mut self,
name: &str, name: &str,
@ -310,6 +316,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn register_set<T, U>( pub fn register_set<T, U>(
&mut self, &mut self,
name: &str, name: &str,
@ -363,6 +370,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn register_set_result<T, U>( pub fn register_set_result<T, U>(
&mut self, &mut self,
name: &str, name: &str,
@ -417,6 +425,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn register_get_set<T, U>( pub fn register_get_set<T, U>(
&mut self, &mut self,
name: &str, name: &str,
@ -472,6 +481,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn register_indexer_get<T, X, U>( pub fn register_indexer_get<T, X, U>(
&mut self, &mut self,
callback: impl Fn(&mut T, X) -> U + SendSync + 'static, callback: impl Fn(&mut T, X) -> U + SendSync + 'static,
@ -543,6 +553,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn register_indexer_get_result<T, X>( pub fn register_indexer_get_result<T, X>(
&mut self, &mut self,
callback: impl Fn(&mut T, X) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static, callback: impl Fn(&mut T, X) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
@ -610,6 +621,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn register_indexer_set<T, X, U>( pub fn register_indexer_set<T, X, U>(
&mut self, &mut self,
callback: impl Fn(&mut T, X, U) + SendSync + 'static, callback: impl Fn(&mut T, X, U) + SendSync + 'static,
@ -682,6 +694,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn register_indexer_set_result<T, X, U>( pub fn register_indexer_set_result<T, X, U>(
&mut self, &mut self,
callback: impl Fn(&mut T, X, U) -> Result<(), Box<EvalAltResult>> + SendSync + 'static, callback: impl Fn(&mut T, X, U) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
@ -752,6 +765,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn register_indexer_get_set<T, X, U>( pub fn register_indexer_get_set<T, X, U>(
&mut self, &mut self,
getter: impl Fn(&mut T, X) -> U + SendSync + 'static, getter: impl Fn(&mut T, X) -> U + SendSync + 'static,
@ -785,6 +799,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn compile(&self, script: &str) -> Result<AST, ParseError> { pub fn compile(&self, script: &str) -> Result<AST, ParseError> {
self.compile_with_scope(&Scope::new(), script) self.compile_with_scope(&Scope::new(), script)
} }
@ -827,6 +842,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result<AST, ParseError> { pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result<AST, ParseError> {
self.compile_scripts_with_scope(scope, &[script]) self.compile_scripts_with_scope(scope, &[script])
} }
@ -877,6 +893,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn compile_scripts_with_scope( pub fn compile_scripts_with_scope(
&self, &self,
scope: &Scope, scope: &Scope,
@ -886,6 +903,7 @@ impl Engine {
} }
/// 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)]
pub(crate) fn compile_with_scope_and_optimization_level( pub(crate) fn compile_with_scope_and_optimization_level(
&self, &self,
scope: &Scope, scope: &Scope,
@ -899,6 +917,7 @@ impl Engine {
/// Read the contents of a file into a string. /// Read the contents of a file into a string.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline]
fn read_file(path: PathBuf) -> Result<String, Box<EvalAltResult>> { fn read_file(path: PathBuf) -> Result<String, Box<EvalAltResult>> {
let mut f = File::open(path.clone()).map_err(|err| { let mut f = File::open(path.clone()).map_err(|err| {
EvalAltResult::ErrorReadingScriptFile(path.clone(), Position::none(), err) EvalAltResult::ErrorReadingScriptFile(path.clone(), Position::none(), err)
@ -935,6 +954,7 @@ impl Engine {
/// ``` /// ```
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)]
pub fn compile_file(&self, path: PathBuf) -> Result<AST, Box<EvalAltResult>> { pub fn compile_file(&self, path: PathBuf) -> Result<AST, Box<EvalAltResult>> {
self.compile_file_with_scope(&Scope::new(), path) self.compile_file_with_scope(&Scope::new(), path)
} }
@ -972,6 +992,7 @@ impl Engine {
/// ``` /// ```
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)]
pub fn compile_file_with_scope( pub fn compile_file_with_scope(
&self, &self,
scope: &Scope, scope: &Scope,
@ -1081,6 +1102,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
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(&Scope::new(), script) self.compile_expression_with_scope(&Scope::new(), script)
} }
@ -1124,6 +1146,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline]
pub fn compile_expression_with_scope( pub fn compile_expression_with_scope(
&self, &self,
scope: &Scope, scope: &Scope,
@ -1154,6 +1177,7 @@ impl Engine {
/// ``` /// ```
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)]
pub fn eval_file<T: Variant + Clone>(&self, path: PathBuf) -> Result<T, Box<EvalAltResult>> { pub fn eval_file<T: Variant + Clone>(&self, path: PathBuf) -> Result<T, Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.eval::<T>(&contents)) Self::read_file(path).and_then(|contents| self.eval::<T>(&contents))
} }
@ -1179,6 +1203,7 @@ impl Engine {
/// ``` /// ```
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)]
pub fn eval_file_with_scope<T: Variant + Clone>( pub fn eval_file_with_scope<T: Variant + Clone>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1201,6 +1226,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn eval<T: Variant + Clone>(&self, script: &str) -> Result<T, Box<EvalAltResult>> { pub fn eval<T: Variant + Clone>(&self, script: &str) -> Result<T, Box<EvalAltResult>> {
self.eval_with_scope(&mut Scope::new(), script) self.eval_with_scope(&mut Scope::new(), script)
} }
@ -1227,6 +1253,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline]
pub fn eval_with_scope<T: Variant + Clone>( pub fn eval_with_scope<T: Variant + Clone>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1254,6 +1281,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn eval_expression<T: Variant + Clone>( pub fn eval_expression<T: Variant + Clone>(
&self, &self,
script: &str, script: &str,
@ -1279,6 +1307,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline]
pub fn eval_expression_with_scope<T: Variant + Clone>( pub fn eval_expression_with_scope<T: Variant + Clone>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1311,6 +1340,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
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 Scope::new(), ast) self.eval_ast_with_scope(&mut Scope::new(), ast)
} }
@ -1344,6 +1374,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline]
pub fn eval_ast_with_scope<T: Variant + Clone>( pub fn eval_ast_with_scope<T: Variant + Clone>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1365,6 +1396,7 @@ impl Engine {
} }
/// Evaluate an `AST` with own scope. /// Evaluate an `AST` with own scope.
#[inline]
pub(crate) fn eval_ast_with_scope_raw<'a>( pub(crate) fn eval_ast_with_scope_raw<'a>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1389,6 +1421,7 @@ impl Engine {
/// 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.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)]
pub fn consume_file(&self, path: PathBuf) -> Result<(), Box<EvalAltResult>> { pub fn consume_file(&self, path: PathBuf) -> Result<(), Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.consume(&contents)) Self::read_file(path).and_then(|contents| self.consume(&contents))
} }
@ -1397,6 +1430,7 @@ impl Engine {
/// 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.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[inline(always)]
pub fn consume_file_with_scope( pub fn consume_file_with_scope(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1407,12 +1441,14 @@ impl Engine {
/// Evaluate a string, but throw away the result and only return error (if any). /// Evaluate a string, 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)]
pub fn consume(&self, script: &str) -> Result<(), Box<EvalAltResult>> { pub fn consume(&self, script: &str) -> Result<(), Box<EvalAltResult>> {
self.consume_with_scope(&mut Scope::new(), script) self.consume_with_scope(&mut Scope::new(), script)
} }
/// Evaluate a string with own scope, but throw away the result and only return error (if any). /// Evaluate a string 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]
pub fn consume_with_scope( pub fn consume_with_scope(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1426,12 +1462,14 @@ impl Engine {
/// Evaluate an AST, but throw away the result and only return error (if any). /// Evaluate an AST, 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)]
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 Scope::new(), ast) self.consume_ast_with_scope(&mut Scope::new(), 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]
pub fn consume_ast_with_scope( pub fn consume_ast_with_scope(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1491,6 +1529,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline]
pub fn call_fn<A: FuncArgs, T: Variant + Clone>( pub fn call_fn<A: FuncArgs, T: Variant + Clone>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1565,6 +1604,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)]
pub fn call_fn_dynamic( pub fn call_fn_dynamic(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1587,6 +1627,7 @@ impl Engine {
/// 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.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline]
pub(crate) fn call_fn_dynamic_raw( pub(crate) fn call_fn_dynamic_raw(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
@ -1624,6 +1665,7 @@ impl Engine {
/// compiled just once. Before evaluation, constants are passed into the `Engine` via an external scope /// compiled just once. Before evaluation, constants are passed into the `Engine` via an external scope
/// (i.e. with `scope.push_constant(...)`). Then, the `AST is cloned and the copy re-optimized before running. /// (i.e. with `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]
pub fn optimize_ast( pub fn optimize_ast(
&self, &self,
scope: &Scope, scope: &Scope,
@ -1678,6 +1720,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn on_progress( pub fn on_progress(
&mut self, &mut self,
callback: impl Fn(&u64) -> bool + SendSync + 'static, callback: impl Fn(&u64) -> bool + SendSync + 'static,
@ -1710,6 +1753,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self { pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self {
self.print = Box::new(callback); self.print = Box::new(callback);
self self
@ -1739,6 +1783,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn on_debug(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self { pub fn on_debug(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self {
self.debug = Box::new(callback); self.debug = Box::new(callback);
self self

View File

@ -440,6 +440,7 @@ impl fmt::Debug for Engine {
} }
impl Default for Engine { impl Default for Engine {
#[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
@ -606,6 +607,7 @@ pub fn search_scope_only<'s, 'a>(
impl Engine { impl Engine {
/// Create a new `Engine` /// Create a new `Engine`
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
// Create the new scripting Engine // Create the new scripting Engine
let mut engine = Self { let mut engine = Self {
@ -661,6 +663,7 @@ impl 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` method to load additional packages of functions.
#[inline(always)]
pub fn new_raw() -> Self { pub fn new_raw() -> Self {
Self { Self {
id: None, id: None,
@ -2040,6 +2043,7 @@ impl Engine {
} }
/// Make a Box<EvalAltResult<ErrorMismatchDataType>>. /// Make a Box<EvalAltResult<ErrorMismatchDataType>>.
#[inline(always)]
pub fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> Box<EvalAltResult> { pub fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> Box<EvalAltResult> {
EvalAltResult::ErrorMismatchDataType( EvalAltResult::ErrorMismatchDataType(
typ.into(), typ.into(),

View File

@ -60,6 +60,7 @@ impl fmt::Display for LexError {
impl LexError { impl LexError {
/// Convert a `LexError` into a `ParseError`. /// Convert a `LexError` into a `ParseError`.
#[inline(always)]
pub fn into_err(&self, pos: Position) -> ParseError { pub fn into_err(&self, pos: Position) -> ParseError {
ParseError(Box::new(self.into()), pos) ParseError(Box::new(self.into()), pos)
} }
@ -157,6 +158,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)]
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)
} }
@ -247,6 +249,7 @@ impl fmt::Display for ParseErrorType {
} }
impl From<&LexError> for ParseErrorType { impl From<&LexError> for ParseErrorType {
#[inline(always)]
fn from(err: &LexError) -> Self { fn from(err: &LexError) -> Self {
match err { match err {
LexError::StringTooLong(max) => { LexError::StringTooLong(max) => {
@ -264,6 +267,7 @@ pub struct ParseError(pub Box<ParseErrorType>, pub Position);
impl Error for ParseError {} impl Error for ParseError {}
impl fmt::Display for ParseError { impl fmt::Display for ParseError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)?; fmt::Display::fmt(&self.0, f)?;
@ -277,12 +281,14 @@ impl fmt::Display for ParseError {
} }
impl From<ParseErrorType> for Box<EvalAltResult> { impl From<ParseErrorType> for Box<EvalAltResult> {
#[inline(always)]
fn from(err: ParseErrorType) -> Self { fn from(err: ParseErrorType) -> Self {
Box::new(EvalAltResult::ErrorParsing(err, Position::none())) Box::new(EvalAltResult::ErrorParsing(err, Position::none()))
} }
} }
impl From<ParseError> for Box<EvalAltResult> { impl From<ParseError> for Box<EvalAltResult> {
#[inline(always)]
fn from(err: ParseError) -> Self { fn from(err: ParseError) -> Self {
Box::new(EvalAltResult::ErrorParsing(*err.0, err.1)) Box::new(EvalAltResult::ErrorParsing(*err.0, err.1))
} }

View File

@ -19,6 +19,7 @@ macro_rules! impl_args {
($($p:ident),*) => { ($($p:ident),*) => {
impl<$($p: Variant + Clone),*> FuncArgs for ($($p,)*) impl<$($p: Variant + Clone),*> FuncArgs for ($($p,)*)
{ {
#[inline]
fn into_vec(self) -> StaticVec<Dynamic> { fn into_vec(self) -> StaticVec<Dynamic> {
let ($($p,)*) = self; let ($($p,)*) = self;

View File

@ -439,6 +439,7 @@ impl Engine {
} }
// Has a system function an override? // Has a system function an override?
#[inline]
pub(crate) fn has_override_by_name_and_arguments( pub(crate) fn has_override_by_name_and_arguments(
&self, &self,
lib: &Module, lib: &Module,
@ -459,6 +460,7 @@ impl Engine {
} }
// Has a system function an override? // Has a system function an override?
#[inline(always)]
pub(crate) fn has_override( pub(crate) fn has_override(
&self, &self,
lib: &Module, lib: &Module,

View File

@ -96,6 +96,7 @@ macro_rules! def_anonymous_fn {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
type Output = Box<dyn Fn($($par),*) -> Result<RET, Box<EvalAltResult>>>; type Output = Box<dyn Fn($($par),*) -> Result<RET, Box<EvalAltResult>>>;
#[inline(always)]
fn create_from_ast(self, ast: AST, entry_point: &str) -> Self::Output { fn create_from_ast(self, ast: AST, entry_point: &str) -> Self::Output {
let fn_name = entry_point.to_string(); let fn_name = entry_point.to_string();
@ -104,6 +105,7 @@ macro_rules! def_anonymous_fn {
}) })
} }
#[inline(always)]
fn create_from_script(self, script: &str, entry_point: &str) -> Result<Self::Output, ParseError> { fn create_from_script(self, script: &str, entry_point: &str) -> Result<Self::Output, ParseError> {
let ast = self.compile(script)?; let ast = self.compile(script)?;
Ok(Func::<($($par,)*), RET>::create_from_ast(self, ast, entry_point)) Ok(Func::<($($par,)*), RET>::create_from_ast(self, ast, entry_point))

View File

@ -78,22 +78,27 @@ pub struct FnPtr(ImmutableString, Vec<Dynamic>);
impl FnPtr { impl FnPtr {
/// Create a new function pointer. /// Create a new function pointer.
#[inline(always)]
pub(crate) fn new_unchecked<S: Into<ImmutableString>>(name: S, curry: Vec<Dynamic>) -> Self { pub(crate) fn new_unchecked<S: Into<ImmutableString>>(name: S, curry: Vec<Dynamic>) -> Self {
Self(name.into(), curry) Self(name.into(), curry)
} }
/// Get the name of the function. /// Get the name of the function.
#[inline(always)]
pub fn fn_name(&self) -> &str { pub fn fn_name(&self) -> &str {
self.get_fn_name().as_ref() self.get_fn_name().as_ref()
} }
/// Get the name of the function. /// Get the name of the function.
#[inline(always)]
pub(crate) fn get_fn_name(&self) -> &ImmutableString { pub(crate) fn get_fn_name(&self) -> &ImmutableString {
&self.0 &self.0
} }
/// Get the underlying data of the function pointer. /// Get the underlying data of the function pointer.
#[inline(always)]
pub(crate) fn take_data(self) -> (ImmutableString, Vec<Dynamic>) { pub(crate) fn take_data(self) -> (ImmutableString, Vec<Dynamic>) {
(self.0, self.1) (self.0, self.1)
} }
/// Get the curried arguments. /// Get the curried arguments.
#[inline(always)]
pub fn curry(&self) -> &[Dynamic] { pub fn curry(&self) -> &[Dynamic] {
&self.1 &self.1
} }
@ -153,6 +158,7 @@ impl FnPtr {
} }
impl fmt::Display for FnPtr { impl fmt::Display for FnPtr {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Fn({})", self.0) write!(f, "Fn({})", self.0)
} }
@ -161,6 +167,7 @@ impl fmt::Display for FnPtr {
impl TryFrom<ImmutableString> for FnPtr { impl TryFrom<ImmutableString> for FnPtr {
type Error = Box<EvalAltResult>; type Error = Box<EvalAltResult>;
#[inline(always)]
fn try_from(value: ImmutableString) -> Result<Self, Self::Error> { fn try_from(value: ImmutableString) -> Result<Self, Self::Error> {
if is_valid_identifier(value.chars()) { if is_valid_identifier(value.chars()) {
Ok(Self(value, Default::default())) Ok(Self(value, Default::default()))
@ -173,6 +180,7 @@ impl TryFrom<ImmutableString> for FnPtr {
impl TryFrom<String> for FnPtr { impl TryFrom<String> for FnPtr {
type Error = Box<EvalAltResult>; type Error = Box<EvalAltResult>;
#[inline(always)]
fn try_from(value: String) -> Result<Self, Self::Error> { fn try_from(value: String) -> Result<Self, Self::Error> {
let s: ImmutableString = value.into(); let s: ImmutableString = value.into();
Self::try_from(s) Self::try_from(s)
@ -182,6 +190,7 @@ impl TryFrom<String> for FnPtr {
impl TryFrom<&str> for FnPtr { impl TryFrom<&str> for FnPtr {
type Error = Box<EvalAltResult>; type Error = Box<EvalAltResult>;
#[inline(always)]
fn try_from(value: &str) -> Result<Self, Self::Error> { fn try_from(value: &str) -> Result<Self, Self::Error> {
let s: ImmutableString = value.into(); let s: ImmutableString = value.into();
Self::try_from(s) Self::try_from(s)
@ -399,26 +408,31 @@ impl CallableFunction {
} }
} }
/// Create a new `CallableFunction::Pure`. /// Create a new `CallableFunction::Pure`.
#[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)]
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)]
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())
} }
} }
impl From<IteratorFn> for CallableFunction { impl From<IteratorFn> for CallableFunction {
#[inline(always)]
fn from(func: IteratorFn) -> Self { fn from(func: IteratorFn) -> Self {
Self::Iterator(func) Self::Iterator(func)
} }
} }
impl From<ScriptFnDef> for CallableFunction { impl From<ScriptFnDef> for CallableFunction {
#[inline(always)]
fn from(_func: ScriptFnDef) -> Self { fn from(_func: ScriptFnDef) -> Self {
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
unreachable!(); unreachable!();
@ -429,6 +443,7 @@ impl From<ScriptFnDef> for CallableFunction {
} }
impl From<Shared<ScriptFnDef>> for CallableFunction { impl From<Shared<ScriptFnDef>> for CallableFunction {
#[inline(always)]
fn from(_func: Shared<ScriptFnDef>) -> Self { fn from(_func: Shared<ScriptFnDef>) -> Self {
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
unreachable!(); unreachable!();
@ -439,12 +454,14 @@ impl From<Shared<ScriptFnDef>> for CallableFunction {
} }
impl<T: PluginFunction + 'static + SendSync> From<T> for CallableFunction { impl<T: PluginFunction + 'static + SendSync> From<T> for CallableFunction {
#[inline(always)]
fn from(func: T) -> Self { fn from(func: T) -> Self {
Self::from_plugin(func) Self::from_plugin(func)
} }
} }
impl From<Shared<FnPlugin>> for CallableFunction { impl From<Shared<FnPlugin>> for CallableFunction {
#[inline(always)]
fn from(func: Shared<FnPlugin>) -> Self { fn from(func: Shared<FnPlugin>) -> Self {
Self::Plugin(func.into()) Self::Plugin(func.into())
} }

View File

@ -188,6 +188,7 @@ macro_rules! def_register {
RET: Variant + Clone RET: Variant + Clone
> RegisterFn<FN, ($($mark,)*), RET> for Engine > RegisterFn<FN, ($($mark,)*), RET> for Engine
{ {
#[inline]
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self { fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
self.global_module.set_fn(name, FnAccess::Public, self.global_module.set_fn(name, FnAccess::Public,
&[$(map_type_id::<$par>()),*], &[$(map_type_id::<$par>()),*],
@ -202,6 +203,7 @@ macro_rules! def_register {
FN: Fn($($param),*) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static, FN: Fn($($param),*) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
> RegisterResultFn<FN, ($($mark,)*)> for Engine > RegisterResultFn<FN, ($($mark,)*)> for Engine
{ {
#[inline]
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self { fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
self.global_module.set_fn(name, FnAccess::Public, self.global_module.set_fn(name, FnAccess::Public,
&[$(map_type_id::<$par>()),*], &[$(map_type_id::<$par>()),*],

View File

@ -103,6 +103,7 @@ impl fmt::Debug for Module {
} }
impl Clone for Module { impl Clone for Module {
#[inline(always)]
fn clone(&self) -> Self { fn clone(&self) -> Self {
// Only clone the index at the top level // Only clone the index at the top level
Self { Self {
@ -115,6 +116,7 @@ impl Clone for Module {
} }
impl AsRef<Module> for Module { impl AsRef<Module> for Module {
#[inline(always)]
fn as_ref(&self) -> &Module { fn as_ref(&self) -> &Module {
self self
} }
@ -132,6 +134,7 @@ impl Module {
/// module.set_var("answer", 42_i64); /// module.set_var("answer", 42_i64);
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42); /// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
@ -147,6 +150,7 @@ impl Module {
/// module.set_var("answer", 42_i64); /// module.set_var("answer", 42_i64);
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42); /// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn new_with_capacity(capacity: usize) -> Self { pub fn new_with_capacity(capacity: usize) -> Self {
Self { Self {
functions: HashMap::with_capacity_and_hasher(capacity, StraightHasherBuilder), functions: HashMap::with_capacity_and_hasher(capacity, StraightHasherBuilder),
@ -164,6 +168,7 @@ impl Module {
/// let module = Module::new(); /// let module = Module::new();
/// assert!(module.is_empty()); /// assert!(module.is_empty());
/// ``` /// ```
#[inline(always)]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.functions.is_empty() self.functions.is_empty()
&& self.all_functions.is_empty() && self.all_functions.is_empty()
@ -174,6 +179,7 @@ impl Module {
} }
/// Clone the module, optionally skipping the index. /// Clone the module, optionally skipping the index.
#[inline(always)]
fn do_clone(&self, clone_index: bool) -> Self { fn do_clone(&self, clone_index: bool) -> Self {
Self { Self {
modules: if clone_index { modules: if clone_index {
@ -202,6 +208,7 @@ impl Module {
/// module.set_var("answer", 42_i64); /// module.set_var("answer", 42_i64);
/// assert!(module.contains_var("answer")); /// assert!(module.contains_var("answer"));
/// ``` /// ```
#[inline(always)]
pub fn contains_var(&self, name: &str) -> bool { pub fn contains_var(&self, name: &str) -> bool {
self.variables.contains_key(name) self.variables.contains_key(name)
} }
@ -217,6 +224,7 @@ impl Module {
/// module.set_var("answer", 42_i64); /// module.set_var("answer", 42_i64);
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42); /// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn get_var_value<T: Variant + Clone>(&self, name: &str) -> Option<T> { pub fn get_var_value<T: Variant + Clone>(&self, name: &str) -> Option<T> {
self.get_var(name).and_then(Dynamic::try_cast::<T>) self.get_var(name).and_then(Dynamic::try_cast::<T>)
} }
@ -232,6 +240,7 @@ impl Module {
/// module.set_var("answer", 42_i64); /// module.set_var("answer", 42_i64);
/// assert_eq!(module.get_var("answer").unwrap().cast::<i64>(), 42); /// assert_eq!(module.get_var("answer").unwrap().cast::<i64>(), 42);
/// ``` /// ```
#[inline(always)]
pub fn get_var(&self, name: &str) -> Option<Dynamic> { pub fn get_var(&self, name: &str) -> Option<Dynamic> {
self.variables.get(name).cloned() self.variables.get(name).cloned()
} }
@ -249,6 +258,7 @@ impl Module {
/// module.set_var("answer", 42_i64); /// module.set_var("answer", 42_i64);
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42); /// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn set_var(&mut self, name: impl Into<String>, value: impl Variant + Clone) -> &mut Self { pub fn set_var(&mut self, name: impl Into<String>, value: impl Variant + Clone) -> &mut Self {
self.variables.insert(name.into(), Dynamic::from(value)); self.variables.insert(name.into(), Dynamic::from(value));
self.indexed = false; self.indexed = false;
@ -259,6 +269,7 @@ impl Module {
/// 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_fn_hash`. /// The `u64` hash is calculated by the function `crate::calc_fn_hash`.
#[inline(always)]
pub(crate) fn get_qualified_var_mut( pub(crate) fn get_qualified_var_mut(
&mut self, &mut self,
hash_var: u64, hash_var: u64,
@ -276,6 +287,7 @@ impl Module {
/// ///
/// If there is an existing function of the same name and number of arguments, it is replaced. /// If there is an existing function of the same name and number of arguments, it is replaced.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline]
pub(crate) fn set_script_fn(&mut self, fn_def: ScriptFnDef) -> u64 { pub(crate) fn set_script_fn(&mut self, fn_def: ScriptFnDef) -> u64 {
// None + function name + number of arguments. // None + function name + number of arguments.
let num_params = fn_def.params.len(); let num_params = fn_def.params.len();
@ -296,6 +308,7 @@ impl Module {
/// Get a script-defined function in the module based on name and number of parameters. /// Get a script-defined function in the module based on name and number of parameters.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)]
pub fn get_script_fn( pub fn get_script_fn(
&self, &self,
name: &str, name: &str,
@ -324,6 +337,7 @@ impl Module {
/// module.set_sub_module("question", sub_module); /// module.set_sub_module("question", sub_module);
/// assert!(module.contains_sub_module("question")); /// assert!(module.contains_sub_module("question"));
/// ``` /// ```
#[inline(always)]
pub fn contains_sub_module(&self, name: &str) -> bool { pub fn contains_sub_module(&self, name: &str) -> bool {
self.modules.contains_key(name) self.modules.contains_key(name)
} }
@ -340,6 +354,7 @@ impl Module {
/// module.set_sub_module("question", sub_module); /// module.set_sub_module("question", sub_module);
/// assert!(module.get_sub_module("question").is_some()); /// assert!(module.get_sub_module("question").is_some());
/// ``` /// ```
#[inline(always)]
pub fn get_sub_module(&self, name: &str) -> Option<&Module> { pub fn get_sub_module(&self, name: &str) -> Option<&Module> {
self.modules.get(name) self.modules.get(name)
} }
@ -356,6 +371,7 @@ impl Module {
/// module.set_sub_module("question", sub_module); /// module.set_sub_module("question", sub_module);
/// assert!(module.get_sub_module_mut("question").is_some()); /// assert!(module.get_sub_module_mut("question").is_some());
/// ``` /// ```
#[inline(always)]
pub fn get_sub_module_mut(&mut self, name: &str) -> Option<&mut Module> { pub fn get_sub_module_mut(&mut self, name: &str) -> Option<&mut Module> {
self.modules.get_mut(name) self.modules.get_mut(name)
} }
@ -374,6 +390,7 @@ impl Module {
/// module.set_sub_module("question", sub_module); /// module.set_sub_module("question", sub_module);
/// assert!(module.get_sub_module("question").is_some()); /// assert!(module.get_sub_module("question").is_some());
/// ``` /// ```
#[inline(always)]
pub fn set_sub_module(&mut self, name: impl Into<String>, sub_module: Module) -> &mut Self { pub fn set_sub_module(&mut self, name: impl Into<String>, sub_module: Module) -> &mut Self {
self.modules.insert(name.into(), sub_module.into()); self.modules.insert(name.into(), sub_module.into());
self.indexed = false; self.indexed = false;
@ -394,6 +411,7 @@ impl Module {
/// let hash = module.set_fn_0("calc", || Ok(42_i64)); /// let hash = module.set_fn_0("calc", || Ok(42_i64));
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn contains_fn(&self, hash_fn: u64, public_only: bool) -> bool { pub fn contains_fn(&self, hash_fn: u64, public_only: bool) -> bool {
if hash_fn == 0 { if hash_fn == 0 {
false false
@ -513,6 +531,7 @@ impl Module {
/// ///
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_raw_fn<T: Variant + Clone>( pub fn set_raw_fn<T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -534,6 +553,7 @@ impl Module {
/// are not determined), but the implementation is in Rust. /// are not determined), but the implementation is in Rust.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline]
pub(crate) fn set_raw_fn_as_scripted( pub(crate) fn set_raw_fn_as_scripted(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -571,6 +591,7 @@ impl Module {
/// let hash = module.set_fn_0("calc", || Ok(42_i64)); /// let hash = module.set_fn_0("calc", || Ok(42_i64));
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_0<T: Variant + Clone>( pub fn set_fn_0<T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -599,6 +620,7 @@ impl Module {
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1)); /// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_1<A: Variant + Clone, T: Variant + Clone>( pub fn set_fn_1<A: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -629,6 +651,7 @@ impl Module {
/// let hash = module.set_fn_1_mut("calc", |x: &mut i64| { *x += 1; Ok(*x) }); /// let hash = module.set_fn_1_mut("calc", |x: &mut i64| { *x += 1; Ok(*x) });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_1_mut<A: Variant + Clone, T: Variant + Clone>( pub fn set_fn_1_mut<A: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -660,6 +683,7 @@ impl Module {
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline]
pub fn set_getter_fn<A: Variant + Clone, T: Variant + Clone>( pub fn set_getter_fn<A: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -683,6 +707,7 @@ impl Module {
/// }); /// });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_2<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>( pub fn set_fn_2<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -719,6 +744,7 @@ impl Module {
/// }); /// });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_2_mut<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>( pub fn set_fn_2_mut<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -757,6 +783,7 @@ impl Module {
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline]
pub fn set_setter_fn<A: Variant + Clone, B: Variant + Clone>( pub fn set_setter_fn<A: Variant + Clone, B: Variant + Clone>(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
@ -787,6 +814,7 @@ impl Module {
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline]
pub fn set_indexer_get_fn<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>( pub fn set_indexer_get_fn<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
func: impl Fn(&mut A, B) -> FuncReturn<T> + SendSync + 'static, func: impl Fn(&mut A, B) -> FuncReturn<T> + SendSync + 'static,
@ -823,6 +851,7 @@ impl Module {
/// }); /// });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_3< pub fn set_fn_3<
A: Variant + Clone, A: Variant + Clone,
B: Variant + Clone, B: Variant + Clone,
@ -865,6 +894,7 @@ impl Module {
/// }); /// });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_3_mut< pub fn set_fn_3_mut<
A: Variant + Clone, A: Variant + Clone,
B: Variant + Clone, B: Variant + Clone,
@ -914,6 +944,7 @@ impl Module {
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline]
pub fn set_indexer_set_fn<A: Variant + Clone, B: Variant + Clone, C: Variant + Clone>( pub fn set_indexer_set_fn<A: Variant + Clone, B: Variant + Clone, C: Variant + Clone>(
&mut self, &mut self,
func: impl Fn(&mut A, B, C) -> FuncReturn<()> + SendSync + 'static, func: impl Fn(&mut A, B, C) -> FuncReturn<()> + SendSync + 'static,
@ -977,6 +1008,7 @@ impl Module {
/// assert!(module.contains_fn(hash_set, true)); /// assert!(module.contains_fn(hash_set, true));
/// ``` /// ```
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline]
pub fn set_indexer_get_set_fn<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>( pub fn set_indexer_get_set_fn<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
&mut self, &mut self,
getter: impl Fn(&mut A, B) -> FuncReturn<T> + SendSync + 'static, getter: impl Fn(&mut A, B) -> FuncReturn<T> + SendSync + 'static,
@ -1003,6 +1035,7 @@ impl Module {
/// }); /// });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_4< pub fn set_fn_4<
A: Variant + Clone, A: Variant + Clone,
B: Variant + Clone, B: Variant + Clone,
@ -1052,6 +1085,7 @@ impl Module {
/// }); /// });
/// assert!(module.contains_fn(hash, true)); /// assert!(module.contains_fn(hash, true));
/// ``` /// ```
#[inline]
pub fn set_fn_4_mut< pub fn set_fn_4_mut<
A: Variant + Clone, A: Variant + Clone,
B: Variant + Clone, B: Variant + Clone,
@ -1089,6 +1123,7 @@ impl Module {
/// ///
/// The `u64` hash is calculated by the function `crate::calc_fn_hash`. /// The `u64` hash is calculated by the function `crate::calc_fn_hash`.
/// It is also returned by the `set_fn_XXX` calls. /// It is also returned by the `set_fn_XXX` calls.
#[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> {
if hash_fn == 0 { if hash_fn == 0 {
None None
@ -1108,12 +1143,14 @@ impl Module {
/// ///
/// The `u64` hash is calculated by the function `crate::calc_fn_hash` and must match /// The `u64` hash is calculated by the function `crate::calc_fn_hash` and must match
/// the hash calculated by `index_all_sub_modules`. /// the hash calculated by `index_all_sub_modules`.
#[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)
} }
/// Combine another module into this module. /// Combine another module into this module.
/// The other module is consumed to merge into this module. /// The other module is consumed to merge into this module.
#[inline]
pub fn combine(&mut self, other: Self) -> &mut Self { pub fn combine(&mut self, other: Self) -> &mut Self {
if !other.modules.is_empty() { if !other.modules.is_empty() {
self.modules.extend(other.modules.into_iter()); self.modules.extend(other.modules.into_iter());
@ -1136,6 +1173,7 @@ impl Module {
/// Combine another module into this module. /// Combine another module into this module.
/// The other module is consumed to merge into this module. /// The other module is consumed to merge into this module.
/// Sub-modules are flattened onto the root module, with higher level overriding lower level. /// Sub-modules are flattened onto the root module, with higher level overriding lower level.
#[inline]
pub fn combine_flatten(&mut self, other: Self) -> &mut Self { pub fn combine_flatten(&mut self, other: Self) -> &mut Self {
if !other.modules.is_empty() { if !other.modules.is_empty() {
other.modules.into_iter().for_each(|(_, m)| { other.modules.into_iter().for_each(|(_, m)| {
@ -1158,6 +1196,7 @@ impl Module {
} }
/// Merge another module into this module. /// Merge another module into this module.
#[inline(always)]
pub fn merge(&mut self, other: &Self) -> &mut Self { pub fn merge(&mut self, other: &Self) -> &mut Self {
self.merge_filtered(other, &mut |_, _, _| true) self.merge_filtered(other, &mut |_, _, _| true)
} }
@ -1213,6 +1252,7 @@ impl Module {
/// Filter out the functions, retaining only some based on a filter predicate. /// Filter out the functions, retaining only some based on a filter predicate.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline]
pub(crate) fn retain_functions( pub(crate) fn retain_functions(
&mut self, &mut self,
mut filter: impl FnMut(FnAccess, &str, usize) -> bool, mut filter: impl FnMut(FnAccess, &str, usize) -> bool,
@ -1229,6 +1269,7 @@ impl Module {
} }
/// Get the number of variables, functions and type iterators in the module. /// Get the number of variables, functions and type iterators in the module.
#[inline(always)]
pub fn count(&self) -> (usize, usize, usize) { pub fn count(&self) -> (usize, usize, usize) {
( (
self.variables.len(), self.variables.len(),
@ -1238,11 +1279,13 @@ impl Module {
} }
/// Get an iterator to the variables in the module. /// Get an iterator to the variables in the module.
#[inline(always)]
pub fn iter_var(&self) -> impl Iterator<Item = (&String, &Dynamic)> { pub fn iter_var(&self) -> impl Iterator<Item = (&String, &Dynamic)> {
self.variables.iter() self.variables.iter()
} }
/// Get an iterator to the functions in the module. /// Get an iterator to the functions in the module.
#[inline(always)]
pub(crate) fn iter_fn(&self) -> impl Iterator<Item = &FuncInfo> { pub(crate) fn iter_fn(&self) -> impl Iterator<Item = &FuncInfo> {
self.functions.values() self.functions.values()
} }
@ -1255,6 +1298,7 @@ impl Module {
/// 3) Number of parameters. /// 3) Number of parameters.
/// 4) Shared reference to function definition `ScriptFnDef`. /// 4) Shared reference to function definition `ScriptFnDef`.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)]
pub(crate) fn iter_script_fn<'a>( pub(crate) fn iter_script_fn<'a>(
&'a self, &'a self,
) -> impl Iterator<Item = (FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a { ) -> impl Iterator<Item = (FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a {
@ -1277,6 +1321,7 @@ impl Module {
/// 3) Number of parameters. /// 3) Number of parameters.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
#[inline(always)]
pub fn iter_script_fn_info(&self) -> impl Iterator<Item = (FnAccess, &str, usize)> { pub fn iter_script_fn_info(&self) -> impl Iterator<Item = (FnAccess, &str, usize)> {
self.functions self.functions
.values() .values()

View File

@ -42,35 +42,43 @@ impl ModuleResolversCollection {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// engine.set_module_resolver(Some(collection)); /// engine.set_module_resolver(Some(collection));
/// ``` /// ```
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
/// Add a module keyed by its path. /// Add a module keyed by its path.
#[inline(always)]
pub fn push(&mut self, resolver: impl ModuleResolver + 'static) { pub fn push(&mut self, resolver: impl ModuleResolver + 'static) {
self.0.push(Box::new(resolver)); self.0.push(Box::new(resolver));
} }
/// Get an iterator of all the module resolvers. /// Get an iterator of all the module resolvers.
#[inline(always)]
pub fn iter(&self) -> impl Iterator<Item = &dyn ModuleResolver> { pub fn iter(&self) -> impl Iterator<Item = &dyn ModuleResolver> {
self.0.iter().map(|v| v.as_ref()) self.0.iter().map(|v| v.as_ref())
} }
/// Get a mutable iterator of all the modules. /// Get a mutable iterator of all the modules.
#[inline(always)]
pub fn into_iter(self) -> impl Iterator<Item = Box<dyn ModuleResolver>> { pub fn into_iter(self) -> impl Iterator<Item = Box<dyn ModuleResolver>> {
self.0.into_iter() self.0.into_iter()
} }
/// Remove all module resolvers. /// Remove all module resolvers.
#[inline(always)]
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)]
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)]
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)]
pub fn append(&mut self, other: Self) { pub fn append(&mut self, other: Self) {
if !other.is_empty() { if !other.is_empty() {
self.0.extend(other.0.into_iter()); self.0.extend(other.0.into_iter());
@ -101,6 +109,7 @@ impl ModuleResolver for ModuleResolversCollection {
} }
impl<M: ModuleResolver + 'static> AddAssign<M> for ModuleResolversCollection { impl<M: ModuleResolver + 'static> AddAssign<M> for ModuleResolversCollection {
#[inline(always)]
fn add_assign(&mut self, rhs: M) { fn add_assign(&mut self, rhs: M) {
self.push(rhs); self.push(rhs);
} }

View File

@ -48,6 +48,7 @@ pub struct FileModuleResolver {
} }
impl Default for FileModuleResolver { impl Default for FileModuleResolver {
#[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::new_with_path(PathBuf::default()) Self::new_with_path(PathBuf::default())
} }
@ -69,6 +70,7 @@ impl FileModuleResolver {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// engine.set_module_resolver(Some(resolver)); /// engine.set_module_resolver(Some(resolver));
/// ``` /// ```
#[inline(always)]
pub fn new_with_path<P: Into<PathBuf>>(path: P) -> Self { pub fn new_with_path<P: Into<PathBuf>>(path: P) -> Self {
Self::new_with_path_and_extension(path, "rhai") Self::new_with_path_and_extension(path, "rhai")
} }
@ -90,6 +92,7 @@ impl FileModuleResolver {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// engine.set_module_resolver(Some(resolver)); /// engine.set_module_resolver(Some(resolver));
/// ``` /// ```
#[inline(always)]
pub fn new_with_path_and_extension<P: Into<PathBuf>, E: Into<String>>( pub fn new_with_path_and_extension<P: Into<PathBuf>, E: Into<String>>(
path: P, path: P,
extension: E, extension: E,
@ -116,11 +119,13 @@ impl FileModuleResolver {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// engine.set_module_resolver(Some(resolver)); /// engine.set_module_resolver(Some(resolver));
/// ``` /// ```
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
/// Create a `Module` from a file path. /// Create a `Module` from a file path.
#[inline(always)]
pub fn create_module<P: Into<PathBuf>>( pub fn create_module<P: Into<PathBuf>>(
&self, &self,
engine: &Engine, engine: &Engine,

View File

@ -42,59 +42,73 @@ impl StaticModuleResolver {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// engine.set_module_resolver(Some(resolver)); /// engine.set_module_resolver(Some(resolver));
/// ``` /// ```
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
/// Add a module keyed by its path. /// Add a module keyed by its path.
#[inline(always)]
pub fn insert<S: Into<String>>(&mut self, path: S, module: Module) { pub fn insert<S: Into<String>>(&mut self, path: S, module: Module) {
self.0.insert(path.into(), module); self.0.insert(path.into(), module);
} }
/// Remove a module given its path. /// Remove a module given its path.
#[inline(always)]
pub fn remove(&mut self, path: &str) -> Option<Module> { pub fn remove(&mut self, path: &str) -> Option<Module> {
self.0.remove(path) self.0.remove(path)
} }
/// Does the path exist? /// Does the path exist?
#[inline(always)]
pub fn contains_path(&self, path: &str) -> bool { pub fn contains_path(&self, path: &str) -> bool {
self.0.contains_key(path) self.0.contains_key(path)
} }
/// Get an iterator of all the modules. /// Get an iterator of all the modules.
#[inline(always)]
pub fn iter(&self) -> impl Iterator<Item = (&str, &Module)> { pub fn iter(&self) -> impl Iterator<Item = (&str, &Module)> {
self.0.iter().map(|(k, v)| (k.as_str(), v)) self.0.iter().map(|(k, v)| (k.as_str(), v))
} }
/// Get a mutable iterator of all the modules. /// Get a mutable iterator of all the modules.
#[inline(always)]
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &mut Module)> { pub fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &mut Module)> {
self.0.iter_mut().map(|(k, v)| (k.as_str(), v)) self.0.iter_mut().map(|(k, v)| (k.as_str(), v))
} }
/// Get a mutable iterator of all the modules. /// Get a mutable iterator of all the modules.
#[inline(always)]
pub fn into_iter(self) -> impl Iterator<Item = (String, Module)> { pub fn into_iter(self) -> impl Iterator<Item = (String, Module)> {
self.0.into_iter() self.0.into_iter()
} }
/// Get an iterator of all the module paths. /// Get an iterator of all the module paths.
#[inline(always)]
pub fn paths(&self) -> impl Iterator<Item = &str> { pub fn paths(&self) -> impl Iterator<Item = &str> {
self.0.keys().map(String::as_str) self.0.keys().map(String::as_str)
} }
/// Get an iterator of all the modules. /// Get an iterator of all the modules.
#[inline(always)]
pub fn values(&self) -> impl Iterator<Item = &Module> { pub fn values(&self) -> impl Iterator<Item = &Module> {
self.0.values() self.0.values()
} }
/// Get a mutable iterator of all the modules. /// Get a mutable iterator of all the modules.
#[inline(always)]
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Module> { pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Module> {
self.0.values_mut() self.0.values_mut()
} }
/// Remove all modules. /// Remove all modules.
#[inline(always)]
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)]
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)]
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)]
pub fn merge(&mut self, other: Self) { pub fn merge(&mut self, other: Self) {
if !other.is_empty() { if !other.is_empty() {
self.0.extend(other.0.into_iter()); self.0.extend(other.0.into_iter());
@ -103,6 +117,7 @@ impl StaticModuleResolver {
} }
impl ModuleResolver for StaticModuleResolver { impl ModuleResolver for StaticModuleResolver {
#[inline(always)]
fn resolve(&self, _: &Engine, path: &str, pos: Position) -> Result<Module, Box<EvalAltResult>> { fn resolve(&self, _: &Engine, path: &str, pos: Position) -> Result<Module, Box<EvalAltResult>> {
self.0 self.0
.get(path) .get(path)
@ -112,6 +127,7 @@ impl ModuleResolver for StaticModuleResolver {
} }
impl AddAssign<Self> for StaticModuleResolver { impl AddAssign<Self> for StaticModuleResolver {
#[inline(always)]
fn add_assign(&mut self, rhs: Self) { fn add_assign(&mut self, rhs: Self) {
self.merge(rhs); self.merge(rhs);
} }

View File

@ -44,16 +44,19 @@ pub enum OptimizationLevel {
impl OptimizationLevel { impl OptimizationLevel {
/// Is the `OptimizationLevel` None. /// Is the `OptimizationLevel` None.
#[inline(always)]
pub fn is_none(self) -> bool { pub fn is_none(self) -> bool {
self == Self::None self == Self::None
} }
/// Is the `OptimizationLevel` Simple. /// Is the `OptimizationLevel` Simple.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline(always)]
pub fn is_simple(self) -> bool { pub fn is_simple(self) -> bool {
self == Self::Simple self == Self::Simple
} }
/// Is the `OptimizationLevel` Full. /// Is the `OptimizationLevel` Full.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline(always)]
pub fn is_full(self) -> bool { pub fn is_full(self) -> bool {
self == Self::Full self == Self::Full
} }
@ -75,6 +78,7 @@ struct State<'a> {
impl<'a> State<'a> { impl<'a> State<'a> {
/// Create a new State. /// Create a new State.
#[inline(always)]
pub fn new(engine: &'a Engine, lib: &'a Module, level: OptimizationLevel) -> Self { pub fn new(engine: &'a Engine, lib: &'a Module, level: OptimizationLevel) -> Self {
Self { Self {
changed: false, changed: false,
@ -85,30 +89,37 @@ impl<'a> State<'a> {
} }
} }
/// Reset the state from dirty to clean. /// Reset the state from dirty to clean.
#[inline(always)]
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.changed = false; self.changed = false;
} }
/// Set the AST state to be dirty (i.e. changed). /// Set the AST state to be dirty (i.e. changed).
#[inline(always)]
pub fn set_dirty(&mut self) { pub fn set_dirty(&mut self) {
self.changed = true; self.changed = true;
} }
/// Is the AST dirty (i.e. changed)? /// Is the AST dirty (i.e. changed)?
#[inline(always)]
pub fn is_dirty(&self) -> bool { pub fn is_dirty(&self) -> bool {
self.changed self.changed
} }
/// Does a constant exist? /// Does a constant exist?
#[inline(always)]
pub fn contains_constant(&self, name: &str) -> bool { pub fn contains_constant(&self, name: &str) -> bool {
self.constants.iter().any(|(n, _)| n == name) self.constants.iter().any(|(n, _)| n == name)
} }
/// Prune the list of constants back to a specified size. /// Prune the list of constants back to a specified size.
#[inline(always)]
pub fn restore_constants(&mut self, len: usize) { pub fn restore_constants(&mut self, len: usize) {
self.constants.truncate(len) self.constants.truncate(len)
} }
/// Add a new constant to the list. /// Add a new constant to the list.
#[inline(always)]
pub fn push_constant(&mut self, name: &str, value: Expr) { pub fn push_constant(&mut self, name: &str, value: Expr) {
self.constants.push((name.into(), value)) self.constants.push((name.into(), value))
} }
/// Look up a constant from the list. /// Look up a constant from the list.
#[inline]
pub fn find_constant(&self, name: &str) -> Option<&Expr> { pub fn find_constant(&self, name: &str) -> Option<&Expr> {
for (n, expr) in self.constants.iter().rev() { for (n, expr) in self.constants.iter().rev() {
if n == name { if n == name {

View File

@ -28,7 +28,6 @@ macro_rules! gen_arithmetic_functions {
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "+", return_raw)] #[rhai_fn(name = "+", return_raw)]
#[inline]
pub fn add(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn add(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_add(y).ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))).map(Dynamic::from) x.checked_add(y).ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))).map(Dynamic::from)
@ -37,7 +36,6 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = "-", return_raw)] #[rhai_fn(name = "-", return_raw)]
#[inline]
pub fn subtract(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn subtract(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_sub(y).ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))).map(Dynamic::from) x.checked_sub(y).ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))).map(Dynamic::from)
@ -46,7 +44,6 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = "*", return_raw)] #[rhai_fn(name = "*", return_raw)]
#[inline]
pub fn multiply(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn multiply(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_mul(y).ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))).map(Dynamic::from) x.checked_mul(y).ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))).map(Dynamic::from)
@ -55,7 +52,6 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = "/", return_raw)] #[rhai_fn(name = "/", return_raw)]
#[inline]
pub fn divide(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn divide(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
// Detect division by zero // Detect division by zero
@ -69,7 +65,6 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = "%", return_raw)] #[rhai_fn(name = "%", return_raw)]
#[inline]
pub fn modulo(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn modulo(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_rem(y).ok_or_else(|| make_err(format!("Modulo division by zero or overflow: {} % {}", x, y))).map(Dynamic::from) x.checked_rem(y).ok_or_else(|| make_err(format!("Modulo division by zero or overflow: {} % {}", x, y))).map(Dynamic::from)
@ -78,7 +73,6 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = "~", return_raw)] #[rhai_fn(name = "~", return_raw)]
#[inline]
pub fn power(x: INT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn power(x: INT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
@ -94,7 +88,6 @@ macro_rules! gen_arithmetic_functions {
} }
#[rhai_fn(name = "<<", return_raw)] #[rhai_fn(name = "<<", return_raw)]
#[inline]
pub fn shift_left(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn shift_left(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
@ -109,7 +102,6 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = ">>", return_raw)] #[rhai_fn(name = ">>", return_raw)]
#[inline]
pub fn shift_right(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn shift_right(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
@ -124,17 +116,14 @@ macro_rules! gen_arithmetic_functions {
} }
} }
#[rhai_fn(name = "&")] #[rhai_fn(name = "&")]
#[inline(always)]
pub fn binary_and(x: $arg_type, y: $arg_type) -> $arg_type { pub fn binary_and(x: $arg_type, y: $arg_type) -> $arg_type {
x & y x & y
} }
#[rhai_fn(name = "|")] #[rhai_fn(name = "|")]
#[inline(always)]
pub fn binary_or(x: $arg_type, y: $arg_type) -> $arg_type { pub fn binary_or(x: $arg_type, y: $arg_type) -> $arg_type {
x | y x | y
} }
#[rhai_fn(name = "^")] #[rhai_fn(name = "^")]
#[inline(always)]
pub fn binary_xor(x: $arg_type, y: $arg_type) -> $arg_type { pub fn binary_xor(x: $arg_type, y: $arg_type) -> $arg_type {
x ^ y x ^ y
} }
@ -151,7 +140,6 @@ macro_rules! gen_signed_functions {
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "-", return_raw)] #[rhai_fn(name = "-", return_raw)]
#[inline]
pub fn neg(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn neg(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_neg().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from) x.checked_neg().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from)
@ -160,7 +148,6 @@ macro_rules! gen_signed_functions {
} }
} }
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
#[inline]
pub fn abs(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn abs(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_abs().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from) x.checked_abs().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from)
@ -168,7 +155,6 @@ macro_rules! gen_signed_functions {
Ok(Dynamic::from(x.abs())) Ok(Dynamic::from(x.abs()))
} }
} }
#[inline]
pub fn sign(x: $arg_type) -> INT { pub fn sign(x: $arg_type) -> INT {
if x == 0 { if x == 0 {
0 0
@ -239,40 +225,32 @@ gen_signed_functions!(signed_num_128 => i128);
#[export_module] #[export_module]
mod f32_functions { mod f32_functions {
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline(always)]
pub fn add(x: f32, y: f32) -> f32 { pub fn add(x: f32, y: f32) -> f32 {
x + y x + y
} }
#[rhai_fn(name = "-")] #[rhai_fn(name = "-")]
#[inline(always)]
pub fn subtract(x: f32, y: f32) -> f32 { pub fn subtract(x: f32, y: f32) -> f32 {
x - y x - y
} }
#[rhai_fn(name = "*")] #[rhai_fn(name = "*")]
#[inline(always)]
pub fn multiply(x: f32, y: f32) -> f32 { pub fn multiply(x: f32, y: f32) -> f32 {
x * y x * y
} }
#[rhai_fn(name = "/")] #[rhai_fn(name = "/")]
#[inline(always)]
pub fn divide(x: f32, y: f32) -> f32 { pub fn divide(x: f32, y: f32) -> f32 {
x / y x / y
} }
#[rhai_fn(name = "%")] #[rhai_fn(name = "%")]
#[inline(always)]
pub fn modulo(x: f32, y: f32) -> f32 { pub fn modulo(x: f32, y: f32) -> f32 {
x % y x % y
} }
#[rhai_fn(name = "-")] #[rhai_fn(name = "-")]
#[inline(always)]
pub fn neg(x: f32) -> f32 { pub fn neg(x: f32) -> f32 {
-x -x
} }
#[inline(always)]
pub fn abs(x: f32) -> f32 { pub fn abs(x: f32) -> f32 {
x.abs() x.abs()
} }
#[inline]
pub fn sign(x: f32) -> INT { pub fn sign(x: f32) -> INT {
if x == 0.0 { if x == 0.0 {
0 0
@ -283,12 +261,10 @@ mod f32_functions {
} }
} }
#[rhai_fn(name = "~", return_raw)] #[rhai_fn(name = "~", return_raw)]
#[inline(always)]
pub fn pow_f_f(x: f32, y: f32) -> Result<Dynamic, Box<EvalAltResult>> { pub fn pow_f_f(x: f32, y: f32) -> Result<Dynamic, Box<EvalAltResult>> {
Ok(Dynamic::from(x.powf(y))) Ok(Dynamic::from(x.powf(y)))
} }
#[rhai_fn(name = "~", return_raw)] #[rhai_fn(name = "~", return_raw)]
#[inline]
pub fn pow_f_i(x: f32, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn pow_f_i(x: f32, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) { if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) {
Err(make_err(format!( Err(make_err(format!(
@ -305,15 +281,12 @@ mod f32_functions {
#[export_module] #[export_module]
mod f64_functions { mod f64_functions {
#[rhai_fn(name = "-")] #[rhai_fn(name = "-")]
#[inline(always)]
pub fn neg(x: f64) -> f64 { pub fn neg(x: f64) -> f64 {
-x -x
} }
#[inline(always)]
pub fn abs(x: f64) -> f64 { pub fn abs(x: f64) -> f64 {
x.abs() x.abs()
} }
#[inline]
pub fn sign(x: f64) -> INT { pub fn sign(x: f64) -> INT {
if x == 0.0 { if x == 0.0 {
0 0
@ -324,7 +297,6 @@ mod f64_functions {
} }
} }
#[rhai_fn(name = "~", return_raw)] #[rhai_fn(name = "~", return_raw)]
#[inline]
pub fn pow_f_i(x: FLOAT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn pow_f_i(x: FLOAT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) { if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) {
Err(make_err(format!( Err(make_err(format!(

View File

@ -29,7 +29,6 @@ macro_rules! gen_array_functions {
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "push", name = "+=")] #[rhai_fn(name = "push", name = "+=")]
#[inline(always)]
pub fn push(list: &mut Array, item: $arg_type) { pub fn push(list: &mut Array, item: $arg_type) {
list.push(Dynamic::from(item)); list.push(Dynamic::from(item));
} }
@ -89,22 +88,18 @@ def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
#[export_module] #[export_module]
mod array_functions { mod array_functions {
#[rhai_fn(name = "len", get = "len")] #[rhai_fn(name = "len", get = "len")]
#[inline(always)]
pub fn len(list: &mut Array) -> INT { pub fn len(list: &mut Array) -> INT {
list.len() as INT list.len() as INT
} }
#[rhai_fn(name = "append", name = "+=")] #[rhai_fn(name = "append", name = "+=")]
#[inline(always)]
pub fn append(x: &mut Array, y: Array) { pub fn append(x: &mut Array, y: Array) {
x.extend(y); x.extend(y);
} }
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn concat(mut x: Array, y: Array) -> Array { pub fn concat(mut x: Array, y: Array) -> Array {
x.extend(y); x.extend(y);
x x
} }
#[inline]
pub fn pop(list: &mut Array) -> Dynamic { pub fn pop(list: &mut Array) -> Dynamic {
list.pop().unwrap_or_else(|| ().into()) list.pop().unwrap_or_else(|| ().into())
} }
@ -122,7 +117,6 @@ mod array_functions {
list.remove(len as usize) list.remove(len as usize)
} }
} }
#[inline(always)]
pub fn clear(list: &mut Array) { pub fn clear(list: &mut Array) {
list.clear(); list.clear();
} }
@ -133,7 +127,6 @@ mod array_functions {
list.clear(); list.clear();
} }
} }
#[inline(always)]
pub fn reverse(list: &mut Array) { pub fn reverse(list: &mut Array) {
list.reverse(); list.reverse();
} }

View File

@ -9,7 +9,6 @@ def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
#[export_module] #[export_module]
mod fn_ptr_functions { mod fn_ptr_functions {
#[rhai_fn(name = "name", get = "name")] #[rhai_fn(name = "name", get = "name")]
#[inline(always)]
pub fn name(f: &mut FnPtr) -> ImmutableString { pub fn name(f: &mut FnPtr) -> ImmutableString {
f.get_fn_name().clone() f.get_fn_name().clone()
} }

View File

@ -9,32 +9,26 @@ macro_rules! gen_cmp_functions {
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "<")] #[rhai_fn(name = "<")]
#[inline(always)]
pub fn lt(x: $arg_type, y: $arg_type) -> bool { pub fn lt(x: $arg_type, y: $arg_type) -> bool {
x < y x < y
} }
#[rhai_fn(name = "<=")] #[rhai_fn(name = "<=")]
#[inline(always)]
pub fn lte(x: $arg_type, y: $arg_type) -> bool { pub fn lte(x: $arg_type, y: $arg_type) -> bool {
x <= y x <= y
} }
#[rhai_fn(name = ">")] #[rhai_fn(name = ">")]
#[inline(always)]
pub fn gt(x: $arg_type, y: $arg_type) -> bool { pub fn gt(x: $arg_type, y: $arg_type) -> bool {
x > y x > y
} }
#[rhai_fn(name = ">=")] #[rhai_fn(name = ">=")]
#[inline(always)]
pub fn gte(x: $arg_type, y: $arg_type) -> bool { pub fn gte(x: $arg_type, y: $arg_type) -> bool {
x >= y x >= y
} }
#[rhai_fn(name = "==")] #[rhai_fn(name = "==")]
#[inline(always)]
pub fn eq(x: $arg_type, y: $arg_type) -> bool { pub fn eq(x: $arg_type, y: $arg_type) -> bool {
x == y x == y
} }
#[rhai_fn(name = "!=")] #[rhai_fn(name = "!=")]
#[inline(always)]
pub fn ne(x: $arg_type, y: $arg_type) -> bool { pub fn ne(x: $arg_type, y: $arg_type) -> bool {
x != y x != y
} }
@ -67,7 +61,6 @@ def_package!(crate:LogicPackage:"Logical operators.", lib, {
// Logic operators // Logic operators
#[export_fn] #[export_fn]
#[inline(always)]
fn not(x: bool) -> bool { fn not(x: bool) -> bool {
!x !x
} }

View File

@ -14,19 +14,15 @@ def_package!(crate:BasicMapPackage:"Basic object map utilities.", lib, {
#[export_module] #[export_module]
mod map_functions { mod map_functions {
#[inline(always)]
pub fn has(map: &mut Map, prop: ImmutableString) -> bool { pub fn has(map: &mut Map, prop: ImmutableString) -> bool {
map.contains_key(&prop) map.contains_key(&prop)
} }
#[inline(always)]
pub fn len(map: &mut Map) -> INT { pub fn len(map: &mut Map) -> INT {
map.len() as INT map.len() as INT
} }
#[inline(always)]
pub fn clear(map: &mut Map) { pub fn clear(map: &mut Map) {
map.clear(); map.clear();
} }
#[inline(always)]
pub fn remove(x: &mut Map, name: ImmutableString) -> Dynamic { pub fn remove(x: &mut Map, name: ImmutableString) -> Dynamic {
x.remove(&name).unwrap_or_else(|| ().into()) x.remove(&name).unwrap_or_else(|| ().into())
} }

View File

@ -31,7 +31,6 @@ macro_rules! gen_conversion_functions {
use super::super::*; use super::super::*;
#[export_fn] #[export_fn]
#[inline(always)]
pub fn $func_name(x: $arg_type) -> $result_type { pub fn $func_name(x: $arg_type) -> $result_type {
x as $result_type x as $result_type
} }
@ -86,51 +85,39 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, {
mod trig_functions { mod trig_functions {
use crate::parser::FLOAT; use crate::parser::FLOAT;
#[inline(always)]
pub fn sin(x: FLOAT) -> FLOAT { pub fn sin(x: FLOAT) -> FLOAT {
x.to_radians().sin() x.to_radians().sin()
} }
#[inline(always)]
pub fn cos(x: FLOAT) -> FLOAT { pub fn cos(x: FLOAT) -> FLOAT {
x.to_radians().cos() x.to_radians().cos()
} }
#[inline(always)]
pub fn tan(x: FLOAT) -> FLOAT { pub fn tan(x: FLOAT) -> FLOAT {
x.to_radians().tan() x.to_radians().tan()
} }
#[inline(always)]
pub fn sinh(x: FLOAT) -> FLOAT { pub fn sinh(x: FLOAT) -> FLOAT {
x.to_radians().sinh() x.to_radians().sinh()
} }
#[inline(always)]
pub fn cosh(x: FLOAT) -> FLOAT { pub fn cosh(x: FLOAT) -> FLOAT {
x.to_radians().cosh() x.to_radians().cosh()
} }
#[inline(always)]
pub fn tanh(x: FLOAT) -> FLOAT { pub fn tanh(x: FLOAT) -> FLOAT {
x.to_radians().tanh() x.to_radians().tanh()
} }
#[inline(always)]
pub fn asin(x: FLOAT) -> FLOAT { pub fn asin(x: FLOAT) -> FLOAT {
x.asin().to_degrees() x.asin().to_degrees()
} }
#[inline(always)]
pub fn acos(x: FLOAT) -> FLOAT { pub fn acos(x: FLOAT) -> FLOAT {
x.acos().to_degrees() x.acos().to_degrees()
} }
#[inline(always)]
pub fn atan(x: FLOAT) -> FLOAT { pub fn atan(x: FLOAT) -> FLOAT {
x.atan().to_degrees() x.atan().to_degrees()
} }
#[inline(always)]
pub fn asinh(x: FLOAT) -> FLOAT { pub fn asinh(x: FLOAT) -> FLOAT {
x.asinh().to_degrees() x.asinh().to_degrees()
} }
#[inline(always)]
pub fn acosh(x: FLOAT) -> FLOAT { pub fn acosh(x: FLOAT) -> FLOAT {
x.acosh().to_degrees() x.acosh().to_degrees()
} }
#[inline(always)]
pub fn atanh(x: FLOAT) -> FLOAT { pub fn atanh(x: FLOAT) -> FLOAT {
x.atanh().to_degrees() x.atanh().to_degrees()
} }
@ -141,68 +128,54 @@ mod trig_functions {
mod float_functions { mod float_functions {
use crate::parser::FLOAT; use crate::parser::FLOAT;
#[inline(always)]
pub fn sqrt(x: FLOAT) -> FLOAT { pub fn sqrt(x: FLOAT) -> FLOAT {
x.sqrt() x.sqrt()
} }
#[inline(always)]
pub fn exp(x: FLOAT) -> FLOAT { pub fn exp(x: FLOAT) -> FLOAT {
x.exp() x.exp()
} }
#[inline(always)]
pub fn ln(x: FLOAT) -> FLOAT { pub fn ln(x: FLOAT) -> FLOAT {
x.ln() x.ln()
} }
#[inline(always)]
pub fn log(x: FLOAT, base: FLOAT) -> FLOAT { pub fn log(x: FLOAT, base: FLOAT) -> FLOAT {
x.log(base) x.log(base)
} }
#[inline(always)]
pub fn log10(x: FLOAT) -> FLOAT { pub fn log10(x: FLOAT) -> FLOAT {
x.log10() x.log10()
} }
#[rhai_fn(name = "floor", get = "floor")] #[rhai_fn(name = "floor", get = "floor")]
#[inline(always)]
pub fn floor(x: FLOAT) -> FLOAT { pub fn floor(x: FLOAT) -> FLOAT {
x.floor() x.floor()
} }
#[rhai_fn(name = "ceiling", get = "ceiling")] #[rhai_fn(name = "ceiling", get = "ceiling")]
#[inline(always)]
pub fn ceiling(x: FLOAT) -> FLOAT { pub fn ceiling(x: FLOAT) -> FLOAT {
x.ceil() x.ceil()
} }
#[rhai_fn(name = "round", get = "round")] #[rhai_fn(name = "round", get = "round")]
#[inline(always)]
pub fn round(x: FLOAT) -> FLOAT { pub fn round(x: FLOAT) -> FLOAT {
x.ceil() x.ceil()
} }
#[rhai_fn(name = "int", get = "int")] #[rhai_fn(name = "int", get = "int")]
#[inline(always)]
pub fn int(x: FLOAT) -> FLOAT { pub fn int(x: FLOAT) -> FLOAT {
x.trunc() x.trunc()
} }
#[rhai_fn(name = "fraction", get = "fraction")] #[rhai_fn(name = "fraction", get = "fraction")]
#[inline(always)]
pub fn fraction(x: FLOAT) -> FLOAT { pub fn fraction(x: FLOAT) -> FLOAT {
x.fract() x.fract()
} }
#[rhai_fn(name = "is_nan", get = "is_nan")] #[rhai_fn(name = "is_nan", get = "is_nan")]
#[inline(always)]
pub fn is_nan(x: FLOAT) -> bool { pub fn is_nan(x: FLOAT) -> bool {
x.is_nan() x.is_nan()
} }
#[rhai_fn(name = "is_finite", get = "is_finite")] #[rhai_fn(name = "is_finite", get = "is_finite")]
#[inline(always)]
pub fn is_finite(x: FLOAT) -> bool { pub fn is_finite(x: FLOAT) -> bool {
x.is_finite() x.is_finite()
} }
#[rhai_fn(name = "is_infinite", get = "is_infinite")] #[rhai_fn(name = "is_infinite", get = "is_infinite")]
#[inline(always)]
pub fn is_infinite(x: FLOAT) -> bool { pub fn is_infinite(x: FLOAT) -> bool {
x.is_infinite() x.is_infinite()
} }
#[rhai_fn(name = "to_int", return_raw)] #[rhai_fn(name = "to_int", return_raw)]
#[inline]
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( EvalAltResult::ErrorArithmetic(
@ -215,7 +188,6 @@ mod float_functions {
} }
} }
#[rhai_fn(name = "to_int", return_raw)] #[rhai_fn(name = "to_int", return_raw)]
#[inline]
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( EvalAltResult::ErrorArithmetic(
@ -229,7 +201,6 @@ mod float_functions {
} }
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
#[inline]
pub fn parse_float(s: &str) -> Result<Dynamic, Box<EvalAltResult>> { pub fn parse_float(s: &str) -> Result<Dynamic, Box<EvalAltResult>> {
s.trim() s.trim()
.parse::<FLOAT>() .parse::<FLOAT>()
@ -291,7 +262,6 @@ fn parse_int_radix(s: &str, radix: INT) -> Result<Dynamic, Box<EvalAltResult>> {
} }
#[export_fn(return_raw)] #[export_fn(return_raw)]
#[inline(always)]
fn parse_int(s: &str) -> Result<Dynamic, Box<EvalAltResult>> { fn parse_int(s: &str) -> Result<Dynamic, Box<EvalAltResult>> {
parse_int_radix(s, 10) parse_int_radix(s, 10)
} }

View File

@ -26,7 +26,6 @@ macro_rules! gen_functions {
use super::super::*; use super::super::*;
#[export_fn] #[export_fn]
#[inline(always)]
pub fn to_string_func(x: &mut $arg_type) -> ImmutableString { pub fn to_string_func(x: &mut $arg_type) -> ImmutableString {
super::super::$fn_name(x) super::super::$fn_name(x)
} }
@ -124,30 +123,24 @@ gen_functions!(print_array => to_debug(Array));
// Register print and debug // Register print and debug
#[export_fn] #[export_fn]
#[inline(always)]
fn print_empty_string() -> ImmutableString { fn print_empty_string() -> ImmutableString {
"".to_string().into() "".to_string().into()
} }
#[export_fn] #[export_fn]
#[inline(always)]
fn print_unit(_x: ()) -> ImmutableString { fn print_unit(_x: ()) -> ImmutableString {
"".to_string().into() "".to_string().into()
} }
#[export_fn] #[export_fn]
#[inline(always)]
fn print_string(s: ImmutableString) -> ImmutableString { fn print_string(s: ImmutableString) -> ImmutableString {
s s
} }
#[export_fn] #[export_fn]
#[inline(always)]
fn debug_fn_ptr(f: &mut FnPtr) -> ImmutableString { fn debug_fn_ptr(f: &mut FnPtr) -> ImmutableString {
to_string(f) to_string(f)
} }
#[inline(always)]
fn to_string<T: Display>(x: &mut T) -> ImmutableString { fn to_string<T: Display>(x: &mut T) -> ImmutableString {
x.to_string().into() x.to_string().into()
} }
#[inline]
fn to_debug<T: Debug>(x: &mut T) -> ImmutableString { fn to_debug<T: Debug>(x: &mut T) -> ImmutableString {
format!("{:?}", x).into() format!("{:?}", x).into()
} }
@ -155,7 +148,7 @@ fn to_debug<T: Debug>(x: &mut T) -> ImmutableString {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
mod format_map { mod format_map {
use super::*; use super::*;
#[inline]
#[export_fn] #[export_fn]
pub fn format_map(x: &mut Map) -> ImmutableString { pub fn format_map(x: &mut Map) -> ImmutableString {
format!("#{:?}", x).into() format!("#{:?}", x).into()

View File

@ -23,13 +23,11 @@ macro_rules! gen_concat_functions {
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn append_func(x: &str, y: $arg_type) -> String { pub fn append_func(x: &str, y: $arg_type) -> String {
format!("{}{}", x, y) format!("{}{}", x, y)
} }
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn prepend_func(x: &mut $arg_type, y: &str) -> String { pub fn prepend_func(x: &mut $arg_type, y: &str) -> String {
format!("{}{}", x, y) format!("{}{}", x, y)
} }
@ -133,34 +131,28 @@ gen_concat_functions!(float => f32, f64);
#[export_module] #[export_module]
mod string_functions { mod string_functions {
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline(always)]
pub fn add_append_unit(s: ImmutableString, _x: ()) -> ImmutableString { pub fn add_append_unit(s: ImmutableString, _x: ()) -> ImmutableString {
s s
} }
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline(always)]
pub fn add_prepend_unit(_x: (), s: ImmutableString) -> ImmutableString { pub fn add_prepend_unit(_x: (), s: ImmutableString) -> ImmutableString {
s s
} }
#[rhai_fn(name = "+=")] #[rhai_fn(name = "+=")]
#[inline(always)]
pub fn append_char(s: &mut ImmutableString, ch: char) { pub fn append_char(s: &mut ImmutableString, ch: char) {
*s += ch; *s += ch;
} }
#[rhai_fn(name = "+=")] #[rhai_fn(name = "+=")]
#[inline(always)]
pub fn append_string(s: &mut ImmutableString, add: ImmutableString) { pub fn append_string(s: &mut ImmutableString, add: ImmutableString) {
*s += &add; *s += &add;
} }
#[rhai_fn(name = "len", get = "len")] #[rhai_fn(name = "len", get = "len")]
#[inline(always)]
pub fn len(s: &str) -> INT { pub fn len(s: &str) -> INT {
s.chars().count() as INT s.chars().count() as INT
} }
#[inline(always)]
pub fn clear(s: &mut ImmutableString) { pub fn clear(s: &mut ImmutableString) {
s.make_mut().clear(); s.make_mut().clear();
} }
@ -183,11 +175,9 @@ mod string_functions {
} }
#[rhai_fn(name = "contains")] #[rhai_fn(name = "contains")]
#[inline(always)]
pub fn contains_char(s: &str, ch: char) -> bool { pub fn contains_char(s: &str, ch: char) -> bool {
s.contains(ch) s.contains(ch)
} }
#[inline(always)]
pub fn contains(s: &str, find: ImmutableString) -> bool { pub fn contains(s: &str, find: ImmutableString) -> bool {
s.contains(find.as_str()) s.contains(find.as_str())
} }
@ -263,7 +253,6 @@ mod string_functions {
.into() .into()
} }
#[rhai_fn(name = "sub_string")] #[rhai_fn(name = "sub_string")]
#[inline(always)]
pub fn sub_string_starting_from(s: &str, start: INT) -> ImmutableString { pub fn sub_string_starting_from(s: &str, start: INT) -> ImmutableString {
let len = s.len() as INT; let len = s.len() as INT;
sub_string(s, start, len) sub_string(s, start, len)
@ -296,28 +285,23 @@ mod string_functions {
copy.extend(chars.iter().skip(offset).take(len)); copy.extend(chars.iter().skip(offset).take(len));
} }
#[rhai_fn(name = "crop")] #[rhai_fn(name = "crop")]
#[inline(always)]
pub fn crop_string_starting_from(s: &mut ImmutableString, start: INT) { pub fn crop_string_starting_from(s: &mut ImmutableString, start: INT) {
crop(s, start, s.len() as INT); crop(s, start, s.len() as INT);
} }
#[rhai_fn(name = "replace")] #[rhai_fn(name = "replace")]
#[inline(always)]
pub fn replace(s: &mut ImmutableString, find: ImmutableString, sub: ImmutableString) { pub fn replace(s: &mut ImmutableString, find: ImmutableString, sub: ImmutableString) {
*s = s.replace(find.as_str(), sub.as_str()).into(); *s = s.replace(find.as_str(), sub.as_str()).into();
} }
#[rhai_fn(name = "replace")] #[rhai_fn(name = "replace")]
#[inline(always)]
pub fn replace_string_with_char(s: &mut ImmutableString, find: ImmutableString, sub: char) { pub fn replace_string_with_char(s: &mut ImmutableString, find: ImmutableString, sub: char) {
*s = s.replace(find.as_str(), &sub.to_string()).into(); *s = s.replace(find.as_str(), &sub.to_string()).into();
} }
#[rhai_fn(name = "replace")] #[rhai_fn(name = "replace")]
#[inline(always)]
pub fn replace_char_with_string(s: &mut ImmutableString, find: char, sub: ImmutableString) { pub fn replace_char_with_string(s: &mut ImmutableString, find: char, sub: ImmutableString) {
*s = s.replace(&find.to_string(), sub.as_str()).into(); *s = s.replace(&find.to_string(), sub.as_str()).into();
} }
#[rhai_fn(name = "replace")] #[rhai_fn(name = "replace")]
#[inline(always)]
pub fn replace_char(s: &mut ImmutableString, find: char, sub: char) { pub fn replace_char(s: &mut ImmutableString, find: char, sub: char) {
*s = s.replace(&find.to_string(), &sub.to_string()).into(); *s = s.replace(&find.to_string(), &sub.to_string()).into();
} }
@ -327,24 +311,20 @@ mod string_functions {
use crate::engine::Array; use crate::engine::Array;
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn append(x: &str, y: Array) -> String { pub fn append(x: &str, y: Array) -> String {
format!("{}{:?}", x, y) format!("{}{:?}", x, y)
} }
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn prepend(x: &mut Array, y: &str) -> String { pub fn prepend(x: &mut Array, y: &str) -> String {
format!("{:?}{}", x, y) format!("{:?}{}", x, y)
} }
#[inline(always)]
pub fn split(s: &str, delimiter: ImmutableString) -> Array { pub fn split(s: &str, delimiter: ImmutableString) -> Array {
s.split(delimiter.as_str()) s.split(delimiter.as_str())
.map(Into::<Dynamic>::into) .map(Into::<Dynamic>::into)
.collect() .collect()
} }
#[rhai_fn(name = "split")] #[rhai_fn(name = "split")]
#[inline(always)]
pub fn split_char(s: &str, delimiter: char) -> Array { pub fn split_char(s: &str, delimiter: char) -> Array {
s.split(delimiter).map(Into::<Dynamic>::into).collect() s.split(delimiter).map(Into::<Dynamic>::into).collect()
} }
@ -355,12 +335,10 @@ mod string_functions {
use crate::engine::Map; use crate::engine::Map;
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn append(x: &str, y: Map) -> String { pub fn append(x: &str, y: Map) -> String {
format!("{}#{:?}", x, y) format!("{}#{:?}", x, y)
} }
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
#[inline]
pub fn prepend(x: &mut Map, y: &str) -> String { pub fn prepend(x: &mut Map, y: &str) -> String {
format!("#{:?}{}", x, y) format!("#{:?}{}", x, y)
} }

View File

@ -26,7 +26,6 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, {
#[export_module] #[export_module]
mod time_functions { mod time_functions {
#[inline(always)]
pub fn timestamp() -> Instant { pub fn timestamp() -> Instant {
Instant::now() Instant::now()
} }
@ -212,32 +211,26 @@ mod time_functions {
} }
#[rhai_fn(name = "==")] #[rhai_fn(name = "==")]
#[inline(always)]
pub fn eq(x: Instant, y: Instant) -> bool { pub fn eq(x: Instant, y: Instant) -> bool {
x == y x == y
} }
#[rhai_fn(name = "!=")] #[rhai_fn(name = "!=")]
#[inline(always)]
pub fn ne(x: Instant, y: Instant) -> bool { pub fn ne(x: Instant, y: Instant) -> bool {
x != y x != y
} }
#[rhai_fn(name = "<")] #[rhai_fn(name = "<")]
#[inline(always)]
pub fn lt(x: Instant, y: Instant) -> bool { pub fn lt(x: Instant, y: Instant) -> bool {
x < y x < y
} }
#[rhai_fn(name = "<=")] #[rhai_fn(name = "<=")]
#[inline(always)]
pub fn lte(x: Instant, y: Instant) -> bool { pub fn lte(x: Instant, y: Instant) -> bool {
x <= y x <= y
} }
#[rhai_fn(name = ">")] #[rhai_fn(name = ">")]
#[inline(always)]
pub fn gt(x: Instant, y: Instant) -> bool { pub fn gt(x: Instant, y: Instant) -> bool {
x > y x > y
} }
#[rhai_fn(name = ">=")] #[rhai_fn(name = ">=")]
#[inline(always)]
pub fn gte(x: Instant, y: Instant) -> bool { pub fn gte(x: Instant, y: Instant) -> bool {
x >= y x >= y
} }

View File

@ -85,12 +85,14 @@ pub struct AST(
impl AST { impl AST {
/// Create a new `AST`. /// Create a new `AST`.
#[inline(always)]
pub fn new(statements: Vec<Stmt>, lib: Module) -> Self { pub fn new(statements: Vec<Stmt>, lib: Module) -> Self {
Self(statements, lib) Self(statements, lib)
} }
/// Get the statements. /// Get the statements.
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
#[inline(always)]
pub(crate) fn statements(&self) -> &[Stmt] { pub(crate) fn statements(&self) -> &[Stmt] {
&self.0 &self.0
} }
@ -99,17 +101,20 @@ impl AST {
/// 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")]
#[inline(always)]
pub fn statements(&self) -> &[Stmt] { pub fn statements(&self) -> &[Stmt] {
&self.0 &self.0
} }
/// Get a mutable reference to the statements. /// Get a mutable reference to the statements.
#[inline(always)]
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 `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)]
pub(crate) fn lib(&self) -> &Module { pub(crate) fn lib(&self) -> &Module {
&self.1 &self.1
} }
@ -118,6 +123,7 @@ impl AST {
/// 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")]
#[inline(always)]
pub fn lib(&self) -> &Module { pub fn lib(&self) -> &Module {
&self.1 &self.1
} }
@ -126,6 +132,7 @@ impl AST {
/// No statements are cloned. /// No statements are cloned.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
#[inline(always)]
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)
} }
@ -134,6 +141,7 @@ impl AST {
/// No statements are cloned. /// No statements are cloned.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
#[inline(always)]
pub fn clone_functions_only_filtered( pub fn clone_functions_only_filtered(
&self, &self,
mut filter: impl FnMut(FnAccess, &str, usize) -> bool, mut filter: impl FnMut(FnAccess, &str, usize) -> bool,
@ -145,6 +153,7 @@ impl AST {
/// 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)]
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())
} }
@ -198,6 +207,7 @@ impl AST {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn merge(&self, other: &Self) -> Self { pub fn merge(&self, other: &Self) -> Self {
self.merge_filtered(other, |_, _, _| true) self.merge_filtered(other, |_, _, _| true)
} }
@ -250,6 +260,7 @@ impl AST {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
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)
} }
@ -305,6 +316,7 @@ impl AST {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline]
pub fn merge_filtered( pub fn merge_filtered(
&self, &self,
other: &Self, other: &Self,
@ -379,6 +391,7 @@ impl AST {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn combine_filtered( pub fn combine_filtered(
&mut self, &mut self,
other: Self, other: Self,
@ -419,12 +432,14 @@ impl AST {
/// # } /// # }
/// ``` /// ```
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)]
pub fn retain_functions(&mut self, filter: impl FnMut(FnAccess, &str, usize) -> bool) { pub fn retain_functions(&mut self, filter: impl FnMut(FnAccess, &str, usize) -> bool) {
self.1.retain_functions(filter); self.1.retain_functions(filter);
} }
/// Iterate through all functions /// Iterate through all functions
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)]
pub fn iter_functions<'a>( pub fn iter_functions<'a>(
&'a self, &'a self,
) -> impl Iterator<Item = (FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a { ) -> impl Iterator<Item = (FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a {
@ -433,11 +448,13 @@ impl AST {
/// 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)]
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)]
pub fn clear_statements(&mut self) { pub fn clear_statements(&mut self) {
self.0 = vec![]; self.0 = vec![];
} }
@ -446,24 +463,28 @@ impl AST {
impl<A: AsRef<AST>> Add<A> for &AST { impl<A: AsRef<AST>> Add<A> for &AST {
type Output = AST; type Output = AST;
#[inline(always)]
fn add(self, rhs: A) -> Self::Output { fn add(self, rhs: A) -> Self::Output {
self.merge(rhs.as_ref()) self.merge(rhs.as_ref())
} }
} }
impl<A: Into<AST>> AddAssign<A> for AST { impl<A: Into<AST>> AddAssign<A> for AST {
#[inline(always)]
fn add_assign(&mut self, rhs: A) { fn add_assign(&mut self, rhs: A) {
self.combine(rhs.into()); self.combine(rhs.into());
} }
} }
impl AsRef<[Stmt]> for AST { impl AsRef<[Stmt]> for AST {
#[inline(always)]
fn as_ref(&self) -> &[Stmt] { fn as_ref(&self) -> &[Stmt] {
self.statements() self.statements()
} }
} }
impl AsRef<Module> for AST { impl AsRef<Module> for AST {
#[inline(always)]
fn as_ref(&self) -> &Module { fn as_ref(&self) -> &Module {
self.lib() self.lib()
} }
@ -479,6 +500,7 @@ pub enum FnAccess {
} }
impl fmt::Display for FnAccess { impl fmt::Display for FnAccess {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Private => write!(f, "private"), Self::Private => write!(f, "private"),
@ -489,6 +511,7 @@ impl fmt::Display for FnAccess {
impl FnAccess { impl FnAccess {
/// Is this access mode private? /// Is this access mode private?
#[inline(always)]
pub fn is_private(self) -> bool { pub fn is_private(self) -> bool {
match self { match self {
Self::Public => false, Self::Public => false,
@ -496,6 +519,7 @@ impl FnAccess {
} }
} }
/// Is this access mode public? /// Is this access mode public?
#[inline(always)]
pub fn is_public(self) -> bool { pub fn is_public(self) -> bool {
match self { match self {
Self::Public => true, Self::Public => true,
@ -587,6 +611,7 @@ struct ParseState<'e> {
impl<'e> ParseState<'e> { impl<'e> ParseState<'e> {
/// Create a new `ParseState`. /// Create a new `ParseState`.
#[inline(always)]
pub fn new( pub fn new(
engine: &'e Engine, engine: &'e Engine,
#[cfg(not(feature = "unchecked"))] max_expr_depth: usize, #[cfg(not(feature = "unchecked"))] max_expr_depth: usize,
@ -614,6 +639,7 @@ impl<'e> ParseState<'e> {
/// The return value is the offset to be deducted from `Stack::len`, /// The return value is the offset to be deducted from `Stack::len`,
/// i.e. the top element of the `ParseState` is offset 1. /// i.e. the top element of the `ParseState` is offset 1.
/// Return `None` when the variable name is not found in the `stack`. /// Return `None` when the variable name is not found in the `stack`.
#[inline]
fn access_var(&mut self, name: &str, _pos: Position) -> Option<NonZeroUsize> { fn access_var(&mut self, name: &str, _pos: Position) -> Option<NonZeroUsize> {
let index = self let index = self
.stack .stack
@ -639,6 +665,7 @@ impl<'e> ParseState<'e> {
/// The return value is the offset to be deducted from `Stack::len`, /// The return value is the offset to be deducted from `Stack::len`,
/// i.e. the top element of the `ParseState` is offset 1. /// i.e. the top element of the `ParseState` is offset 1.
/// Return `None` when the variable name is not found in the `ParseState`. /// Return `None` when the variable name is not found in the `ParseState`.
#[inline(always)]
pub fn find_module(&self, name: &str) -> Option<NonZeroUsize> { pub fn find_module(&self, name: &str) -> Option<NonZeroUsize> {
self.modules self.modules
.iter() .iter()
@ -672,6 +699,7 @@ struct ParseSettings {
impl ParseSettings { impl ParseSettings {
/// Create a new `ParseSettings` with one higher expression level. /// Create a new `ParseSettings` with one higher expression level.
#[inline(always)]
pub fn level_up(&self) -> Self { pub fn level_up(&self) -> Self {
Self { Self {
level: self.level + 1, level: self.level + 1,
@ -680,6 +708,7 @@ impl ParseSettings {
} }
/// Make sure that the current level of expression nesting is within the maximum limit. /// Make sure that the current level of expression nesting is within the maximum limit.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline]
pub fn ensure_level_within_max_limit(&self, limit: usize) -> Result<(), ParseError> { pub fn ensure_level_within_max_limit(&self, limit: usize) -> Result<(), ParseError> {
if limit == 0 { if limit == 0 {
Ok(()) Ok(())
@ -739,6 +768,7 @@ pub enum Stmt {
} }
impl Default for Stmt { impl Default for Stmt {
#[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::Noop(Default::default()) Self::Noop(Default::default())
} }
@ -861,12 +891,14 @@ impl Stmt {
pub struct CustomExpr(pub StaticVec<Expr>, pub Shared<FnCustomSyntaxEval>); pub struct CustomExpr(pub StaticVec<Expr>, pub Shared<FnCustomSyntaxEval>);
impl fmt::Debug for CustomExpr { impl fmt::Debug for CustomExpr {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f) fmt::Debug::fmt(&self.0, f)
} }
} }
impl Hash for CustomExpr { impl Hash for CustomExpr {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state); self.0.hash(state);
} }
@ -887,6 +919,7 @@ pub struct FloatWrapper(pub FLOAT, pub Position);
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
impl Hash for FloatWrapper { impl Hash for FloatWrapper {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
state.write(&self.0.to_le_bytes()); state.write(&self.0.to_le_bytes());
self.1.hash(state); self.1.hash(state);
@ -969,6 +1002,7 @@ pub enum Expr {
} }
impl Default for Expr { impl Default for Expr {
#[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::Unit(Default::default()) Self::Unit(Default::default())
} }
@ -1216,6 +1250,7 @@ impl Expr {
/// Convert a `Variable` into a `Property`. All other variants are untouched. /// Convert a `Variable` into a `Property`. All other variants are untouched.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline]
pub(crate) fn into_property(self) -> Self { pub(crate) fn into_property(self) -> Self {
match self { match self {
Self::Variable(x) if x.1.is_none() => { Self::Variable(x) if x.1.is_none() => {
@ -3611,6 +3646,7 @@ impl Engine {
} }
/// Run the parser on an input stream, returning an AST. /// Run the parser on an input stream, returning an AST.
#[inline(always)]
pub(crate) fn parse( pub(crate) fn parse(
&self, &self,
input: &mut TokenStream, input: &mut TokenStream,

View File

@ -252,6 +252,7 @@ impl fmt::Display for EvalAltResult {
} }
impl<T: AsRef<str>> From<T> for Box<EvalAltResult> { impl<T: AsRef<str>> From<T> for Box<EvalAltResult> {
#[inline(always)]
fn from(err: T) -> Self { fn from(err: T) -> Self {
Box::new(EvalAltResult::ErrorRuntime( Box::new(EvalAltResult::ErrorRuntime(
err.as_ref().to_string(), err.as_ref().to_string(),
@ -337,6 +338,7 @@ impl EvalAltResult {
/// 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)]
pub(crate) fn new_position(mut self: Box<Self>, new_position: Position) -> Box<Self> { pub(crate) fn new_position(mut self: Box<Self>, new_position: Position) -> Box<Self> {
if self.position().is_none() { if self.position().is_none() {
self.set_position(new_position); self.set_position(new_position);
@ -346,6 +348,7 @@ impl EvalAltResult {
} }
impl<T> From<EvalAltResult> for Result<T, Box<EvalAltResult>> { impl<T> From<EvalAltResult> for Result<T, Box<EvalAltResult>> {
#[inline(always)]
fn from(err: EvalAltResult) -> Self { fn from(err: EvalAltResult) -> Self {
Err(err.into()) Err(err.into())
} }

View File

@ -74,6 +74,7 @@ impl<'a> Scope<'a> {
/// my_scope.push("x", 42_i64); /// my_scope.push("x", 42_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
@ -97,6 +98,7 @@ impl<'a> Scope<'a> {
/// assert_eq!(my_scope.len(), 0); /// assert_eq!(my_scope.len(), 0);
/// assert!(my_scope.is_empty()); /// assert!(my_scope.is_empty());
/// ``` /// ```
#[inline(always)]
pub fn clear(&mut self) -> &mut Self { pub fn clear(&mut self) -> &mut Self {
self.0.clear(); self.0.clear();
self self
@ -115,6 +117,7 @@ impl<'a> Scope<'a> {
/// my_scope.push("x", 42_i64); /// my_scope.push("x", 42_i64);
/// assert_eq!(my_scope.len(), 1); /// assert_eq!(my_scope.len(), 1);
/// ``` /// ```
#[inline(always)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.0.len() self.0.len()
} }
@ -132,6 +135,7 @@ impl<'a> Scope<'a> {
/// my_scope.push("x", 42_i64); /// my_scope.push("x", 42_i64);
/// assert!(!my_scope.is_empty()); /// assert!(!my_scope.is_empty());
/// ``` /// ```
#[inline(always)]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.len() == 0 self.0.len() == 0
} }
@ -148,6 +152,7 @@ impl<'a> Scope<'a> {
/// my_scope.push("x", 42_i64); /// my_scope.push("x", 42_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn push<K: Into<Cow<'a, str>>, T: Variant + Clone>( pub fn push<K: Into<Cow<'a, str>>, T: Variant + Clone>(
&mut self, &mut self,
name: K, name: K,
@ -168,6 +173,7 @@ impl<'a> Scope<'a> {
/// my_scope.push_dynamic("x", Dynamic::from(42_i64)); /// my_scope.push_dynamic("x", Dynamic::from(42_i64));
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn push_dynamic<K: Into<Cow<'a, str>>>(&mut self, name: K, value: Dynamic) -> &mut Self { pub fn push_dynamic<K: Into<Cow<'a, str>>>(&mut self, name: K, value: Dynamic) -> &mut Self {
self.push_dynamic_value(name, EntryType::Normal, value, false) self.push_dynamic_value(name, EntryType::Normal, value, false)
} }
@ -190,6 +196,7 @@ impl<'a> Scope<'a> {
/// my_scope.push_constant("x", 42_i64); /// my_scope.push_constant("x", 42_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn push_constant<K: Into<Cow<'a, str>>, T: Variant + Clone>( pub fn push_constant<K: Into<Cow<'a, str>>, T: Variant + Clone>(
&mut self, &mut self,
name: K, name: K,
@ -217,6 +224,7 @@ impl<'a> Scope<'a> {
/// my_scope.push_constant_dynamic("x", Dynamic::from(42_i64)); /// my_scope.push_constant_dynamic("x", Dynamic::from(42_i64));
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn push_constant_dynamic<K: Into<Cow<'a, str>>>( pub fn push_constant_dynamic<K: Into<Cow<'a, str>>>(
&mut self, &mut self,
name: K, name: K,
@ -226,6 +234,7 @@ impl<'a> Scope<'a> {
} }
/// 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]
pub(crate) fn push_dynamic_value<K: Into<Cow<'a, str>>>( pub(crate) fn push_dynamic_value<K: Into<Cow<'a, str>>>(
&mut self, &mut self,
name: K, name: K,
@ -276,6 +285,7 @@ impl<'a> Scope<'a> {
/// assert_eq!(my_scope.len(), 0); /// assert_eq!(my_scope.len(), 0);
/// assert!(my_scope.is_empty()); /// assert!(my_scope.is_empty());
/// ``` /// ```
#[inline(always)]
pub fn rewind(&mut self, size: usize) -> &mut Self { pub fn rewind(&mut self, size: usize) -> &mut Self {
self.0.truncate(size); self.0.truncate(size);
self self
@ -294,6 +304,7 @@ impl<'a> Scope<'a> {
/// assert!(my_scope.contains("x")); /// assert!(my_scope.contains("x"));
/// assert!(!my_scope.contains("y")); /// assert!(!my_scope.contains("y"));
/// ``` /// ```
#[inline(always)]
pub fn contains(&self, name: &str) -> bool { pub fn contains(&self, name: &str) -> bool {
self.0 self.0
.iter() .iter()
@ -302,6 +313,7 @@ impl<'a> Scope<'a> {
} }
/// Find an entry in the Scope, starting from the last. /// Find an entry in the Scope, starting from the last.
#[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.0 self.0
.iter() .iter()
@ -317,6 +329,7 @@ impl<'a> Scope<'a> {
} }
/// Get an entry in the Scope, starting from the last. /// Get an entry in the Scope, starting from the last.
#[inline(always)]
pub(crate) fn get_entry(&self, name: &str) -> Option<&Entry> { pub(crate) fn get_entry(&self, name: &str) -> Option<&Entry> {
self.0 self.0
.iter() .iter()
@ -336,6 +349,7 @@ impl<'a> Scope<'a> {
/// my_scope.push("x", 42_i64); /// my_scope.push("x", 42_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ``` /// ```
#[inline(always)]
pub fn get_value<T: Variant + Clone>(&self, name: &str) -> Option<T> { pub fn get_value<T: Variant + Clone>(&self, name: &str) -> Option<T> {
self.get_entry(name) self.get_entry(name)
.and_then(|Entry { value, .. }| value.flatten_clone().try_cast()) .and_then(|Entry { value, .. }| value.flatten_clone().try_cast())
@ -362,6 +376,7 @@ impl<'a> Scope<'a> {
/// my_scope.set_value("x", 0_i64); /// my_scope.set_value("x", 0_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 0); /// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 0);
/// ``` /// ```
#[inline(always)]
pub fn set_value<T: Variant + Clone>(&mut self, name: &'a str, value: T) -> &mut Self { pub fn set_value<T: Variant + Clone>(&mut self, name: &'a str, value: T) -> &mut Self {
match self.get_index(name) { match self.get_index(name) {
None => { None => {
@ -376,6 +391,7 @@ impl<'a> Scope<'a> {
} }
/// Get a mutable reference to an entry in the Scope. /// Get a mutable reference to an entry in the Scope.
#[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) {
let entry = self.0.get_mut(index).expect("invalid index in Scope"); let entry = self.0.get_mut(index).expect("invalid index in Scope");
(&mut entry.value, entry.typ) (&mut entry.value, entry.typ)
@ -383,6 +399,7 @@ impl<'a> Scope<'a> {
/// 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)]
pub(crate) fn set_entry_alias(&mut self, index: usize, alias: String) -> &mut Self { pub(crate) fn set_entry_alias(&mut self, index: usize, alias: String) -> &mut Self {
let entry = self.0.get_mut(index).expect("invalid index in Scope"); let entry = self.0.get_mut(index).expect("invalid index in Scope");
entry.alias = Some(Box::new(alias)); entry.alias = Some(Box::new(alias));
@ -391,6 +408,7 @@ impl<'a> Scope<'a> {
/// 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]
pub(crate) fn flatten_clone(&self) -> Self { pub(crate) fn flatten_clone(&self) -> Self {
let mut entries: Vec<Entry> = Default::default(); let mut entries: Vec<Entry> = Default::default();
@ -408,11 +426,13 @@ impl<'a> Scope<'a> {
} }
/// Get an iterator to entries in the Scope. /// Get an iterator to entries in the Scope.
#[inline(always)]
pub(crate) fn into_iter(self) -> impl Iterator<Item = Entry<'a>> { pub(crate) fn into_iter(self) -> impl Iterator<Item = Entry<'a>> {
self.0.into_iter() self.0.into_iter()
} }
/// Get an iterator to entries in the Scope in reverse order. /// Get an iterator to entries in the Scope in reverse order.
#[inline(always)]
pub(crate) fn to_iter(&self) -> impl Iterator<Item = &Entry> { pub(crate) fn to_iter(&self) -> impl Iterator<Item = &Entry> {
self.0.iter().rev() // Always search a Scope in reverse order self.0.iter().rev() // Always search a Scope in reverse order
} }
@ -439,6 +459,7 @@ impl<'a> Scope<'a> {
/// assert_eq!(name, "foo"); /// assert_eq!(name, "foo");
/// assert_eq!(value.cast::<String>(), "hello"); /// assert_eq!(value.cast::<String>(), "hello");
/// ``` /// ```
#[inline(always)]
pub fn iter(&self) -> impl Iterator<Item = (&str, Dynamic)> { pub fn iter(&self) -> impl Iterator<Item = (&str, Dynamic)> {
self.iter_raw() self.iter_raw()
.map(|(name, value)| (name, value.flatten_clone())) .map(|(name, value)| (name, value.flatten_clone()))
@ -446,6 +467,7 @@ impl<'a> Scope<'a> {
/// 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)]
pub fn iter_raw(&self) -> impl Iterator<Item = (&str, &Dynamic)> { pub fn iter_raw(&self) -> impl Iterator<Item = (&str, &Dynamic)> {
self.0 self.0
.iter() .iter()
@ -454,6 +476,7 @@ impl<'a> Scope<'a> {
} }
impl<'a, K: Into<Cow<'a, str>>> iter::Extend<(K, EntryType, Dynamic)> for Scope<'a> { impl<'a, K: Into<Cow<'a, str>>> iter::Extend<(K, EntryType, Dynamic)> for Scope<'a> {
#[inline(always)]
fn extend<T: IntoIterator<Item = (K, EntryType, Dynamic)>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = (K, EntryType, Dynamic)>>(&mut self, iter: T) {
self.0 self.0
.extend(iter.into_iter().map(|(name, typ, value)| Entry { .extend(iter.into_iter().map(|(name, typ, value)| Entry {

View File

@ -21,6 +21,7 @@ impl Engine {
/// ///
/// 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.
#[inline(always)]
pub fn load_package(&mut self, package: impl Into<PackageLibrary>) -> &mut Self { pub fn load_package(&mut self, package: impl Into<PackageLibrary>) -> &mut Self {
// Push the package to the top - packages are searched in reverse order // Push the package to the top - packages are searched in reverse order
self.packages.push(package.into()); self.packages.push(package.into());
@ -31,6 +32,7 @@ impl Engine {
/// ///
/// Not available under the `no_optimize` feature. /// Not available under the `no_optimize` feature.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline(always)]
pub fn set_optimization_level(&mut self, optimization_level: OptimizationLevel) -> &mut Self { pub fn set_optimization_level(&mut self, optimization_level: OptimizationLevel) -> &mut Self {
self.optimization_level = optimization_level; self.optimization_level = optimization_level;
self self
@ -41,6 +43,7 @@ impl Engine {
/// ///
/// Not available under the `no_optimize` feature. /// Not available under the `no_optimize` feature.
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
#[inline(always)]
pub fn optimization_level(&self) -> OptimizationLevel { pub fn optimization_level(&self) -> OptimizationLevel {
self.optimization_level self.optimization_level
} }
@ -48,6 +51,7 @@ impl Engine {
/// Set the maximum levels of function calls allowed for a script in order to avoid /// Set the maximum levels of function calls allowed for a script in order to avoid
/// infinite recursion and stack overflows. /// infinite recursion and stack overflows.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn set_max_call_levels(&mut self, levels: usize) -> &mut Self { pub fn set_max_call_levels(&mut self, levels: usize) -> &mut Self {
self.limits.max_call_stack_depth = levels; self.limits.max_call_stack_depth = levels;
self self
@ -55,6 +59,7 @@ impl Engine {
/// The maximum levels of function calls allowed for a script. /// The maximum levels of function calls allowed for a script.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn max_call_levels(&self) -> usize { pub fn max_call_levels(&self) -> usize {
self.limits.max_call_stack_depth self.limits.max_call_stack_depth
} }
@ -62,6 +67,7 @@ impl Engine {
/// Set the maximum number of operations allowed for a script to run to avoid /// Set the maximum number of operations allowed for a script to run to avoid
/// consuming too much resources (0 for unlimited). /// consuming too much resources (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn set_max_operations(&mut self, operations: u64) -> &mut Self { pub fn set_max_operations(&mut self, operations: u64) -> &mut Self {
self.limits.max_operations = if operations == u64::MAX { self.limits.max_operations = if operations == u64::MAX {
0 0
@ -73,12 +79,14 @@ impl Engine {
/// The maximum number of operations allowed for a script to run (0 for unlimited). /// The maximum number of operations allowed for a script to run (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn max_operations(&self) -> u64 { pub fn max_operations(&self) -> u64 {
self.limits.max_operations self.limits.max_operations
} }
/// Set the maximum number of imported modules allowed for a script. /// Set the maximum number of imported modules allowed for a script.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn set_max_modules(&mut self, modules: usize) -> &mut Self { pub fn set_max_modules(&mut self, modules: usize) -> &mut Self {
self.limits.max_modules = modules; self.limits.max_modules = modules;
self self
@ -86,12 +94,14 @@ impl Engine {
/// The maximum number of imported modules allowed for a script. /// The maximum number of imported modules allowed for a script.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn max_modules(&self) -> usize { pub fn max_modules(&self) -> usize {
self.limits.max_modules self.limits.max_modules
} }
/// Set the depth limits for expressions (0 for unlimited). /// Set the depth limits for expressions (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn set_max_expr_depths( pub fn set_max_expr_depths(
&mut self, &mut self,
max_expr_depth: usize, max_expr_depth: usize,
@ -112,18 +122,21 @@ impl Engine {
/// The depth limit for expressions (0 for unlimited). /// The depth limit for expressions (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn max_expr_depth(&self) -> usize { pub fn max_expr_depth(&self) -> usize {
self.limits.max_expr_depth self.limits.max_expr_depth
} }
/// The depth limit for expressions in functions (0 for unlimited). /// The depth limit for expressions in functions (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn max_function_expr_depth(&self) -> usize { pub fn max_function_expr_depth(&self) -> usize {
self.limits.max_function_expr_depth self.limits.max_function_expr_depth
} }
/// Set the maximum length of strings (0 for unlimited). /// Set the maximum length of strings (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self { pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self {
self.limits.max_string_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_string_size = if max_size == usize::MAX { 0 } else { max_size };
self self
@ -131,6 +144,7 @@ impl Engine {
/// The maximum length of strings (0 for unlimited). /// The maximum length of strings (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn max_string_size(&self) -> usize { pub fn max_string_size(&self) -> usize {
self.limits.max_string_size self.limits.max_string_size
} }
@ -138,6 +152,7 @@ impl Engine {
/// Set the maximum length of arrays (0 for unlimited). /// Set the maximum length of arrays (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn set_max_array_size(&mut self, max_size: usize) -> &mut Self { pub fn set_max_array_size(&mut self, max_size: usize) -> &mut Self {
self.limits.max_array_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_array_size = if max_size == usize::MAX { 0 } else { max_size };
self self
@ -146,6 +161,7 @@ impl Engine {
/// The maximum length of arrays (0 for unlimited). /// The maximum length of arrays (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)]
pub fn max_array_size(&self) -> usize { pub fn max_array_size(&self) -> usize {
self.limits.max_array_size self.limits.max_array_size
} }
@ -153,6 +169,7 @@ impl Engine {
/// Set the maximum length of object maps (0 for unlimited). /// Set the maximum length of object maps (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn set_max_map_size(&mut self, max_size: usize) -> &mut Self { pub fn set_max_map_size(&mut self, max_size: usize) -> &mut Self {
self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size };
self self
@ -161,6 +178,7 @@ impl Engine {
/// The maximum length of object maps (0 for unlimited). /// The maximum length of object maps (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)]
pub fn max_map_size(&self) -> usize { pub fn max_map_size(&self) -> usize {
self.limits.max_map_size self.limits.max_map_size
} }
@ -169,6 +187,7 @@ impl 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"))]
#[inline(always)]
pub fn set_module_resolver( pub fn set_module_resolver(
&mut self, &mut self,
resolver: Option<impl ModuleResolver + 'static>, resolver: Option<impl ModuleResolver + 'static>,
@ -213,6 +232,7 @@ impl Engine {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[inline(always)]
pub fn disable_symbol(&mut self, symbol: &str) -> &mut Self { pub fn disable_symbol(&mut self, symbol: &str) -> &mut Self {
if self.disabled_symbols.is_none() { if self.disabled_symbols.is_none() {
self.disabled_symbols = Some(Default::default()); self.disabled_symbols = Some(Default::default());

View File

@ -36,6 +36,7 @@ pub type FnCustomSyntaxEval = dyn Fn(&Engine, &mut EvalContext, &mut Scope, &[Ex
pub struct Expression<'a>(&'a Expr); pub struct Expression<'a>(&'a Expr);
impl<'a> From<&'a Expr> for Expression<'a> { impl<'a> From<&'a Expr> for Expression<'a> {
#[inline(always)]
fn from(expr: &'a Expr) -> Self { fn from(expr: &'a Expr) -> Self {
Self(expr) Self(expr)
} }
@ -43,6 +44,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)]
pub fn get_variable_name(&self) -> Option<&str> { pub fn get_variable_name(&self) -> Option<&str> {
match self.0 { match self.0 {
Expr::Variable(x) => Some((x.0).0.as_str()), Expr::Variable(x) => Some((x.0).0.as_str()),
@ -50,10 +52,12 @@ impl Expression<'_> {
} }
} }
/// Get the expression. /// Get the expression.
#[inline(always)]
pub(crate) fn expr(&self) -> &Expr { pub(crate) fn expr(&self) -> &Expr {
&self.0 &self.0
} }
/// Get the position of this expression. /// Get the position of this expression.
#[inline(always)]
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
self.0.position() self.0.position()
} }
@ -67,6 +71,7 @@ pub struct CustomSyntax {
} }
impl fmt::Debug for CustomSyntax { impl fmt::Debug for CustomSyntax {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.segments, f) fmt::Debug::fmt(&self.segments, f)
} }
@ -191,6 +196,7 @@ impl Engine {
/// ## 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.
#[inline(always)]
pub fn eval_expression_tree( pub fn eval_expression_tree(
&self, &self,
context: &mut EvalContext, context: &mut EvalContext,

View File

@ -55,6 +55,7 @@ impl Position {
/// # Panics /// # Panics
/// ///
/// Panics if `line` is zero. /// Panics if `line` is zero.
#[inline(always)]
pub fn new(line: u16, position: u16) -> Self { pub fn new(line: u16, position: u16) -> Self {
assert!(line != 0, "line cannot be zero"); assert!(line != 0, "line cannot be zero");
@ -65,6 +66,7 @@ impl 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)]
pub fn line(&self) -> Option<usize> { pub fn line(&self) -> Option<usize> {
if self.is_none() { if self.is_none() {
None None
@ -74,6 +76,7 @@ impl Position {
} }
/// 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)]
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 {
None None
@ -83,6 +86,7 @@ impl Position {
} }
/// Advance by one character position. /// Advance by one character position.
#[inline(always)]
pub(crate) fn advance(&mut self) { pub(crate) fn advance(&mut self) {
assert!(!self.is_none(), "cannot advance Position::none"); assert!(!self.is_none(), "cannot advance Position::none");
@ -97,6 +101,7 @@ impl Position {
/// # Panics /// # Panics
/// ///
/// Panics if already at beginning of a line - cannot rewind to a previous line. /// Panics if already at beginning of a line - cannot rewind to a previous line.
#[inline(always)]
pub(crate) fn rewind(&mut self) { pub(crate) fn rewind(&mut self) {
assert!(!self.is_none(), "cannot rewind Position::none"); assert!(!self.is_none(), "cannot rewind Position::none");
assert!(self.pos > 0, "cannot rewind at position 0"); assert!(self.pos > 0, "cannot rewind at position 0");
@ -104,6 +109,7 @@ impl Position {
} }
/// Advance to the next line. /// Advance to the next line.
#[inline(always)]
pub(crate) fn new_line(&mut self) { pub(crate) fn new_line(&mut self) {
assert!(!self.is_none(), "cannot advance Position::none"); assert!(!self.is_none(), "cannot advance Position::none");
@ -115,23 +121,27 @@ impl Position {
} }
/// Create a `Position` representing no position. /// Create a `Position` representing no position.
#[inline(always)]
pub fn none() -> Self { pub fn none() -> Self {
Self { line: 0, pos: 0 } Self { line: 0, pos: 0 }
} }
/// Is there no `Position`? /// Is there no `Position`?
#[inline(always)]
pub fn is_none(&self) -> bool { pub fn is_none(&self) -> bool {
self.line == 0 && self.pos == 0 self.line == 0 && self.pos == 0
} }
} }
impl Default for Position { impl Default for Position {
#[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::new(1, 0) Self::new(1, 0)
} }
} }
impl fmt::Display for Position { impl fmt::Display for Position {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_none() { if self.is_none() {
write!(f, "none") write!(f, "none")
@ -142,6 +152,7 @@ impl fmt::Display for Position {
} }
impl fmt::Debug for Position { impl fmt::Debug for Position {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.line, self.pos) write!(f, "{}:{}", self.line, self.pos)
} }
@ -521,6 +532,7 @@ impl Token {
} }
// Is this token EOF? // Is this token EOF?
#[inline(always)]
pub fn is_eof(&self) -> bool { pub fn is_eof(&self) -> bool {
use Token::*; use Token::*;
@ -677,6 +689,7 @@ impl Token {
} }
/// Is this token a reserved symbol? /// Is this token a reserved symbol?
#[inline(always)]
pub fn is_reserved(&self) -> bool { pub fn is_reserved(&self) -> bool {
match self { match self {
Self::Reserved(_) => true, Self::Reserved(_) => true,
@ -695,6 +708,7 @@ impl Token {
} }
/// Is this token a custom keyword? /// Is this token a custom keyword?
#[inline(always)]
pub fn is_custom(&self) -> bool { pub fn is_custom(&self) -> bool {
match self { match self {
Self::Custom(_) => true, Self::Custom(_) => true,
@ -704,6 +718,7 @@ impl Token {
} }
impl From<Token> for String { impl From<Token> for String {
#[inline(always)]
fn from(token: Token) -> Self { fn from(token: Token) -> Self {
token.syntax().into() token.syntax().into()
} }
@ -879,6 +894,7 @@ pub fn parse_string_literal(
} }
/// Consume the next character. /// Consume the next character.
#[inline(always)]
fn eat_next(stream: &mut impl InputStream, pos: &mut Position) -> Option<char> { fn eat_next(stream: &mut impl InputStream, pos: &mut Position) -> Option<char> {
pos.advance(); pos.advance();
stream.get_next() stream.get_next()
@ -937,6 +953,7 @@ fn scan_comment(
/// ## WARNING /// ## WARNING
/// ///
/// This type is volatile and may change. /// This type is volatile and may change.
#[inline]
pub fn get_next_token( pub fn get_next_token(
stream: &mut impl InputStream, stream: &mut impl InputStream,
state: &mut TokenizeState, state: &mut TokenizeState,
@ -953,6 +970,7 @@ pub fn get_next_token(
} }
/// Test if the given character is a hex character. /// Test if the given character is a hex character.
#[inline(always)]
fn is_hex_char(c: char) -> bool { fn is_hex_char(c: char) -> bool {
match c { match c {
'a'..='f' => true, 'a'..='f' => true,
@ -963,6 +981,7 @@ fn is_hex_char(c: char) -> bool {
} }
/// Test if the given character is an octal character. /// Test if the given character is an octal character.
#[inline(always)]
fn is_octal_char(c: char) -> bool { fn is_octal_char(c: char) -> bool {
match c { match c {
'0'..='7' => true, '0'..='7' => true,
@ -971,6 +990,7 @@ fn is_octal_char(c: char) -> bool {
} }
/// Test if the given character is a binary character. /// Test if the given character is a binary character.
#[inline(always)]
fn is_binary_char(c: char) -> bool { fn is_binary_char(c: char) -> bool {
match c { match c {
'0' | '1' => true, '0' | '1' => true,
@ -1533,6 +1553,7 @@ pub struct MultiInputsStream<'a> {
impl InputStream for MultiInputsStream<'_> { impl InputStream for MultiInputsStream<'_> {
/// Buffer a character. /// Buffer a character.
#[inline(always)]
fn unread(&mut self, ch: char) { fn unread(&mut self, ch: char) {
self.buf = Some(ch); self.buf = Some(ch);
} }
@ -1692,6 +1713,7 @@ impl<'a> Iterator for TokenIterator<'a, '_> {
} }
/// Tokenize an input text stream. /// Tokenize an input text stream.
#[inline]
pub fn lex<'a, 'e>( pub fn lex<'a, 'e>(
input: &'a [&'a str], input: &'a [&'a str],
map: Option<Box<dyn Fn(Token) -> Token>>, map: Option<Box<dyn Fn(Token) -> Token>>,

View File

@ -32,9 +32,11 @@ use smallvec::SmallVec;
pub struct StraightHasher(u64); pub struct StraightHasher(u64);
impl Hasher for StraightHasher { impl Hasher for StraightHasher {
#[inline(always)]
fn finish(&self) -> u64 { fn finish(&self) -> u64 {
self.0 self.0
} }
#[inline(always)]
fn write(&mut self, bytes: &[u8]) { fn write(&mut self, bytes: &[u8]) {
let mut key = [0_u8; 8]; let mut key = [0_u8; 8];
key.copy_from_slice(&bytes[..8]); // Panics if fewer than 8 bytes key.copy_from_slice(&bytes[..8]); // Panics if fewer than 8 bytes
@ -44,6 +46,7 @@ impl Hasher for StraightHasher {
impl StraightHasher { impl StraightHasher {
/// Create a `StraightHasher`. /// Create a `StraightHasher`.
#[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
Self(0) Self(0)
} }
@ -56,6 +59,7 @@ pub struct StraightHasherBuilder;
impl BuildHasher for StraightHasherBuilder { impl BuildHasher for StraightHasherBuilder {
type Hasher = StraightHasher; type Hasher = StraightHasher;
#[inline(always)]
fn build_hasher(&self) -> Self::Hasher { fn build_hasher(&self) -> Self::Hasher {
StraightHasher::new() StraightHasher::new()
} }
@ -132,47 +136,55 @@ pub struct ImmutableString(Shared<String>);
impl Deref for ImmutableString { impl Deref for ImmutableString {
type Target = String; type Target = String;
#[inline(always)]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
} }
impl AsRef<String> for ImmutableString { impl AsRef<String> for ImmutableString {
#[inline(always)]
fn as_ref(&self) -> &String { fn as_ref(&self) -> &String {
&self.0 &self.0
} }
} }
impl Borrow<String> for ImmutableString { impl Borrow<String> for ImmutableString {
#[inline(always)]
fn borrow(&self) -> &String { fn borrow(&self) -> &String {
&self.0 &self.0
} }
} }
impl Borrow<str> for ImmutableString { impl Borrow<str> for ImmutableString {
#[inline(always)]
fn borrow(&self) -> &str { fn borrow(&self) -> &str {
self.0.as_str() self.0.as_str()
} }
} }
impl From<&str> for ImmutableString { impl From<&str> for ImmutableString {
#[inline(always)]
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
Self(value.to_string().into()) Self(value.to_string().into())
} }
} }
impl From<String> for ImmutableString { impl From<String> for ImmutableString {
#[inline(always)]
fn from(value: String) -> Self { fn from(value: String) -> Self {
Self(value.into()) Self(value.into())
} }
} }
impl From<Box<String>> for ImmutableString { impl From<Box<String>> for ImmutableString {
#[inline(always)]
fn from(value: Box<String>) -> Self { fn from(value: Box<String>) -> Self {
Self(value.into()) Self(value.into())
} }
} }
impl From<ImmutableString> for String { impl From<ImmutableString> for String {
#[inline(always)]
fn from(value: ImmutableString) -> Self { fn from(value: ImmutableString) -> Self {
value.into_owned() value.into_owned()
} }
@ -181,42 +193,49 @@ impl From<ImmutableString> for String {
impl FromStr for ImmutableString { impl FromStr for ImmutableString {
type Err = (); type Err = ();
#[inline(always)]
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.to_string().into())) Ok(Self(s.to_string().into()))
} }
} }
impl FromIterator<char> for ImmutableString { impl FromIterator<char> for ImmutableString {
#[inline(always)]
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self { fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
Self(iter.into_iter().collect::<String>().into()) Self(iter.into_iter().collect::<String>().into())
} }
} }
impl<'a> FromIterator<&'a char> for ImmutableString { impl<'a> FromIterator<&'a char> for ImmutableString {
#[inline(always)]
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self { fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
Self(iter.into_iter().cloned().collect::<String>().into()) Self(iter.into_iter().cloned().collect::<String>().into())
} }
} }
impl<'a> FromIterator<&'a str> for ImmutableString { impl<'a> FromIterator<&'a str> for ImmutableString {
#[inline(always)]
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self { fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
Self(iter.into_iter().collect::<String>().into()) Self(iter.into_iter().collect::<String>().into())
} }
} }
impl<'a> FromIterator<String> for ImmutableString { impl<'a> FromIterator<String> for ImmutableString {
#[inline(always)]
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self { fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
Self(iter.into_iter().collect::<String>().into()) Self(iter.into_iter().collect::<String>().into())
} }
} }
impl fmt::Display for ImmutableString { impl fmt::Display for ImmutableString {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.0.as_str(), f) fmt::Display::fmt(self.0.as_str(), f)
} }
} }
impl fmt::Debug for ImmutableString { impl fmt::Debug for ImmutableString {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.0.as_str(), f) fmt::Debug::fmt(self.0.as_str(), f)
} }
@ -225,6 +244,7 @@ impl fmt::Debug for ImmutableString {
impl Add for ImmutableString { impl Add for ImmutableString {
type Output = Self; type Output = Self;
#[inline]
fn add(mut self, rhs: Self) -> Self::Output { fn add(mut self, rhs: Self) -> Self::Output {
if rhs.is_empty() { if rhs.is_empty() {
self self
@ -240,6 +260,7 @@ impl Add for ImmutableString {
impl Add for &ImmutableString { impl Add for &ImmutableString {
type Output = ImmutableString; type Output = ImmutableString;
#[inline]
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
if rhs.is_empty() { if rhs.is_empty() {
self.clone() self.clone()
@ -254,6 +275,7 @@ impl Add for &ImmutableString {
} }
impl AddAssign<&ImmutableString> for ImmutableString { impl AddAssign<&ImmutableString> for ImmutableString {
#[inline]
fn add_assign(&mut self, rhs: &ImmutableString) { fn add_assign(&mut self, rhs: &ImmutableString) {
if !rhs.is_empty() { if !rhs.is_empty() {
if self.is_empty() { if self.is_empty() {
@ -266,6 +288,7 @@ impl AddAssign<&ImmutableString> for ImmutableString {
} }
impl AddAssign<ImmutableString> for ImmutableString { impl AddAssign<ImmutableString> for ImmutableString {
#[inline]
fn add_assign(&mut self, rhs: ImmutableString) { fn add_assign(&mut self, rhs: ImmutableString) {
if !rhs.is_empty() { if !rhs.is_empty() {
if self.is_empty() { if self.is_empty() {
@ -280,6 +303,7 @@ impl AddAssign<ImmutableString> for ImmutableString {
impl Add<&str> for ImmutableString { impl Add<&str> for ImmutableString {
type Output = Self; type Output = Self;
#[inline]
fn add(mut self, rhs: &str) -> Self::Output { fn add(mut self, rhs: &str) -> Self::Output {
if rhs.is_empty() { if rhs.is_empty() {
self self
@ -293,6 +317,7 @@ impl Add<&str> for ImmutableString {
impl Add<&str> for &ImmutableString { impl Add<&str> for &ImmutableString {
type Output = ImmutableString; type Output = ImmutableString;
#[inline]
fn add(self, rhs: &str) -> Self::Output { fn add(self, rhs: &str) -> Self::Output {
if rhs.is_empty() { if rhs.is_empty() {
self.clone() self.clone()
@ -305,6 +330,7 @@ impl Add<&str> for &ImmutableString {
} }
impl AddAssign<&str> for ImmutableString { impl AddAssign<&str> for ImmutableString {
#[inline(always)]
fn add_assign(&mut self, rhs: &str) { fn add_assign(&mut self, rhs: &str) {
if !rhs.is_empty() { if !rhs.is_empty() {
self.make_mut().push_str(rhs); self.make_mut().push_str(rhs);
@ -315,6 +341,7 @@ impl AddAssign<&str> for ImmutableString {
impl Add<String> for ImmutableString { impl Add<String> for ImmutableString {
type Output = Self; type Output = Self;
#[inline]
fn add(mut self, rhs: String) -> Self::Output { fn add(mut self, rhs: String) -> Self::Output {
if rhs.is_empty() { if rhs.is_empty() {
self self
@ -330,6 +357,7 @@ impl Add<String> for ImmutableString {
impl Add<String> for &ImmutableString { impl Add<String> for &ImmutableString {
type Output = ImmutableString; type Output = ImmutableString;
#[inline]
fn add(self, rhs: String) -> Self::Output { fn add(self, rhs: String) -> Self::Output {
if rhs.is_empty() { if rhs.is_empty() {
self.clone() self.clone()
@ -346,6 +374,7 @@ impl Add<String> for &ImmutableString {
impl Add<char> for ImmutableString { impl Add<char> for ImmutableString {
type Output = Self; type Output = Self;
#[inline(always)]
fn add(mut self, rhs: char) -> Self::Output { fn add(mut self, rhs: char) -> Self::Output {
self.make_mut().push(rhs); self.make_mut().push(rhs);
self self
@ -355,6 +384,7 @@ impl Add<char> for ImmutableString {
impl Add<char> for &ImmutableString { impl Add<char> for &ImmutableString {
type Output = ImmutableString; type Output = ImmutableString;
#[inline(always)]
fn add(self, rhs: char) -> Self::Output { fn add(self, rhs: char) -> Self::Output {
let mut s = self.clone(); let mut s = self.clone();
s.make_mut().push(rhs); s.make_mut().push(rhs);
@ -363,42 +393,49 @@ impl Add<char> for &ImmutableString {
} }
impl AddAssign<char> for ImmutableString { impl AddAssign<char> for ImmutableString {
#[inline(always)]
fn add_assign(&mut self, rhs: char) { fn add_assign(&mut self, rhs: char) {
self.make_mut().push(rhs); self.make_mut().push(rhs);
} }
} }
impl<S: AsRef<str>> PartialEq<S> for ImmutableString { impl<S: AsRef<str>> PartialEq<S> for ImmutableString {
#[inline(always)]
fn eq(&self, other: &S) -> bool { fn eq(&self, other: &S) -> bool {
self.as_str().eq(other.as_ref()) self.as_str().eq(other.as_ref())
} }
} }
impl PartialEq<ImmutableString> for str { impl PartialEq<ImmutableString> for str {
#[inline(always)]
fn eq(&self, other: &ImmutableString) -> bool { fn eq(&self, other: &ImmutableString) -> bool {
self.eq(other.as_str()) self.eq(other.as_str())
} }
} }
impl PartialEq<ImmutableString> for String { impl PartialEq<ImmutableString> for String {
#[inline(always)]
fn eq(&self, other: &ImmutableString) -> bool { fn eq(&self, other: &ImmutableString) -> bool {
self.eq(other.as_str()) self.eq(other.as_str())
} }
} }
impl<S: AsRef<str>> PartialOrd<S> for ImmutableString { impl<S: AsRef<str>> PartialOrd<S> for ImmutableString {
#[inline(always)]
fn partial_cmp(&self, other: &S) -> Option<Ordering> { fn partial_cmp(&self, other: &S) -> Option<Ordering> {
self.as_str().partial_cmp(other.as_ref()) self.as_str().partial_cmp(other.as_ref())
} }
} }
impl PartialOrd<ImmutableString> for str { impl PartialOrd<ImmutableString> for str {
#[inline(always)]
fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> { fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> {
self.partial_cmp(other.as_str()) self.partial_cmp(other.as_str())
} }
} }
impl PartialOrd<ImmutableString> for String { impl PartialOrd<ImmutableString> for String {
#[inline(always)]
fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> { fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> {
self.as_str().partial_cmp(other.as_str()) self.as_str().partial_cmp(other.as_str())
} }
@ -407,12 +444,14 @@ 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)]
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)]
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)
} }