Use Option instead of once/empty.

This commit is contained in:
Stephen Chung 2022-06-11 16:01:15 +08:00
parent 8999872d62
commit b9cbeb65d6
7 changed files with 34 additions and 30 deletions

View File

@ -123,9 +123,7 @@ impl Engine {
let param_type_names: crate::StaticVec<_> = F::param_names() let param_type_names: crate::StaticVec<_> = F::param_names()
.iter() .iter()
.map(|ty| format!("_: {}", self.format_type_name(ty))) .map(|ty| format!("_: {}", self.format_type_name(ty)))
.chain(std::iter::once( .chain(Some(self.format_type_name(F::return_type_name()).into()))
self.format_type_name(F::return_type_name()).into(),
))
.collect(); .collect();
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]

View File

@ -28,9 +28,9 @@ pub trait FuncArgs {
/// ///
/// impl FuncArgs for Options { /// impl FuncArgs for Options {
/// fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) { /// fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) {
/// args.extend(std::iter::once(self.foo.into())); /// args.extend(Some(self.foo.into()));
/// args.extend(std::iter::once(self.bar.into())); /// args.extend(Some(self.bar.into()));
/// args.extend(std::iter::once(self.baz.into())); /// args.extend(Some(self.baz.into()));
/// } /// }
/// } /// }
/// ///

View File

@ -5,7 +5,6 @@ use std::prelude::v1::*;
use std::{ use std::{
any::TypeId, any::TypeId,
hash::{BuildHasher, Hash, Hasher}, hash::{BuildHasher, Hash, Hasher},
iter::empty,
}; };
/// Dummy hash value to map zeros to. This value can be anything. /// Dummy hash value to map zeros to. This value can be anything.
@ -87,12 +86,16 @@ pub fn get_hasher() -> ahash::AHasher {
/// The first module name is skipped. Hashing starts from the _second_ module in the chain. /// The first module name is skipped. Hashing starts from the _second_ module in the chain.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn calc_qualified_var_hash<'a>(modules: impl Iterator<Item = &'a str>, var_name: &str) -> u64 { pub fn calc_qualified_var_hash<'a>(
modules: impl IntoIterator<Item = &'a str>,
var_name: &str,
) -> u64 {
let s = &mut get_hasher(); let s = &mut get_hasher();
// We always skip the first module // We always skip the first module
let mut len = 0; let mut len = 0;
modules modules
.into_iter()
.inspect(|_| len += 1) .inspect(|_| len += 1)
.skip(1) .skip(1)
.for_each(|m| m.hash(s)); .for_each(|m| m.hash(s));
@ -121,7 +124,7 @@ pub fn calc_qualified_var_hash<'a>(modules: impl Iterator<Item = &'a str>, var_n
#[inline] #[inline]
#[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 IntoIterator<Item = &'a str>,
fn_name: &str, fn_name: &str,
num: usize, num: usize,
) -> u64 { ) -> u64 {
@ -130,6 +133,7 @@ pub fn calc_qualified_fn_hash<'a>(
// We always skip the first module // We always skip the first module
let mut len = 0; let mut len = 0;
modules modules
.into_iter()
.inspect(|_| len += 1) .inspect(|_| len += 1)
.skip(1) .skip(1)
.for_each(|m| m.hash(s)); .for_each(|m| m.hash(s));
@ -154,7 +158,7 @@ pub fn calc_qualified_fn_hash<'a>(
#[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: &str, num: usize) -> u64 {
calc_qualified_fn_hash(empty(), fn_name, num) calc_qualified_fn_hash(None, fn_name, num)
} }
/// Calculate a non-zero [`u64`] hash key from a list of parameter types. /// Calculate a non-zero [`u64`] hash key from a list of parameter types.
@ -166,10 +170,13 @@ pub fn calc_fn_hash(fn_name: &str, num: usize) -> u64 {
/// If the hash happens to be zero, it is mapped to `DEFAULT_HASH`. /// If the hash happens to be zero, it is mapped to `DEFAULT_HASH`.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn calc_fn_params_hash(params: impl Iterator<Item = TypeId>) -> u64 { pub fn calc_fn_params_hash(params: impl IntoIterator<Item = TypeId>) -> u64 {
let s = &mut get_hasher(); let s = &mut get_hasher();
let mut len = 0; let mut len = 0;
params.inspect(|_| len += 1).for_each(|t| t.hash(s)); params
.into_iter()
.inspect(|_| len += 1)
.for_each(|t| t.hash(s));
len.hash(s); len.hash(s);
match s.finish() { match s.finish() {

View File

@ -17,7 +17,6 @@ use std::{
cmp::Ordering, cmp::Ordering,
collections::{BTreeMap, BTreeSet}, collections::{BTreeMap, BTreeSet},
fmt, fmt,
iter::{empty, once},
ops::{Add, AddAssign}, ops::{Add, AddAssign},
}; };
@ -214,7 +213,7 @@ impl FuncInfo {
/// The first module name is skipped. Hashing starts from the _second_ module in the chain. /// The first module name is skipped. Hashing starts from the _second_ module in the chain.
#[inline] #[inline]
pub fn calc_native_fn_hash<'a>( pub fn calc_native_fn_hash<'a>(
modules: impl Iterator<Item = &'a str>, modules: impl IntoIterator<Item = &'a str>,
fn_name: &str, fn_name: &str,
params: &[TypeId], params: &[TypeId],
) -> u64 { ) -> u64 {
@ -626,7 +625,7 @@ impl Module {
let value = Dynamic::from(value); let value = Dynamic::from(value);
if self.indexed { if self.indexed {
let hash_var = crate::calc_qualified_var_hash(once(""), &ident); let hash_var = crate::calc_qualified_var_hash(Some(""), &ident);
self.all_variables.insert(hash_var, value.clone()); self.all_variables.insert(hash_var, value.clone());
} }
self.variables.insert(ident, value); self.variables.insert(ident, value);
@ -981,7 +980,7 @@ impl Module {
(names, return_type) (names, return_type)
}; };
let hash_fn = calc_native_fn_hash(empty::<&str>(), name.as_ref(), &param_types); let hash_fn = calc_native_fn_hash(None, name.as_ref(), &param_types);
self.functions.insert( self.functions.insert(
hash_fn, hash_fn,

View File

@ -1397,11 +1397,11 @@ pub mod array_functions {
/// ```rhai /// ```rhai
/// let x = [1, 2, 3, 4, 5]; /// let x = [1, 2, 3, 4, 5];
/// ///
/// let y = x.reduce(|r, v| v + if r == () { 0 } else { r }); /// let y = x.reduce(|r, v| v + (r ?? 0));
/// ///
/// print(y); // prints 15 /// print(y); // prints 15
/// ///
/// let y = x.reduce(|r, v, i| v + i + if r == () { 0 } else { r }); /// let y = x.reduce(|r, v, i| v + i + (r ?? 0));
/// ///
/// print(y); // prints 25 /// print(y); // prints 25
/// ``` /// ```
@ -1423,10 +1423,10 @@ pub mod array_functions {
/// ///
/// ```rhai /// ```rhai
/// fn process(r, x) { /// fn process(r, x) {
/// x + if r == () { 0 } else { r } /// x + (r ?? 0)
/// } /// }
/// fn process_extra(r, x, i) { /// fn process_extra(r, x, i) {
/// x + i + if r == () { 0 } else { r } /// x + i + (r ?? 0)
/// } /// }
/// ///
/// let x = [1, 2, 3, 4, 5]; /// let x = [1, 2, 3, 4, 5];
@ -1556,11 +1556,11 @@ pub mod array_functions {
/// ```rhai /// ```rhai
/// let x = [1, 2, 3, 4, 5]; /// let x = [1, 2, 3, 4, 5];
/// ///
/// let y = x.reduce_rev(|r, v| v + if r == () { 0 } else { r }); /// let y = x.reduce_rev(|r, v| v + (r ?? 0));
/// ///
/// print(y); // prints 15 /// print(y); // prints 15
/// ///
/// let y = x.reduce_rev(|r, v, i| v + i + if r == () { 0 } else { r }); /// let y = x.reduce_rev(|r, v, i| v + i + (r ?? 0));
/// ///
/// print(y); // prints 25 /// print(y); // prints 25
/// ``` /// ```
@ -1583,10 +1583,10 @@ pub mod array_functions {
/// ///
/// ```rhai /// ```rhai
/// fn process(r, x) { /// fn process(r, x) {
/// x + if r == () { 0 } else { r } /// x + (r ?? 0)
/// } /// }
/// fn process_extra(r, x, i) { /// fn process_extra(r, x, i) {
/// x + i + if r == () { 0 } else { r } /// x + i + (r ?? 0)
/// } /// }
/// ///
/// let x = [1, 2, 3, 4, 5]; /// let x = [1, 2, 3, 4, 5];

View File

@ -7,7 +7,7 @@ use crate::{calc_fn_hash, Engine, AST};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap, iter::empty}; use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap};
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -106,7 +106,7 @@ impl<'a> From<&'a FuncInfo> for FnMetadata<'a> {
} else { } else {
( (
FnType::Native, FnType::Native,
calc_native_fn_hash(empty::<&str>(), &info.metadata.name, &info.param_types), calc_native_fn_hash(None, &info.metadata.name, &info.param_types),
) )
}; };

View File

@ -1,6 +1,6 @@
#![cfg(not(feature = "no_function"))] #![cfg(not(feature = "no_function"))]
use rhai::{Dynamic, Engine, EvalAltResult, FnPtr, Func, FuncArgs, Scope, AST, INT}; use rhai::{Dynamic, Engine, EvalAltResult, FnPtr, Func, FuncArgs, Scope, AST, INT};
use std::{any::TypeId, iter::once}; use std::any::TypeId;
#[test] #[test]
fn test_call_fn() -> Result<(), Box<EvalAltResult>> { fn test_call_fn() -> Result<(), Box<EvalAltResult>> {
@ -107,9 +107,9 @@ struct Options {
impl FuncArgs for Options { impl FuncArgs for Options {
fn parse<C: Extend<Dynamic>>(self, container: &mut C) { fn parse<C: Extend<Dynamic>>(self, container: &mut C) {
container.extend(once(self.foo.into())); container.extend(Some(self.foo.into()));
container.extend(once(self.bar.into())); container.extend(Some(self.bar.into()));
container.extend(once(self.baz.into())); container.extend(Some(self.baz.into()));
} }
} }