Use AsRef<str> for more flexible API.

This commit is contained in:
Stephen Chung 2021-11-27 23:04:45 +08:00
parent 30bfdd841a
commit e918e61e95
12 changed files with 114 additions and 75 deletions

View File

@ -29,7 +29,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn compile(&self, script: &str) -> Result<AST, ParseError> { pub fn compile(&self, script: impl AsRef<str>) -> Result<AST, ParseError> {
self.compile_with_scope(&Scope::new(), script) self.compile_with_scope(&Scope::new(), script)
} }
/// Compile a string into an [`AST`] using own scope, which can be used later for evaluation. /// Compile a string into an [`AST`] using own scope, which can be used later for evaluation.
@ -70,7 +70,11 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result<AST, ParseError> { pub fn compile_with_scope(
&self,
scope: &Scope,
script: impl AsRef<str>,
) -> Result<AST, ParseError> {
self.compile_scripts_with_scope(scope, &[script]) self.compile_scripts_with_scope(scope, &[script])
} }
/// Compile a string into an [`AST`] using own scope, which can be used later for evaluation, /// Compile a string into an [`AST`] using own scope, which can be used later for evaluation,
@ -86,7 +90,7 @@ impl Engine {
pub fn compile_into_self_contained( pub fn compile_into_self_contained(
&self, &self,
scope: &Scope, scope: &Scope,
script: &str, script: impl AsRef<str>,
) -> Result<AST, Box<EvalAltResult>> { ) -> Result<AST, Box<EvalAltResult>> {
use crate::{ use crate::{
ast::{ASTNode, Expr, Stmt}, ast::{ASTNode, Expr, Stmt},
@ -198,7 +202,7 @@ impl Engine {
pub fn compile_scripts_with_scope( pub fn compile_scripts_with_scope(
&self, &self,
scope: &Scope, scope: &Scope,
scripts: &[&str], scripts: &[impl AsRef<str>],
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
self.compile_with_scope_and_optimization_level( self.compile_with_scope_and_optimization_level(
scope, scope,
@ -218,7 +222,7 @@ impl Engine {
pub(crate) fn compile_with_scope_and_optimization_level( pub(crate) fn compile_with_scope_and_optimization_level(
&self, &self,
scope: &Scope, scope: &Scope,
scripts: &[&str], scripts: &[impl AsRef<str>],
#[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel,
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
let (stream, tokenizer_control) = let (stream, tokenizer_control) =
@ -253,7 +257,7 @@ impl Engine {
/// # } /// # }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn compile_expression(&self, script: &str) -> Result<AST, ParseError> { pub fn compile_expression(&self, script: impl AsRef<str>) -> Result<AST, ParseError> {
self.compile_expression_with_scope(&Scope::new(), script) self.compile_expression_with_scope(&Scope::new(), script)
} }
/// Compile a string containing an expression into an [`AST`] using own scope, /// Compile a string containing an expression into an [`AST`] using own scope,
@ -292,7 +296,7 @@ impl Engine {
pub fn compile_expression_with_scope( pub fn compile_expression_with_scope(
&self, &self,
scope: &Scope, scope: &Scope,
script: &str, script: impl AsRef<str>,
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
let scripts = [script]; let scripts = [script];
let (stream, tokenizer_control) = let (stream, tokenizer_control) =

View File

@ -163,7 +163,7 @@ impl Engine {
scope: &mut Scope, scope: &mut Scope,
path: std::path::PathBuf, path: std::path::PathBuf,
) -> Result<T, Box<EvalAltResult>> { ) -> Result<T, Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.eval_with_scope::<T>(scope, &contents)) Self::read_file(path).and_then(|contents| self.eval_with_scope(scope, &contents))
} }
/// Evaluate a file, returning any error (if any). /// Evaluate a file, returning any error (if any).
/// ///

View File

@ -324,7 +324,7 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn register_get<T: Variant + Clone, V: Variant + Clone>( pub fn register_get<T: Variant + Clone, V: Variant + Clone>(
&mut self, &mut self,
name: &str, name: impl AsRef<str>,
get_fn: impl Fn(&mut T) -> V + SendSync + 'static, get_fn: impl Fn(&mut T) -> V + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
self.register_fn(&crate::engine::make_getter(name), get_fn) self.register_fn(&crate::engine::make_getter(name), get_fn)
@ -371,7 +371,7 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn register_get_result<T: Variant + Clone, V: Variant + Clone>( pub fn register_get_result<T: Variant + Clone, V: Variant + Clone>(
&mut self, &mut self,
name: &str, name: impl AsRef<str>,
get_fn: impl Fn(&mut T) -> Result<V, Box<EvalAltResult>> + SendSync + 'static, get_fn: impl Fn(&mut T) -> Result<V, Box<EvalAltResult>> + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
self.register_result_fn(&crate::engine::make_getter(name), get_fn) self.register_result_fn(&crate::engine::make_getter(name), get_fn)
@ -417,7 +417,7 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn register_set<T: Variant + Clone, V: Variant + Clone>( pub fn register_set<T: Variant + Clone, V: Variant + Clone>(
&mut self, &mut self,
name: &str, name: impl AsRef<str>,
set_fn: impl Fn(&mut T, V) + SendSync + 'static, set_fn: impl Fn(&mut T, V) + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
self.register_fn(&crate::engine::make_setter(name), set_fn) self.register_fn(&crate::engine::make_setter(name), set_fn)
@ -466,7 +466,7 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn register_set_result<T: Variant + Clone, V: Variant + Clone>( pub fn register_set_result<T: Variant + Clone, V: Variant + Clone>(
&mut self, &mut self,
name: &str, name: impl AsRef<str>,
set_fn: impl Fn(&mut T, V) -> Result<(), Box<EvalAltResult>> + SendSync + 'static, set_fn: impl Fn(&mut T, V) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
self.register_result_fn(&crate::engine::make_setter(name), set_fn) self.register_result_fn(&crate::engine::make_setter(name), set_fn)
@ -514,11 +514,11 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn register_get_set<T: Variant + Clone, V: Variant + Clone>( pub fn register_get_set<T: Variant + Clone, V: Variant + Clone>(
&mut self, &mut self,
name: &str, name: impl AsRef<str>,
get_fn: impl Fn(&mut T) -> V + SendSync + 'static, get_fn: impl Fn(&mut T) -> V + SendSync + 'static,
set_fn: impl Fn(&mut T, V) + SendSync + 'static, set_fn: impl Fn(&mut T, V) + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
self.register_get(name, get_fn).register_set(name, set_fn) self.register_get(&name, get_fn).register_set(&name, set_fn)
} }
/// Register an index getter for a custom type with the [`Engine`]. /// Register an index getter for a custom type with the [`Engine`].
/// ///

View File

@ -131,7 +131,9 @@ impl Imports {
/// Get the index of an imported [module][Module] by name. /// Get the index of an imported [module][Module] by name.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn find(&self, name: &str) -> Option<usize> { pub fn find(&self, name: impl AsRef<str>) -> Option<usize> {
let name = name.as_ref();
self.keys self.keys
.iter() .iter()
.enumerate() .enumerate()
@ -222,7 +224,7 @@ impl Imports {
/// Set a constant into the cache of globally-defined constants. /// Set a constant into the cache of globally-defined constants.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub(crate) fn set_global_constant(&mut self, name: &str, value: Dynamic) { pub(crate) fn set_global_constant(&mut self, name: impl Into<Identifier>, value: Dynamic) {
if self.global_constants.is_none() { if self.global_constants.is_none() {
let dict: crate::Locked<_> = BTreeMap::new().into(); let dict: crate::Locked<_> = BTreeMap::new().into();
self.global_constants = Some(dict.into()); self.global_constants = Some(dict.into());
@ -1063,24 +1065,24 @@ impl Default for Engine {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline] #[inline]
#[must_use] #[must_use]
pub fn make_getter(id: &str) -> String { pub fn make_getter(id: impl AsRef<str>) -> String {
format!("{}{}", FN_GET, id) format!("{}{}", FN_GET, id.as_ref())
} }
/// Make setter function /// Make setter function
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline] #[inline]
#[must_use] #[must_use]
pub fn make_setter(id: &str) -> String { pub fn make_setter(id: impl AsRef<str>) -> String {
format!("{}{}", FN_SET, id) format!("{}{}", FN_SET, id.as_ref())
} }
/// Is this function an anonymous function? /// Is this function an anonymous function?
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn is_anonymous_fn(fn_name: &str) -> bool { pub fn is_anonymous_fn(fn_name: impl AsRef<str>) -> bool {
fn_name.starts_with(FN_ANONYMOUS) fn_name.as_ref().starts_with(FN_ANONYMOUS)
} }
/// Print to `stdout` /// Print to `stdout`
@ -3105,7 +3107,7 @@ impl Engine {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
if entry_type == AccessMode::ReadOnly && lib.iter().any(|&m| !m.is_empty()) { if entry_type == AccessMode::ReadOnly && lib.iter().any(|&m| !m.is_empty()) {
mods.set_global_constant(name, value.clone()); mods.set_global_constant(name.clone(), value.clone());
} }
( (

View File

@ -107,7 +107,7 @@ impl Drop for ArgBackup<'_> {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[inline] #[inline]
pub fn ensure_no_data_race( pub fn ensure_no_data_race(
fn_name: &str, fn_name: impl AsRef<str>,
args: &FnCallArgs, args: &FnCallArgs,
is_method_call: bool, is_method_call: bool,
) -> Result<(), Box<EvalAltResult>> { ) -> Result<(), Box<EvalAltResult>> {
@ -118,7 +118,7 @@ pub fn ensure_no_data_race(
.find(|(_, a)| a.is_locked()) .find(|(_, a)| a.is_locked())
{ {
return Err(EvalAltResult::ErrorDataRace( return Err(EvalAltResult::ErrorDataRace(
format!("argument #{} of function '{}'", n + 1, fn_name), format!("argument #{} of function '{}'", n + 1, fn_name.as_ref()),
Position::NONE, Position::NONE,
) )
.into()); .into());
@ -134,7 +134,7 @@ impl Engine {
fn gen_call_signature( fn gen_call_signature(
&self, &self,
namespace: Option<&NamespaceRef>, namespace: Option<&NamespaceRef>,
fn_name: &str, fn_name: impl AsRef<str>,
args: &[&mut Dynamic], args: &[&mut Dynamic],
) -> String { ) -> String {
format!( format!(
@ -145,7 +145,7 @@ impl Engine {
} else { } else {
"" ""
}, },
fn_name, fn_name.as_ref(),
args.iter() args.iter()
.map(|a| if a.is::<ImmutableString>() { .map(|a| if a.is::<ImmutableString>() {
"&str | ImmutableString | String" "&str | ImmutableString | String"
@ -171,12 +171,14 @@ impl Engine {
mods: &Imports, mods: &Imports,
state: &'s mut EvalState, state: &'s mut EvalState,
lib: &[&Module], lib: &[&Module],
fn_name: &str, fn_name: impl AsRef<str>,
hash_script: u64, hash_script: u64,
args: Option<&mut FnCallArgs>, args: Option<&mut FnCallArgs>,
allow_dynamic: bool, allow_dynamic: bool,
is_op_assignment: bool, is_op_assignment: bool,
) -> Option<&'s FnResolutionCacheEntry> { ) -> Option<&'s FnResolutionCacheEntry> {
let fn_name = fn_name.as_ref();
let mut hash = args.as_ref().map_or(hash_script, |args| { let mut hash = args.as_ref().map_or(hash_script, |args| {
combine_hashes( combine_hashes(
hash_script, hash_script,
@ -307,7 +309,7 @@ impl Engine {
mods: &mut Imports, mods: &mut Imports,
state: &mut EvalState, state: &mut EvalState,
lib: &[&Module], lib: &[&Module],
name: &str, name: impl AsRef<str>,
hash: u64, hash: u64,
args: &mut FnCallArgs, args: &mut FnCallArgs,
is_method_call: bool, is_method_call: bool,
@ -317,6 +319,7 @@ impl Engine {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut mods.num_operations, pos)?; self.inc_operations(&mut mods.num_operations, pos)?;
let name = name.as_ref();
let parent_source = mods.source.clone(); let parent_source = mods.source.clone();
// Check if function access already in the cache // Check if function access already in the cache
@ -666,7 +669,7 @@ impl Engine {
mods: &mut Imports, mods: &mut Imports,
state: &mut EvalState, state: &mut EvalState,
lib: &[&Module], lib: &[&Module],
fn_name: &str, fn_name: impl AsRef<str>,
hashes: FnCallHashes, hashes: FnCallHashes,
args: &mut FnCallArgs, args: &mut FnCallArgs,
is_ref_mut: bool, is_ref_mut: bool,
@ -680,6 +683,8 @@ impl Engine {
Err(EvalAltResult::ErrorRuntime(msg.into(), pos).into()) Err(EvalAltResult::ErrorRuntime(msg.into(), pos).into())
} }
let fn_name = fn_name.as_ref();
// Check for data race. // Check for data race.
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
ensure_no_data_race(fn_name, args, is_ref_mut)?; ensure_no_data_race(fn_name, args, is_ref_mut)?;
@ -859,14 +864,14 @@ impl Engine {
scope: &mut Scope, scope: &mut Scope,
mods: &mut Imports, mods: &mut Imports,
lib: &[&Module], lib: &[&Module],
script: &str, script: impl AsRef<str>,
_pos: Position, _pos: Position,
level: usize, level: usize,
) -> RhaiResult { ) -> RhaiResult {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut mods.num_operations, _pos)?; self.inc_operations(&mut mods.num_operations, _pos)?;
let script = script.trim(); let script = script.as_ref().trim();
if script.is_empty() { if script.is_empty() {
return Ok(Dynamic::UNIT); return Ok(Dynamic::UNIT);
} }
@ -901,13 +906,14 @@ impl Engine {
mods: &mut Imports, mods: &mut Imports,
state: &mut EvalState, state: &mut EvalState,
lib: &[&Module], lib: &[&Module],
fn_name: &str, fn_name: impl AsRef<str>,
mut hash: FnCallHashes, mut hash: FnCallHashes,
target: &mut crate::engine::Target, target: &mut crate::engine::Target,
(call_args, call_arg_pos): &mut (StaticVec<Dynamic>, Position), (call_args, call_arg_pos): &mut (StaticVec<Dynamic>, Position),
pos: Position, pos: Position,
level: usize, level: usize,
) -> Result<(Dynamic, bool), Box<EvalAltResult>> { ) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
let fn_name = fn_name.as_ref();
let is_ref_mut = target.is_ref(); let is_ref_mut = target.is_ref();
let (result, updated) = match fn_name { let (result, updated) = match fn_name {
@ -1083,7 +1089,7 @@ impl Engine {
state: &mut EvalState, state: &mut EvalState,
lib: &[&Module], lib: &[&Module],
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
fn_name: &str, fn_name: impl AsRef<str>,
args_expr: &[Expr], args_expr: &[Expr],
constants: &[Dynamic], constants: &[Dynamic],
hashes: FnCallHashes, hashes: FnCallHashes,
@ -1091,6 +1097,7 @@ impl Engine {
capture_scope: bool, capture_scope: bool,
level: usize, level: usize,
) -> RhaiResult { ) -> RhaiResult {
let fn_name = fn_name.as_ref();
let mut a_expr = args_expr; let mut a_expr = args_expr;
let mut total_args = a_expr.len(); let mut total_args = a_expr.len();
let mut curry = StaticVec::new_const(); let mut curry = StaticVec::new_const();
@ -1354,13 +1361,14 @@ impl Engine {
lib: &[&Module], lib: &[&Module],
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
namespace: &NamespaceRef, namespace: &NamespaceRef,
fn_name: &str, fn_name: impl AsRef<str>,
args_expr: &[Expr], args_expr: &[Expr],
constants: &[Dynamic], constants: &[Dynamic],
hash: u64, hash: u64,
pos: Position, pos: Position,
level: usize, level: usize,
) -> RhaiResult { ) -> RhaiResult {
let fn_name = fn_name.as_ref();
let mut arg_values = StaticVec::with_capacity(args_expr.len()); let mut arg_values = StaticVec::with_capacity(args_expr.len());
let mut args = StaticVec::with_capacity(args_expr.len()); let mut args = StaticVec::with_capacity(args_expr.len());
let mut first_arg_value = None; let mut first_arg_value = None;

View File

@ -89,7 +89,7 @@ pub fn calc_qualified_var_hash<'a>(modules: impl Iterator<Item = &'a str>, var_n
#[must_use] #[must_use]
pub fn calc_qualified_fn_hash<'a>( pub fn calc_qualified_fn_hash<'a>(
modules: impl Iterator<Item = &'a str>, modules: impl Iterator<Item = &'a str>,
fn_name: &str, fn_name: impl AsRef<str>,
num: usize, num: usize,
) -> u64 { ) -> u64 {
let s = &mut get_hasher(); let s = &mut get_hasher();
@ -101,7 +101,7 @@ pub fn calc_qualified_fn_hash<'a>(
.skip(1) .skip(1)
.for_each(|m| m.hash(s)); .for_each(|m| m.hash(s));
len.hash(s); len.hash(s);
fn_name.hash(s); fn_name.as_ref().hash(s);
num.hash(s); num.hash(s);
s.finish() s.finish()
} }
@ -112,7 +112,7 @@ pub fn calc_qualified_fn_hash<'a>(
/// Parameter types are passed in via [`TypeId`] values from an iterator. /// Parameter types are passed in via [`TypeId`] values from an iterator.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn calc_fn_hash(fn_name: &str, num: usize) -> u64 { pub fn calc_fn_hash(fn_name: impl AsRef<str>, num: usize) -> u64 {
calc_qualified_fn_hash(empty(), fn_name, num) calc_qualified_fn_hash(empty(), fn_name, num)
} }

View File

@ -233,11 +233,13 @@ impl<'a> NativeCallContext<'a> {
/// by reference and is not consumed. /// by reference and is not consumed.
pub fn call_fn_raw( pub fn call_fn_raw(
&self, &self,
fn_name: &str, fn_name: impl AsRef<str>,
is_ref_mut: bool, is_ref_mut: bool,
is_method_call: bool, is_method_call: bool,
args: &mut [&mut Dynamic], args: &mut [&mut Dynamic],
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
let fn_name = fn_name.as_ref();
let hash = if is_method_call { let hash = if is_method_call {
FnCallHashes::from_all( FnCallHashes::from_all(
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]

View File

@ -109,10 +109,10 @@ impl FuncInfo {
#[inline] #[inline]
fn calc_native_fn_hash<'a>( fn calc_native_fn_hash<'a>(
modules: impl Iterator<Item = &'a str>, modules: impl Iterator<Item = &'a str>,
fn_name: &str, fn_name: impl AsRef<str>,
params: &[TypeId], params: &[TypeId],
) -> u64 { ) -> u64 {
let hash_script = calc_qualified_fn_hash(modules, fn_name, params.len()); let hash_script = calc_qualified_fn_hash(modules, fn_name.as_ref(), params.len());
let hash_params = calc_fn_params_hash(params.iter().cloned()); let hash_params = calc_fn_params_hash(params.iter().cloned());
combine_hashes(hash_script, hash_params) combine_hashes(hash_script, hash_params)
} }
@ -501,12 +501,14 @@ impl Module {
#[must_use] #[must_use]
pub fn get_script_fn( pub fn get_script_fn(
&self, &self,
name: &str, name: impl AsRef<str>,
num_params: usize, num_params: usize,
) -> Option<&Shared<crate::ast::ScriptFnDef>> { ) -> Option<&Shared<crate::ast::ScriptFnDef>> {
if self.functions.is_empty() { if self.functions.is_empty() {
None None
} else { } else {
let name = name.as_ref();
self.functions self.functions
.values() .values()
.find(|f| f.params == num_params && f.name == name) .find(|f| f.params == num_params && f.name == name)
@ -627,10 +629,10 @@ impl Module {
/// In other words, the number of entries should be one larger than the number of parameters. /// In other words, the number of entries should be one larger than the number of parameters.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
#[inline] #[inline]
pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self { pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[impl AsRef<str>]) -> &mut Self {
let param_names = arg_names let param_names = arg_names
.iter() .iter()
.map(|&name| self.identifiers.get(name)) .map(|name| self.identifiers.get(name.as_ref()))
.collect(); .collect();
if let Some(f) = self.functions.get_mut(&hash_fn) { if let Some(f) = self.functions.get_mut(&hash_fn) {
@ -685,10 +687,11 @@ impl Module {
name: impl AsRef<str> + Into<Identifier>, name: impl AsRef<str> + Into<Identifier>,
namespace: FnNamespace, namespace: FnNamespace,
access: FnAccess, access: FnAccess,
_arg_names: Option<&[&str]>, arg_names: Option<&[&str]>,
arg_types: &[TypeId], arg_types: &[TypeId],
func: CallableFunction, func: CallableFunction,
) -> u64 { ) -> u64 {
let _arg_names = arg_names;
let is_method = func.is_method(); let is_method = func.is_method();
let mut param_types: StaticVec<_> = arg_types let mut param_types: StaticVec<_> = arg_types
@ -702,7 +705,7 @@ impl Module {
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
let mut param_names: StaticVec<_> = _arg_names let mut param_names: StaticVec<_> = _arg_names
.iter() .iter()
.flat_map(|p| p.iter()) .flat_map(|&p| p.iter())
.map(|&arg| self.identifiers.get(arg)) .map(|&arg| self.identifiers.get(arg))
.collect(); .collect();
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
@ -884,7 +887,7 @@ impl Module {
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]
pub fn set_getter_fn<ARGS, A, T, F>(&mut self, name: &str, func: F) -> u64 pub fn set_getter_fn<ARGS, A, T, F>(&mut self, name: impl AsRef<str>, func: F) -> u64
where where
A: Variant + Clone, A: Variant + Clone,
T: Variant + Clone, T: Variant + Clone,
@ -925,7 +928,7 @@ impl Module {
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]
pub fn set_setter_fn<ARGS, A, B, F>(&mut self, name: &str, func: F) -> u64 pub fn set_setter_fn<ARGS, A, B, F>(&mut self, name: impl AsRef<str>, func: F) -> u64
where where
A: Variant + Clone, A: Variant + Clone,
B: Variant + Clone, B: Variant + Clone,

View File

@ -197,12 +197,12 @@ impl FileModuleResolver {
/// Is a particular path cached? /// Is a particular path cached?
#[inline] #[inline]
#[must_use] #[must_use]
pub fn is_cached(&self, path: &str, source_path: Option<&str>) -> bool { pub fn is_cached(&self, path: impl AsRef<str>, source_path: Option<&str>) -> bool {
if !self.cache_enabled { if !self.cache_enabled {
return false; return false;
} }
let file_path = self.get_file_path(path, source_path); let file_path = self.get_file_path(path.as_ref(), source_path);
shared_write_lock(&self.cache).contains_key(&file_path) shared_write_lock(&self.cache).contains_key(&file_path)
} }
@ -219,10 +219,10 @@ impl FileModuleResolver {
#[must_use] #[must_use]
pub fn clear_cache_for_path( pub fn clear_cache_for_path(
&mut self, &mut self,
path: &str, path: impl AsRef<str>,
source_path: Option<&str>, source_path: Option<impl AsRef<str>>,
) -> Option<Shared<Module>> { ) -> Option<Shared<Module>> {
let file_path = self.get_file_path(path, source_path); let file_path = self.get_file_path(path.as_ref(), source_path.as_ref().map(|v| v.as_ref()));
shared_write_lock(&self.cache) shared_write_lock(&self.cache)
.remove_entry(&file_path) .remove_entry(&file_path)

View File

@ -103,16 +103,23 @@ impl<'a> OptimizerState<'a> {
} }
/// Add a new constant to the list. /// Add a new constant to the list.
#[inline(always)] #[inline(always)]
pub fn push_var(&mut self, name: &str, access: AccessMode, value: Option<Dynamic>) { pub fn push_var(
&mut self,
name: impl Into<String>,
access: AccessMode,
value: Option<Dynamic>,
) {
self.variables.push((name.into(), access, value)) self.variables.push((name.into(), access, value))
} }
/// Look up a constant from the list. /// Look up a constant from the list.
#[inline] #[inline]
pub fn find_constant(&self, name: &str) -> Option<&Dynamic> { pub fn find_constant(&self, name: impl AsRef<str>) -> Option<&Dynamic> {
if !self.propagate_constants { if !self.propagate_constants {
return None; return None;
} }
let name = name.as_ref();
for (n, access, value) in self.variables.iter().rev() { for (n, access, value) in self.variables.iter().rev() {
if n == name { if n == name {
return match access { return match access {
@ -128,7 +135,7 @@ impl<'a> OptimizerState<'a> {
#[inline] #[inline]
pub fn call_fn_with_constant_arguments( pub fn call_fn_with_constant_arguments(
&self, &self,
fn_name: &str, fn_name: impl AsRef<str>,
arg_values: &mut [Dynamic], arg_values: &mut [Dynamic],
) -> Option<Dynamic> { ) -> Option<Dynamic> {
self.engine self.engine
@ -136,8 +143,8 @@ impl<'a> OptimizerState<'a> {
&mut Imports::new(), &mut Imports::new(),
&mut EvalState::new(), &mut EvalState::new(),
self.lib, self.lib,
fn_name, &fn_name,
calc_fn_hash(fn_name, arg_values.len()), calc_fn_hash(&fn_name, arg_values.len()),
&mut arg_values.iter_mut().collect::<StaticVec<_>>(), &mut arg_values.iter_mut().collect::<StaticVec<_>>(),
false, false,
false, false,
@ -210,7 +217,7 @@ fn optimize_stmt_block(
if value_expr.is_constant() { if value_expr.is_constant() {
state.push_var( state.push_var(
&x.name, x.name.as_str(),
AccessMode::ReadOnly, AccessMode::ReadOnly,
value_expr.get_literal_value(), value_expr.get_literal_value(),
); );
@ -218,7 +225,7 @@ fn optimize_stmt_block(
} else { } else {
// Add variables into the state // Add variables into the state
optimize_expr(value_expr, state, false); optimize_expr(value_expr, state, false);
state.push_var(&x.name, AccessMode::ReadWrite, None); state.push_var(x.name.as_str(), AccessMode::ReadWrite, None);
} }
} }
// Optimize the statement // Optimize the statement
@ -984,7 +991,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
_ if x.args.len() == 2 && !state.has_native_fn_override(x.hashes.native, arg_types.as_ref()) => { _ if x.args.len() == 2 && !state.has_native_fn_override(x.hashes.native, arg_types.as_ref()) => {
if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1]) if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1])
.and_then(|f| { .and_then(|f| {
let context = (state.engine, x.name.as_ref(), state.lib).into(); let context = (state.engine, x.name.as_str(), state.lib).into();
let (first, second) = arg_values.split_first_mut().expect("not empty"); let (first, second) = arg_values.split_first_mut().expect("not empty");
(f)(context, &mut [ first, &mut second[0] ]).ok() (f)(context, &mut [ first, &mut second[0] ]).ok()
}) { }) {
@ -1017,7 +1024,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
=> { => {
// First search for script-defined functions (can override built-in) // First search for script-defined functions (can override built-in)
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let has_script_fn = state.lib.iter().any(|&m| m.get_script_fn(x.name.as_ref(), x.args.len()).is_some()); let has_script_fn = state.lib.iter().any(|&m| m.get_script_fn(&x.name, x.args.len()).is_some());
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
let has_script_fn = false; let has_script_fn = false;
@ -1031,7 +1038,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
KEYWORD_TYPE_OF if arg_values.len() == 1 => Some(state.engine.map_type_name(arg_values[0].type_name()).into()), KEYWORD_TYPE_OF if arg_values.len() == 1 => Some(state.engine.map_type_name(arg_values[0].type_name()).into()),
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
KEYWORD_IS_SHARED if arg_values.len() == 1 => Some(Dynamic::FALSE), KEYWORD_IS_SHARED if arg_values.len() == 1 => Some(Dynamic::FALSE),
_ => state.call_fn_with_constant_arguments(x.name.as_ref(), arg_values) _ => state.call_fn_with_constant_arguments(&x.name, arg_values)
}; };
if let Some(result) = result { if let Some(result) = result {

View File

@ -146,7 +146,8 @@ impl<'e> ParseState<'e> {
/// ///
/// 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] #[inline]
pub fn access_var(&mut self, name: &str, pos: Position) -> Option<NonZeroUsize> { pub fn access_var(&mut self, name: impl AsRef<str>, pos: Position) -> Option<NonZeroUsize> {
let name = name.as_ref();
let mut barrier = false; let mut barrier = false;
let _pos = pos; let _pos = pos;
@ -195,7 +196,9 @@ impl<'e> ParseState<'e> {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline] #[inline]
#[must_use] #[must_use]
pub fn find_module(&self, name: &str) -> Option<NonZeroUsize> { pub fn find_module(&self, name: impl AsRef<str>) -> Option<NonZeroUsize> {
let name = name.as_ref();
self.modules self.modules
.iter() .iter()
.rev() .rev()
@ -330,7 +333,10 @@ impl Expr {
/// Make sure that the next expression is not a statement expression (i.e. wrapped in `{}`). /// Make sure that the next expression is not a statement expression (i.e. wrapped in `{}`).
#[inline] #[inline]
fn ensure_not_statement_expr(input: &mut TokenStream, type_name: &str) -> Result<(), ParseError> { fn ensure_not_statement_expr(
input: &mut TokenStream,
type_name: impl ToString,
) -> Result<(), ParseError> {
match input.peek().expect(NEVER_ENDS) { match input.peek().expect(NEVER_ENDS) {
(Token::LeftBrace, pos) => Err(PERR::ExprExpected(type_name.to_string()).into_err(*pos)), (Token::LeftBrace, pos) => Err(PERR::ExprExpected(type_name.to_string()).into_err(*pos)),
_ => Ok(()), _ => Ok(()),
@ -1996,7 +2002,7 @@ fn parse_custom_syntax(
state: &mut ParseState, state: &mut ParseState,
lib: &mut FunctionsLib, lib: &mut FunctionsLib,
settings: ParseSettings, settings: ParseSettings,
key: &str, key: impl Into<ImmutableString>,
syntax: &CustomSyntax, syntax: &CustomSyntax,
pos: Position, pos: Position,
) -> Result<Expr, ParseError> { ) -> Result<Expr, ParseError> {

View File

@ -695,9 +695,11 @@ impl Token {
/// Reverse lookup a token from a piece of syntax. /// Reverse lookup a token from a piece of syntax.
#[must_use] #[must_use]
pub fn lookup_from_syntax(syntax: &str) -> Option<Self> { pub fn lookup_from_syntax(syntax: impl AsRef<str>) -> Option<Self> {
use Token::*; use Token::*;
let syntax = syntax.as_ref();
Some(match syntax { Some(match syntax {
"{" => LeftBrace, "{" => LeftBrace,
"}" => RightBrace, "}" => RightBrace,
@ -1364,7 +1366,9 @@ fn is_numeric_digit(c: char) -> bool {
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
#[inline] #[inline]
#[must_use] #[must_use]
pub fn is_doc_comment(comment: &str) -> bool { pub fn is_doc_comment(comment: impl AsRef<str>) -> bool {
let comment = comment.as_ref();
(comment.starts_with("///") && !comment.starts_with("////")) (comment.starts_with("///") && !comment.starts_with("////"))
|| (comment.starts_with("/**") && !comment.starts_with("/***")) || (comment.starts_with("/**") && !comment.starts_with("/***"))
} }
@ -2004,8 +2008,8 @@ fn get_identifier(
/// Is this keyword allowed as a function? /// Is this keyword allowed as a function?
#[inline] #[inline]
#[must_use] #[must_use]
pub fn is_keyword_function(name: &str) -> bool { pub fn is_keyword_function(name: impl AsRef<str>) -> bool {
match name { match name.as_ref() {
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR => true, | KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR => true,
@ -2037,8 +2041,8 @@ pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool {
/// Is a text string a valid scripted function name? /// Is a text string a valid scripted function name?
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn is_valid_function_name(name: &str) -> bool { pub fn is_valid_function_name(name: impl AsRef<str>) -> bool {
is_valid_identifier(name.chars()) is_valid_identifier(name.as_ref().chars())
} }
/// Is a character valid to start an identifier? /// Is a character valid to start an identifier?
@ -2286,7 +2290,7 @@ impl Engine {
#[must_use] #[must_use]
pub(crate) fn lex_raw<'a>( pub(crate) fn lex_raw<'a>(
&'a self, &'a self,
input: impl IntoIterator<Item = &'a &'a str>, input: impl IntoIterator<Item = &'a (impl AsRef<str> + 'a)>,
token_mapper: Option<&'a OnParseTokenCallback>, token_mapper: Option<&'a OnParseTokenCallback>,
) -> (TokenIterator<'a>, TokenizerControl) { ) -> (TokenIterator<'a>, TokenizerControl) {
let buffer: TokenizerControl = Cell::new(TokenizerControlBlock::new()).into(); let buffer: TokenizerControl = Cell::new(TokenizerControlBlock::new()).into();
@ -2309,7 +2313,10 @@ impl Engine {
tokenizer_control: buffer, tokenizer_control: buffer,
stream: MultiInputsStream { stream: MultiInputsStream {
buf: None, buf: None,
streams: input.into_iter().map(|s| s.chars().peekable()).collect(), streams: input
.into_iter()
.map(|s| s.as_ref().chars().peekable())
.collect(),
index: 0, index: 0,
}, },
token_mapper, token_mapper,