From 07efdddba3ae6fe94e69e520cd6f8c4ab880c13a Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 29 Mar 2021 13:40:33 +0800 Subject: [PATCH] Add smartstring default feature. --- Cargo.toml | 7 +++++-- src/ast.rs | 4 ++++ src/dynamic.rs | 7 ++++--- src/engine_api.rs | 14 ++++++++------ src/fn_builtin.rs | 8 ++++++++ src/lib.rs | 11 +++++++++-- src/packages/arithmetic.rs | 4 ++++ src/packages/math_basic.rs | 4 ++++ src/packages/string_basic.rs | 4 ++++ src/parser.rs | 2 +- src/utils.rs | 14 ++++++++++++-- 11 files changed, 63 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2f17533..09fbbb93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,13 +17,12 @@ categories = ["no-std", "embedded", "wasm", "parser-implementations"] [dependencies] smallvec = { version = "1.6", default-features = false, features = ["union"] } -smartstring = { version = "0.2.6" } ahash = { version = "0.7", default-features = false } num-traits = { version = "0.2", default_features = false } rhai_codegen = { version = "0.3.4", path = "codegen", features = ["metadata"] } [features] -default = [] +default = ["smartstring"] unchecked = [] # unchecked arithmetic sync = [] # restrict to only types that implement Send + Sync no_optimize = [] # no script optimizer @@ -76,6 +75,10 @@ default_features = false features = ["alloc"] optional = true +[dependencies.smartstring] +version = "0.2.6" +optional = true + [dependencies.unicode-xid] version = "0.2" default_features = false diff --git a/src/ast.rs b/src/ast.rs index 81a277c5..9af2bdf2 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1480,6 +1480,10 @@ impl fmt::Debug for FloatWrapper { impl fmt::Display for FloatWrapper { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(feature = "no_std")] + #[cfg(not(feature = "no_float"))] + use num_traits::Float; + let abs = self.0.abs(); if abs > 10000000000000.0 || abs < 0.0000000000001 { write!(f, "{:e}", self.0) diff --git a/src/dynamic.rs b/src/dynamic.rs index 477075af..4edf8957 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -8,7 +8,7 @@ use crate::stdlib::{ fmt, hash::{Hash, Hasher}, ops::{Deref, DerefMut}, - string::{String, ToString}, + string::String, }; use crate::{FnPtr, ImmutableString, INT}; @@ -1673,9 +1673,10 @@ impl From<&ImmutableString> for Dynamic { value.clone().into() } } -impl From<&smartstring::SmartString> for Dynamic { +#[cfg(feature = "smartstring")] +impl From<&crate::Identifier> for Dynamic { #[inline(always)] - fn from(value: &smartstring::SmartString) -> Self { + fn from(value: &crate::Identifier) -> Self { value.to_string().into() } } diff --git a/src/engine_api.rs b/src/engine_api.rs index cd37ac6c..3f1e1674 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -8,7 +8,6 @@ use crate::optimize::OptimizationLevel; use crate::stdlib::{ any::{type_name, TypeId}, boxed::Box, - format, string::String, }; use crate::{ @@ -61,7 +60,7 @@ impl Engine { #[cfg(feature = "metadata")] let mut param_type_names: crate::StaticVec<_> = F::param_names() .iter() - .map(|ty| format!("_: {}", self.map_type_name(ty))) + .map(|ty| crate::stdlib::format!("_: {}", self.map_type_name(ty))) .collect(); #[cfg(feature = "metadata")] @@ -121,7 +120,7 @@ impl Engine { #[cfg(feature = "metadata")] let param_type_names: crate::StaticVec<_> = F::param_names() .iter() - .map(|ty| format!("_: {}", self.map_type_name(ty))) + .map(|ty| crate::stdlib::format!("_: {}", self.map_type_name(ty))) .chain(crate::stdlib::iter::once( self.map_type_name(F::return_type_name()).into(), )) @@ -1167,7 +1166,7 @@ impl Engine { let mut f = crate::stdlib::fs::File::open(path.clone()).map_err(|err| { EvalAltResult::ErrorSystem( - format!("Cannot open script file '{}'", path.to_string_lossy()), + crate::stdlib::format!("Cannot open script file '{}'", path.to_string_lossy()), err.into(), ) })?; @@ -1176,7 +1175,7 @@ impl Engine { f.read_to_string(&mut contents).map_err(|err| { EvalAltResult::ErrorSystem( - format!("Cannot read script file '{}'", path.to_string_lossy()), + crate::stdlib::format!("Cannot read script file '{}'", path.to_string_lossy()), err.into(), ) })?; @@ -1991,7 +1990,10 @@ impl Engine { signatures.extend(self.global_namespace.gen_fn_signatures()); self.global_sub_modules.iter().for_each(|(name, m)| { - signatures.extend(m.gen_fn_signatures().map(|f| format!("{}::{}", name, f))) + signatures.extend( + m.gen_fn_signatures() + .map(|f| crate::stdlib::format!("{}::{}", name, f)), + ) }); if include_packages { diff --git a/src/fn_builtin.rs b/src/fn_builtin.rs index 8e00463c..3558d098 100644 --- a/src/fn_builtin.rs +++ b/src/fn_builtin.rs @@ -41,6 +41,10 @@ pub fn get_builtin_binary_op_fn( x: &Dynamic, y: &Dynamic, ) -> Option RhaiResult> { + #[cfg(feature = "no_std")] + #[cfg(not(feature = "no_float"))] + use num_traits::Float; + let type1 = x.type_id(); let type2 = y.type_id(); @@ -411,6 +415,10 @@ pub fn get_builtin_op_assignment_fn( x: &Dynamic, y: &Dynamic, ) -> Option RhaiResult> { + #[cfg(feature = "no_std")] + #[cfg(not(feature = "no_float"))] + use num_traits::Float; + let type1 = x.type_id(); let type2 = y.type_id(); diff --git a/src/lib.rs b/src/lib.rs index 04173c37..de3eff14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,6 +135,15 @@ pub use syntax::Expression; pub use token::Position; pub use utils::ImmutableString; +/// An identifier in Rhai. [`SmartString`](https://crates.io/crates/smartstring) is used because most +/// identifiers are ASCII and short, fewer than 23 characters, so they can be stored inline. +#[cfg(feature = "smartstring")] +pub type Identifier = smartstring::SmartString; + +/// An identifier in Rhai. +#[cfg(not(feature = "smartstring"))] +pub type Identifier = ImmutableString; + /// A trait to enable registering Rust functions. /// This trait is no longer needed and will be removed in the future. #[deprecated( @@ -292,8 +301,6 @@ type StaticVec = smallvec::SmallVec<[T; 4]>; #[cfg(feature = "internals")] pub type StaticVec = smallvec::SmallVec<[T; 4]>; -pub type Identifier = smartstring::SmartString; - // Compiler guards against mutually-exclusive feature flags #[cfg(feature = "no_float")] diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index 07d838b9..efefbd87 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -7,6 +7,10 @@ use crate::{def_package, EvalAltResult, Position, INT}; #[cfg(not(feature = "no_float"))] use crate::FLOAT; +#[cfg(feature = "no_std")] +#[cfg(not(feature = "no_float"))] +use num_traits::Float; + #[inline(always)] pub fn make_err(msg: impl Into) -> Box { EvalAltResult::ErrorArithmetic(msg.into(), Position::NONE).into() diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index e229e282..977fe2ed 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -12,6 +12,10 @@ use crate::result::EvalAltResult; #[cfg(not(feature = "no_float"))] use crate::stdlib::format; +#[cfg(feature = "no_std")] +#[cfg(not(feature = "no_float"))] +use num_traits::Float; + #[cfg(feature = "decimal")] use rust_decimal::Decimal; diff --git a/src/packages/string_basic.rs b/src/packages/string_basic.rs index 71341c44..08839b5b 100644 --- a/src/packages/string_basic.rs +++ b/src/packages/string_basic.rs @@ -55,6 +55,10 @@ mod print_debug_functions { #[cfg(not(feature = "no_float"))] pub mod float_functions { + #[cfg(feature = "no_std")] + #[cfg(not(feature = "no_float"))] + use num_traits::Float; + #[rhai_fn(name = "print", name = "to_string")] pub fn print_f64(number: f64) -> ImmutableString { let abs = number.abs(); diff --git a/src/parser.rs b/src/parser.rs index 0d6de2ba..1480a75f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -166,7 +166,7 @@ impl<'e> ParseState<'e> { /// Get an interned string, creating one if it is not yet interned. #[inline(always)] - pub fn get_interned_string(&mut self, text: impl AsRef) -> Identifier { + pub fn get_interned_string(&mut self, text: impl AsRef + Into) -> Identifier { self.interned_strings.get(text) } } diff --git a/src/utils.rs b/src/utils.rs index 380a1f8b..040229e0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -590,6 +590,7 @@ impl PartialOrd for String { } } +#[cfg(feature = "smartstring")] impl From for Identifier { #[inline(always)] fn from(value: ImmutableString) -> Self { @@ -597,6 +598,7 @@ impl From for Identifier { } } +#[cfg(feature = "smartstring")] impl From for ImmutableString { #[inline(always)] fn from(value: Identifier) -> Self { @@ -627,7 +629,15 @@ pub struct StringInterner(BTreeSet); impl StringInterner { /// Get an interned string, creating one if it is not yet interned. #[inline(always)] - pub fn get(&mut self, text: impl AsRef) -> Identifier { - text.as_ref().into() + pub fn get(&mut self, text: impl AsRef + Into) -> Identifier { + #[cfg(feature = "smartstring")] + return text.as_ref().into(); + + #[cfg(not(feature = "smartstring"))] + return self.0.get(text.as_ref()).cloned().unwrap_or_else(|| { + let s: Identifier = text.into(); + self.0.insert(s.clone()); + s + }); } }