From e918e61e95b6c43e2bd59b8b76ee275388a67005 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 27 Nov 2021 23:04:45 +0800 Subject: [PATCH] Use AsRef for more flexible API. --- src/api/compile.rs | 18 +++++++++++------- src/api/files.rs | 2 +- src/api/register.rs | 12 ++++++------ src/engine.rs | 20 +++++++++++--------- src/func/call.rs | 32 ++++++++++++++++++++------------ src/func/hashing.rs | 6 +++--- src/func/native.rs | 4 +++- src/module/mod.rs | 21 ++++++++++++--------- src/module/resolvers/file.rs | 10 +++++----- src/optimizer.rs | 27 +++++++++++++++++---------- src/parser.rs | 14 ++++++++++---- src/tokenizer.rs | 23 +++++++++++++++-------- 12 files changed, 114 insertions(+), 75 deletions(-) diff --git a/src/api/compile.rs b/src/api/compile.rs index 880a0dfc..8fbba23a 100644 --- a/src/api/compile.rs +++ b/src/api/compile.rs @@ -29,7 +29,7 @@ impl Engine { /// # } /// ``` #[inline(always)] - pub fn compile(&self, script: &str) -> Result { + pub fn compile(&self, script: impl AsRef) -> Result { self.compile_with_scope(&Scope::new(), script) } /// Compile a string into an [`AST`] using own scope, which can be used later for evaluation. @@ -70,7 +70,11 @@ impl Engine { /// # } /// ``` #[inline(always)] - pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result { + pub fn compile_with_scope( + &self, + scope: &Scope, + script: impl AsRef, + ) -> Result { self.compile_scripts_with_scope(scope, &[script]) } /// 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( &self, scope: &Scope, - script: &str, + script: impl AsRef, ) -> Result> { use crate::{ ast::{ASTNode, Expr, Stmt}, @@ -198,7 +202,7 @@ impl Engine { pub fn compile_scripts_with_scope( &self, scope: &Scope, - scripts: &[&str], + scripts: &[impl AsRef], ) -> Result { self.compile_with_scope_and_optimization_level( scope, @@ -218,7 +222,7 @@ impl Engine { pub(crate) fn compile_with_scope_and_optimization_level( &self, scope: &Scope, - scripts: &[&str], + scripts: &[impl AsRef], #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, ) -> Result { let (stream, tokenizer_control) = @@ -253,7 +257,7 @@ impl Engine { /// # } /// ``` #[inline(always)] - pub fn compile_expression(&self, script: &str) -> Result { + pub fn compile_expression(&self, script: impl AsRef) -> Result { self.compile_expression_with_scope(&Scope::new(), script) } /// Compile a string containing an expression into an [`AST`] using own scope, @@ -292,7 +296,7 @@ impl Engine { pub fn compile_expression_with_scope( &self, scope: &Scope, - script: &str, + script: impl AsRef, ) -> Result { let scripts = [script]; let (stream, tokenizer_control) = diff --git a/src/api/files.rs b/src/api/files.rs index 5da34f0b..785bffbc 100644 --- a/src/api/files.rs +++ b/src/api/files.rs @@ -163,7 +163,7 @@ impl Engine { scope: &mut Scope, path: std::path::PathBuf, ) -> Result> { - Self::read_file(path).and_then(|contents| self.eval_with_scope::(scope, &contents)) + Self::read_file(path).and_then(|contents| self.eval_with_scope(scope, &contents)) } /// Evaluate a file, returning any error (if any). /// diff --git a/src/api/register.rs b/src/api/register.rs index 8d1f4540..679d9e0c 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -324,7 +324,7 @@ impl Engine { #[inline(always)] pub fn register_get( &mut self, - name: &str, + name: impl AsRef, get_fn: impl Fn(&mut T) -> V + SendSync + 'static, ) -> &mut Self { self.register_fn(&crate::engine::make_getter(name), get_fn) @@ -371,7 +371,7 @@ impl Engine { #[inline(always)] pub fn register_get_result( &mut self, - name: &str, + name: impl AsRef, get_fn: impl Fn(&mut T) -> Result> + SendSync + 'static, ) -> &mut Self { self.register_result_fn(&crate::engine::make_getter(name), get_fn) @@ -417,7 +417,7 @@ impl Engine { #[inline(always)] pub fn register_set( &mut self, - name: &str, + name: impl AsRef, set_fn: impl Fn(&mut T, V) + SendSync + 'static, ) -> &mut Self { self.register_fn(&crate::engine::make_setter(name), set_fn) @@ -466,7 +466,7 @@ impl Engine { #[inline(always)] pub fn register_set_result( &mut self, - name: &str, + name: impl AsRef, set_fn: impl Fn(&mut T, V) -> Result<(), Box> + SendSync + 'static, ) -> &mut Self { self.register_result_fn(&crate::engine::make_setter(name), set_fn) @@ -514,11 +514,11 @@ impl Engine { #[inline(always)] pub fn register_get_set( &mut self, - name: &str, + name: impl AsRef, get_fn: impl Fn(&mut T) -> V + SendSync + 'static, set_fn: impl Fn(&mut T, V) + SendSync + 'static, ) -> &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`]. /// diff --git a/src/engine.rs b/src/engine.rs index 70253581..74e252f2 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -131,7 +131,9 @@ impl Imports { /// Get the index of an imported [module][Module] by name. #[inline] #[must_use] - pub fn find(&self, name: &str) -> Option { + pub fn find(&self, name: impl AsRef) -> Option { + let name = name.as_ref(); + self.keys .iter() .enumerate() @@ -222,7 +224,7 @@ impl Imports { /// Set a constant into the cache of globally-defined constants. #[cfg(not(feature = "no_module"))] #[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, value: Dynamic) { if self.global_constants.is_none() { let dict: crate::Locked<_> = BTreeMap::new().into(); self.global_constants = Some(dict.into()); @@ -1063,24 +1065,24 @@ impl Default for Engine { #[cfg(not(feature = "no_object"))] #[inline] #[must_use] -pub fn make_getter(id: &str) -> String { - format!("{}{}", FN_GET, id) +pub fn make_getter(id: impl AsRef) -> String { + format!("{}{}", FN_GET, id.as_ref()) } /// Make setter function #[cfg(not(feature = "no_object"))] #[inline] #[must_use] -pub fn make_setter(id: &str) -> String { - format!("{}{}", FN_SET, id) +pub fn make_setter(id: impl AsRef) -> String { + format!("{}{}", FN_SET, id.as_ref()) } /// Is this function an anonymous function? #[cfg(not(feature = "no_function"))] #[inline(always)] #[must_use] -pub fn is_anonymous_fn(fn_name: &str) -> bool { - fn_name.starts_with(FN_ANONYMOUS) +pub fn is_anonymous_fn(fn_name: impl AsRef) -> bool { + fn_name.as_ref().starts_with(FN_ANONYMOUS) } /// Print to `stdout` @@ -3105,7 +3107,7 @@ impl Engine { #[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_module"))] 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()); } ( diff --git a/src/func/call.rs b/src/func/call.rs index 8a54a187..3866497d 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -107,7 +107,7 @@ impl Drop for ArgBackup<'_> { #[cfg(not(feature = "no_closure"))] #[inline] pub fn ensure_no_data_race( - fn_name: &str, + fn_name: impl AsRef, args: &FnCallArgs, is_method_call: bool, ) -> Result<(), Box> { @@ -118,7 +118,7 @@ pub fn ensure_no_data_race( .find(|(_, a)| a.is_locked()) { return Err(EvalAltResult::ErrorDataRace( - format!("argument #{} of function '{}'", n + 1, fn_name), + format!("argument #{} of function '{}'", n + 1, fn_name.as_ref()), Position::NONE, ) .into()); @@ -134,7 +134,7 @@ impl Engine { fn gen_call_signature( &self, namespace: Option<&NamespaceRef>, - fn_name: &str, + fn_name: impl AsRef, args: &[&mut Dynamic], ) -> String { format!( @@ -145,7 +145,7 @@ impl Engine { } else { "" }, - fn_name, + fn_name.as_ref(), args.iter() .map(|a| if a.is::() { "&str | ImmutableString | String" @@ -171,12 +171,14 @@ impl Engine { mods: &Imports, state: &'s mut EvalState, lib: &[&Module], - fn_name: &str, + fn_name: impl AsRef, hash_script: u64, args: Option<&mut FnCallArgs>, allow_dynamic: bool, is_op_assignment: bool, ) -> Option<&'s FnResolutionCacheEntry> { + let fn_name = fn_name.as_ref(); + let mut hash = args.as_ref().map_or(hash_script, |args| { combine_hashes( hash_script, @@ -307,7 +309,7 @@ impl Engine { mods: &mut Imports, state: &mut EvalState, lib: &[&Module], - name: &str, + name: impl AsRef, hash: u64, args: &mut FnCallArgs, is_method_call: bool, @@ -317,6 +319,7 @@ impl Engine { #[cfg(not(feature = "unchecked"))] self.inc_operations(&mut mods.num_operations, pos)?; + let name = name.as_ref(); let parent_source = mods.source.clone(); // Check if function access already in the cache @@ -666,7 +669,7 @@ impl Engine { mods: &mut Imports, state: &mut EvalState, lib: &[&Module], - fn_name: &str, + fn_name: impl AsRef, hashes: FnCallHashes, args: &mut FnCallArgs, is_ref_mut: bool, @@ -680,6 +683,8 @@ impl Engine { Err(EvalAltResult::ErrorRuntime(msg.into(), pos).into()) } + let fn_name = fn_name.as_ref(); + // Check for data race. #[cfg(not(feature = "no_closure"))] ensure_no_data_race(fn_name, args, is_ref_mut)?; @@ -859,14 +864,14 @@ impl Engine { scope: &mut Scope, mods: &mut Imports, lib: &[&Module], - script: &str, + script: impl AsRef, _pos: Position, level: usize, ) -> RhaiResult { #[cfg(not(feature = "unchecked"))] self.inc_operations(&mut mods.num_operations, _pos)?; - let script = script.trim(); + let script = script.as_ref().trim(); if script.is_empty() { return Ok(Dynamic::UNIT); } @@ -901,13 +906,14 @@ impl Engine { mods: &mut Imports, state: &mut EvalState, lib: &[&Module], - fn_name: &str, + fn_name: impl AsRef, mut hash: FnCallHashes, target: &mut crate::engine::Target, (call_args, call_arg_pos): &mut (StaticVec, Position), pos: Position, level: usize, ) -> Result<(Dynamic, bool), Box> { + let fn_name = fn_name.as_ref(); let is_ref_mut = target.is_ref(); let (result, updated) = match fn_name { @@ -1083,7 +1089,7 @@ impl Engine { state: &mut EvalState, lib: &[&Module], this_ptr: &mut Option<&mut Dynamic>, - fn_name: &str, + fn_name: impl AsRef, args_expr: &[Expr], constants: &[Dynamic], hashes: FnCallHashes, @@ -1091,6 +1097,7 @@ impl Engine { capture_scope: bool, level: usize, ) -> RhaiResult { + let fn_name = fn_name.as_ref(); let mut a_expr = args_expr; let mut total_args = a_expr.len(); let mut curry = StaticVec::new_const(); @@ -1354,13 +1361,14 @@ impl Engine { lib: &[&Module], this_ptr: &mut Option<&mut Dynamic>, namespace: &NamespaceRef, - fn_name: &str, + fn_name: impl AsRef, args_expr: &[Expr], constants: &[Dynamic], hash: u64, pos: Position, level: usize, ) -> RhaiResult { + let fn_name = fn_name.as_ref(); let mut arg_values = StaticVec::with_capacity(args_expr.len()); let mut args = StaticVec::with_capacity(args_expr.len()); let mut first_arg_value = None; diff --git a/src/func/hashing.rs b/src/func/hashing.rs index a681fa04..86931c82 100644 --- a/src/func/hashing.rs +++ b/src/func/hashing.rs @@ -89,7 +89,7 @@ pub fn calc_qualified_var_hash<'a>(modules: impl Iterator, var_n #[must_use] pub fn calc_qualified_fn_hash<'a>( modules: impl Iterator, - fn_name: &str, + fn_name: impl AsRef, num: usize, ) -> u64 { let s = &mut get_hasher(); @@ -101,7 +101,7 @@ pub fn calc_qualified_fn_hash<'a>( .skip(1) .for_each(|m| m.hash(s)); len.hash(s); - fn_name.hash(s); + fn_name.as_ref().hash(s); num.hash(s); s.finish() } @@ -112,7 +112,7 @@ pub fn calc_qualified_fn_hash<'a>( /// Parameter types are passed in via [`TypeId`] values from an iterator. #[inline(always)] #[must_use] -pub fn calc_fn_hash(fn_name: &str, num: usize) -> u64 { +pub fn calc_fn_hash(fn_name: impl AsRef, num: usize) -> u64 { calc_qualified_fn_hash(empty(), fn_name, num) } diff --git a/src/func/native.rs b/src/func/native.rs index e50e5da1..5c8a383a 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -233,11 +233,13 @@ impl<'a> NativeCallContext<'a> { /// by reference and is not consumed. pub fn call_fn_raw( &self, - fn_name: &str, + fn_name: impl AsRef, is_ref_mut: bool, is_method_call: bool, args: &mut [&mut Dynamic], ) -> Result> { + let fn_name = fn_name.as_ref(); + let hash = if is_method_call { FnCallHashes::from_all( #[cfg(not(feature = "no_function"))] diff --git a/src/module/mod.rs b/src/module/mod.rs index d5bd568f..0511f042 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -109,10 +109,10 @@ impl FuncInfo { #[inline] fn calc_native_fn_hash<'a>( modules: impl Iterator, - fn_name: &str, + fn_name: impl AsRef, params: &[TypeId], ) -> 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()); combine_hashes(hash_script, hash_params) } @@ -501,12 +501,14 @@ impl Module { #[must_use] pub fn get_script_fn( &self, - name: &str, + name: impl AsRef, num_params: usize, ) -> Option<&Shared> { if self.functions.is_empty() { None } else { + let name = name.as_ref(); + self.functions .values() .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. #[cfg(feature = "metadata")] #[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]) -> &mut Self { let param_names = arg_names .iter() - .map(|&name| self.identifiers.get(name)) + .map(|name| self.identifiers.get(name.as_ref())) .collect(); if let Some(f) = self.functions.get_mut(&hash_fn) { @@ -685,10 +687,11 @@ impl Module { name: impl AsRef + Into, namespace: FnNamespace, access: FnAccess, - _arg_names: Option<&[&str]>, + arg_names: Option<&[&str]>, arg_types: &[TypeId], func: CallableFunction, ) -> u64 { + let _arg_names = arg_names; let is_method = func.is_method(); let mut param_types: StaticVec<_> = arg_types @@ -702,7 +705,7 @@ impl Module { #[cfg(feature = "metadata")] let mut param_names: StaticVec<_> = _arg_names .iter() - .flat_map(|p| p.iter()) + .flat_map(|&p| p.iter()) .map(|&arg| self.identifiers.get(arg)) .collect(); #[cfg(feature = "metadata")] @@ -884,7 +887,7 @@ impl Module { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn set_getter_fn(&mut self, name: &str, func: F) -> u64 + pub fn set_getter_fn(&mut self, name: impl AsRef, func: F) -> u64 where A: Variant + Clone, T: Variant + Clone, @@ -925,7 +928,7 @@ impl Module { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn set_setter_fn(&mut self, name: &str, func: F) -> u64 + pub fn set_setter_fn(&mut self, name: impl AsRef, func: F) -> u64 where A: Variant + Clone, B: Variant + Clone, diff --git a/src/module/resolvers/file.rs b/src/module/resolvers/file.rs index 5af89136..f5f1717a 100644 --- a/src/module/resolvers/file.rs +++ b/src/module/resolvers/file.rs @@ -197,12 +197,12 @@ impl FileModuleResolver { /// Is a particular path cached? #[inline] #[must_use] - pub fn is_cached(&self, path: &str, source_path: Option<&str>) -> bool { + pub fn is_cached(&self, path: impl AsRef, source_path: Option<&str>) -> bool { if !self.cache_enabled { 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) } @@ -219,10 +219,10 @@ impl FileModuleResolver { #[must_use] pub fn clear_cache_for_path( &mut self, - path: &str, - source_path: Option<&str>, + path: impl AsRef, + source_path: Option>, ) -> Option> { - 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) .remove_entry(&file_path) diff --git a/src/optimizer.rs b/src/optimizer.rs index 620923b7..70094205 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -103,16 +103,23 @@ impl<'a> OptimizerState<'a> { } /// Add a new constant to the list. #[inline(always)] - pub fn push_var(&mut self, name: &str, access: AccessMode, value: Option) { + pub fn push_var( + &mut self, + name: impl Into, + access: AccessMode, + value: Option, + ) { self.variables.push((name.into(), access, value)) } /// Look up a constant from the list. #[inline] - pub fn find_constant(&self, name: &str) -> Option<&Dynamic> { + pub fn find_constant(&self, name: impl AsRef) -> Option<&Dynamic> { if !self.propagate_constants { return None; } + let name = name.as_ref(); + for (n, access, value) in self.variables.iter().rev() { if n == name { return match access { @@ -128,7 +135,7 @@ impl<'a> OptimizerState<'a> { #[inline] pub fn call_fn_with_constant_arguments( &self, - fn_name: &str, + fn_name: impl AsRef, arg_values: &mut [Dynamic], ) -> Option { self.engine @@ -136,8 +143,8 @@ impl<'a> OptimizerState<'a> { &mut Imports::new(), &mut EvalState::new(), self.lib, - fn_name, - calc_fn_hash(fn_name, arg_values.len()), + &fn_name, + calc_fn_hash(&fn_name, arg_values.len()), &mut arg_values.iter_mut().collect::>(), false, false, @@ -210,7 +217,7 @@ fn optimize_stmt_block( if value_expr.is_constant() { state.push_var( - &x.name, + x.name.as_str(), AccessMode::ReadOnly, value_expr.get_literal_value(), ); @@ -218,7 +225,7 @@ fn optimize_stmt_block( } else { // Add variables into the state 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 @@ -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 let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1]) .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"); (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) #[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")] 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()), #[cfg(not(feature = "no_closure"))] 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 { diff --git a/src/parser.rs b/src/parser.rs index 2d5c6c19..ffdb63c5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -146,7 +146,8 @@ impl<'e> ParseState<'e> { /// /// Return `None` when the variable name is not found in the `stack`. #[inline] - pub fn access_var(&mut self, name: &str, pos: Position) -> Option { + pub fn access_var(&mut self, name: impl AsRef, pos: Position) -> Option { + let name = name.as_ref(); let mut barrier = false; let _pos = pos; @@ -195,7 +196,9 @@ impl<'e> ParseState<'e> { #[cfg(not(feature = "no_module"))] #[inline] #[must_use] - pub fn find_module(&self, name: &str) -> Option { + pub fn find_module(&self, name: impl AsRef) -> Option { + let name = name.as_ref(); + self.modules .iter() .rev() @@ -330,7 +333,10 @@ impl Expr { /// Make sure that the next expression is not a statement expression (i.e. wrapped in `{}`). #[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) { (Token::LeftBrace, pos) => Err(PERR::ExprExpected(type_name.to_string()).into_err(*pos)), _ => Ok(()), @@ -1996,7 +2002,7 @@ fn parse_custom_syntax( state: &mut ParseState, lib: &mut FunctionsLib, settings: ParseSettings, - key: &str, + key: impl Into, syntax: &CustomSyntax, pos: Position, ) -> Result { diff --git a/src/tokenizer.rs b/src/tokenizer.rs index abc6f34f..3fa2dc5f 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -695,9 +695,11 @@ impl Token { /// Reverse lookup a token from a piece of syntax. #[must_use] - pub fn lookup_from_syntax(syntax: &str) -> Option { + pub fn lookup_from_syntax(syntax: impl AsRef) -> Option { use Token::*; + let syntax = syntax.as_ref(); + Some(match syntax { "{" => LeftBrace, "}" => RightBrace, @@ -1364,7 +1366,9 @@ fn is_numeric_digit(c: char) -> bool { #[cfg(feature = "metadata")] #[inline] #[must_use] -pub fn is_doc_comment(comment: &str) -> bool { +pub fn is_doc_comment(comment: impl AsRef) -> bool { + let comment = comment.as_ref(); + (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? #[inline] #[must_use] -pub fn is_keyword_function(name: &str) -> bool { - match name { +pub fn is_keyword_function(name: impl AsRef) -> bool { + match name.as_ref() { 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, @@ -2037,8 +2041,8 @@ pub fn is_valid_identifier(name: impl Iterator) -> bool { /// Is a text string a valid scripted function name? #[inline(always)] #[must_use] -pub fn is_valid_function_name(name: &str) -> bool { - is_valid_identifier(name.chars()) +pub fn is_valid_function_name(name: impl AsRef) -> bool { + is_valid_identifier(name.as_ref().chars()) } /// Is a character valid to start an identifier? @@ -2286,7 +2290,7 @@ impl Engine { #[must_use] pub(crate) fn lex_raw<'a>( &'a self, - input: impl IntoIterator, + input: impl IntoIterator + 'a)>, token_mapper: Option<&'a OnParseTokenCallback>, ) -> (TokenIterator<'a>, TokenizerControl) { let buffer: TokenizerControl = Cell::new(TokenizerControlBlock::new()).into(); @@ -2309,7 +2313,10 @@ impl Engine { tokenizer_control: buffer, stream: MultiInputsStream { 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, }, token_mapper,