Make API chainable.

This commit is contained in:
Stephen Chung
2020-07-12 11:46:53 +08:00
parent 2a8d63fd5f
commit 8449f8c55e
22 changed files with 223 additions and 143 deletions

View File

@@ -54,8 +54,9 @@ impl Engine {
name: &str,
arg_types: &[TypeId],
func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn<T> + SendSync + 'static,
) {
) -> &mut Self {
self.global_module.set_raw_fn(name, arg_types, func);
self
}
/// Register a function of no parameters with the `Engine`.
@@ -68,8 +69,9 @@ impl Engine {
&mut self,
name: &str,
func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn<T> + SendSync + 'static,
) {
) -> &mut Self {
self.global_module.set_raw_fn(name, &[], func);
self
}
/// Register a function of one parameter with the `Engine`.
@@ -92,9 +94,10 @@ impl Engine {
&mut self,
name: &str,
func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn<T> + SendSync + 'static,
) {
) -> &mut Self {
self.global_module
.set_raw_fn(name, &[TypeId::of::<A>()], func);
self
}
/// Register a function of two parameters with the `Engine`.
@@ -117,9 +120,10 @@ impl Engine {
&mut self,
name: &str,
func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn<T> + SendSync + 'static,
) {
) -> &mut Self {
self.global_module
.set_raw_fn(name, &[TypeId::of::<A>(), TypeId::of::<B>()], func);
self
}
/// Register a function of three parameters with the `Engine`.
@@ -147,12 +151,13 @@ impl Engine {
&mut self,
name: &str,
func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn<T> + SendSync + 'static,
) {
) -> &mut Self {
self.global_module.set_raw_fn(
name,
&[TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()],
func,
);
self
}
/// Register a function of four parameters with the `Engine`.
@@ -181,7 +186,7 @@ impl Engine {
&mut self,
name: &str,
func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn<T> + SendSync + 'static,
) {
) -> &mut Self {
self.global_module.set_raw_fn(
name,
&[
@@ -192,6 +197,7 @@ impl Engine {
],
func,
);
self
}
/// Register a custom type for use with the `Engine`.
@@ -231,8 +237,8 @@ impl Engine {
/// # }
/// ```
#[cfg(not(feature = "no_object"))]
pub fn register_type<T: Variant + Clone>(&mut self) {
self.register_type_with_name::<T>(type_name::<T>());
pub fn register_type<T: Variant + Clone>(&mut self) -> &mut Self {
self.register_type_with_name::<T>(type_name::<T>())
}
/// Register a custom type for use with the `Engine`, with a pretty-print name
@@ -279,7 +285,7 @@ impl Engine {
/// # }
/// ```
#[cfg(not(feature = "no_object"))]
pub fn register_type_with_name<T: Variant + Clone>(&mut self, name: &str) {
pub fn register_type_with_name<T: Variant + Clone>(&mut self, name: &str) -> &mut Self {
if self.type_names.is_none() {
self.type_names = Some(Default::default());
}
@@ -288,12 +294,14 @@ impl Engine {
.as_mut()
.unwrap()
.insert(type_name::<T>().to_string(), name.to_string());
self
}
/// Register an iterator adapter for a type with the `Engine`.
/// This is an advanced feature.
pub fn register_iterator<T: Variant + Clone>(&mut self, f: IteratorFn) {
pub fn register_iterator<T: Variant + Clone>(&mut self, f: IteratorFn) -> &mut Self {
self.global_module.set_iter(TypeId::of::<T>(), f);
self
}
/// Register a getter function for a member of a registered type with the `Engine`.
@@ -337,11 +345,12 @@ impl Engine {
&mut self,
name: &str,
callback: impl Fn(&mut T) -> U + SendSync + 'static,
) where
) -> &mut Self
where
T: Variant + Clone,
U: Variant + Clone,
{
self.register_fn(&make_getter(name), callback);
self.register_fn(&make_getter(name), callback)
}
/// Register a setter function for a member of a registered type with the `Engine`.
@@ -385,11 +394,12 @@ impl Engine {
&mut self,
name: &str,
callback: impl Fn(&mut T, U) + SendSync + 'static,
) where
) -> &mut Self
where
T: Variant + Clone,
U: Variant + Clone,
{
self.register_fn(&make_setter(name), callback);
self.register_fn(&make_setter(name), callback)
}
/// Shorthand for registering both getter and setter functions
@@ -436,12 +446,12 @@ impl Engine {
name: &str,
get_fn: impl Fn(&mut T) -> U + SendSync + 'static,
set_fn: impl Fn(&mut T, U) + SendSync + 'static,
) where
) -> &mut Self
where
T: Variant + Clone,
U: Variant + Clone,
{
self.register_get(name, get_fn);
self.register_set(name, set_fn);
self.register_get(name, get_fn).register_set(name, set_fn)
}
/// Register an index getter for a registered type with the `Engine`.
@@ -485,12 +495,13 @@ impl Engine {
pub fn register_indexer_get<T, X, U>(
&mut self,
callback: impl Fn(&mut T, X) -> U + SendSync + 'static,
) where
) -> &mut Self
where
T: Variant + Clone,
U: Variant + Clone,
X: Variant + Clone,
{
self.register_fn(FN_IDX_GET, callback);
self.register_fn(FN_IDX_GET, callback)
}
/// Register an index setter for a registered type with the `Engine`.
@@ -533,12 +544,13 @@ impl Engine {
pub fn register_indexer_set<T, X, U>(
&mut self,
callback: impl Fn(&mut T, X, U) -> () + SendSync + 'static,
) where
) -> &mut Self
where
T: Variant + Clone,
U: Variant + Clone,
X: Variant + Clone,
{
self.register_fn(FN_IDX_SET, callback);
self.register_fn(FN_IDX_SET, callback)
}
/// Shorthand for register both index getter and setter functions for a registered type with the `Engine`.
@@ -580,13 +592,14 @@ impl Engine {
&mut self,
getter: impl Fn(&mut T, X) -> U + SendSync + 'static,
setter: impl Fn(&mut T, X, U) -> () + SendSync + 'static,
) where
) -> &mut Self
where
T: Variant + Clone,
U: Variant + Clone,
X: Variant + Clone,
{
self.register_indexer_get(getter);
self.register_indexer_set(setter);
self.register_indexer_get(getter)
.register_indexer_set(setter)
}
/// Compile a string into an `AST`, which can be used later for evaluation.
@@ -1466,8 +1479,12 @@ impl Engine {
/// # Ok(())
/// # }
/// ```
pub fn on_progress(&mut self, callback: impl Fn(&u64) -> bool + SendSync + 'static) {
pub fn on_progress(
&mut self,
callback: impl Fn(&u64) -> bool + SendSync + 'static,
) -> &mut Self {
self.progress = Some(Box::new(callback));
self
}
/// Override default action of `print` (print to stdout using `println!`)
@@ -1494,8 +1511,9 @@ impl Engine {
/// # Ok(())
/// # }
/// ```
pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) {
pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self {
self.print = Box::new(callback);
self
}
/// Override default action of `debug` (print to stdout using `println!`)
@@ -1522,7 +1540,8 @@ impl Engine {
/// # Ok(())
/// # }
/// ```
pub fn on_debug(&mut self, callback: impl Fn(&str) + SendSync + 'static) {
pub fn on_debug(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self {
self.debug = Box::new(callback);
self
}
}

View File

@@ -40,7 +40,7 @@ pub trait RegisterFn<FN, ARGS, RET> {
/// # Ok(())
/// # }
/// ```
fn register_fn(&mut self, name: &str, f: FN);
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self;
}
/// Trait to register fallible custom functions returning `Result<Dynamic, Box<EvalAltResult>>` with the `Engine`.
@@ -70,7 +70,7 @@ pub trait RegisterResultFn<FN, ARGS> {
/// engine.eval::<i64>("div(42, 0)")
/// .expect_err("expecting division by zero error!");
/// ```
fn register_result_fn(&mut self, name: &str, f: FN);
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self;
}
// These types are used to build a unique _marker_ tuple type for each combination
@@ -182,11 +182,12 @@ macro_rules! def_register {
RET: Variant + Clone
> RegisterFn<FN, ($($mark,)*), RET> for Engine
{
fn register_fn(&mut self, name: &str, f: FN) {
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
self.global_module.set_fn(name, FnAccess::Public,
&[$(map_type_id::<$par>()),*],
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $clone),*))
);
self
}
}
@@ -195,11 +196,12 @@ macro_rules! def_register {
FN: Fn($($param),*) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static,
> RegisterResultFn<FN, ($($mark,)*)> for Engine
{
fn register_result_fn(&mut self, name: &str, f: FN) {
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
self.global_module.set_fn(name, FnAccess::Public,
&[$(map_type_id::<$par>()),*],
CallableFunction::$abi(make_func!(f : map_result ; $($par => $clone),*))
);
self
}
}

View File

@@ -214,9 +214,10 @@ impl Module {
/// module.set_var("answer", 42_i64);
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
/// ```
pub fn set_var(&mut self, name: impl Into<String>, value: impl Variant + Clone) {
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.indexed = false;
self
}
/// Get a mutable reference to a modules-qualified variable.
@@ -239,7 +240,7 @@ impl Module {
///
/// If there is an existing function of the same name and number of arguments, it is replaced.
#[cfg(not(feature = "no_function"))]
pub(crate) fn set_script_fn(&mut self, fn_def: ScriptFnDef) {
pub(crate) fn set_script_fn(&mut self, fn_def: ScriptFnDef) -> &mut Self {
// None + function name + number of arguments.
let hash_script = calc_fn_hash(empty(), &fn_def.name, fn_def.params.len(), empty());
self.functions.insert(
@@ -252,6 +253,7 @@ impl Module {
),
);
self.indexed = false;
self
}
/// Does a sub-module exist in the module?
@@ -316,9 +318,10 @@ impl Module {
/// module.set_sub_module("question", sub_module);
/// assert!(module.get_sub_module("question").is_some());
/// ```
pub fn set_sub_module(&mut self, name: impl Into<String>, sub_module: Module) {
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.indexed = false;
self
}
/// Does the particular Rust function exist in the module?
@@ -865,7 +868,7 @@ impl Module {
}
/// Merge another module into this module.
pub fn merge(&mut self, other: &Self) {
pub fn merge(&mut self, other: &Self) -> &mut Self {
self.merge_filtered(other, |_, _, _| true)
}
@@ -874,7 +877,7 @@ impl Module {
&mut self,
other: &Self,
filter: impl Fn(FnAccess, &str, usize) -> bool,
) {
) -> &mut Self {
self.variables
.extend(other.variables.iter().map(|(k, v)| (k.clone(), v.clone())));
@@ -896,11 +899,15 @@ impl Module {
self.all_functions.clear();
self.all_variables.clear();
self.indexed = false;
self
}
/// Filter out the functions, retaining only some based on a filter predicate.
#[cfg(not(feature = "no_function"))]
pub(crate) fn retain_functions(&mut self, filter: impl Fn(FnAccess, &str, usize) -> bool) {
pub(crate) fn retain_functions(
&mut self,
filter: impl Fn(FnAccess, &str, usize) -> bool,
) -> &mut Self {
self.functions.retain(|_, (_, _, _, v)| match v {
Func::Script(ref f) => filter(f.access, f.name.as_str(), f.params.len()),
_ => true,
@@ -909,6 +916,7 @@ impl Module {
self.all_functions.clear();
self.all_variables.clear();
self.indexed = false;
self
}
/// Get the number of variables in the module.
@@ -1071,9 +1079,10 @@ impl Module {
}
/// Set a type iterator into the module.
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) {
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self {
self.type_iterators.insert(typ, func);
self.indexed = false;
self
}
/// Get the specified type iterator.

View File

@@ -732,7 +732,9 @@ pub fn optimize_into_ast(
}
.into()
})
.for_each(|fn_def| lib2.set_script_fn(fn_def));
.for_each(|fn_def| {
lib2.set_script_fn(fn_def);
});
functions
.into_iter()
@@ -761,11 +763,13 @@ pub fn optimize_into_ast(
};
fn_def.into()
})
.for_each(|fn_def| module.set_script_fn(fn_def));
.for_each(|fn_def| {
module.set_script_fn(fn_def);
});
} else {
functions
.into_iter()
.for_each(|fn_def| module.set_script_fn(fn_def));
functions.into_iter().for_each(|fn_def| {
module.set_script_fn(fn_def);
});
}
module

View File

@@ -97,8 +97,9 @@ impl<'a> Scope<'a> {
/// assert_eq!(my_scope.len(), 0);
/// assert!(my_scope.is_empty());
/// ```
pub fn clear(&mut self) {
pub fn clear(&mut self) -> &mut Self {
self.0.clear();
self
}
/// Get the number of entries inside the Scope.
@@ -147,8 +148,12 @@ impl<'a> Scope<'a> {
/// my_scope.push("x", 42_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ```
pub fn push<K: Into<Cow<'a, str>>, T: Variant + Clone>(&mut self, name: K, value: T) {
self.push_dynamic_value(name, EntryType::Normal, Dynamic::from(value), false);
pub fn push<K: Into<Cow<'a, str>>, T: Variant + Clone>(
&mut self,
name: K,
value: T,
) -> &mut Self {
self.push_dynamic_value(name, EntryType::Normal, Dynamic::from(value), false)
}
/// Add (push) a new `Dynamic` entry to the Scope.
@@ -163,8 +168,8 @@ impl<'a> Scope<'a> {
/// my_scope.push_dynamic("x", Dynamic::from(42_i64));
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ```
pub fn push_dynamic<K: Into<Cow<'a, str>>>(&mut self, name: K, value: Dynamic) {
self.push_dynamic_value(name, EntryType::Normal, value, false);
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)
}
/// Add (push) a new constant to the Scope.
@@ -185,8 +190,12 @@ impl<'a> Scope<'a> {
/// my_scope.push_constant("x", 42_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ```
pub fn push_constant<K: Into<Cow<'a, str>>, T: Variant + Clone>(&mut self, name: K, value: T) {
self.push_dynamic_value(name, EntryType::Constant, Dynamic::from(value), true);
pub fn push_constant<K: Into<Cow<'a, str>>, T: Variant + Clone>(
&mut self,
name: K,
value: T,
) -> &mut Self {
self.push_dynamic_value(name, EntryType::Constant, Dynamic::from(value), true)
}
/// Add (push) a new constant with a `Dynamic` value to the Scope.
@@ -208,8 +217,12 @@ impl<'a> Scope<'a> {
/// my_scope.push_constant_dynamic("x", Dynamic::from(42_i64));
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 42);
/// ```
pub fn push_constant_dynamic<K: Into<Cow<'a, str>>>(&mut self, name: K, value: Dynamic) {
self.push_dynamic_value(name, EntryType::Constant, value, true);
pub fn push_constant_dynamic<K: Into<Cow<'a, str>>>(
&mut self,
name: K,
value: Dynamic,
) -> &mut Self {
self.push_dynamic_value(name, EntryType::Constant, value, true)
}
/// Add (push) a new entry with a `Dynamic` value to the Scope.
@@ -219,7 +232,7 @@ impl<'a> Scope<'a> {
entry_type: EntryType,
value: Dynamic,
map_expr: bool,
) {
) -> &mut Self {
let expr = if map_expr {
map_dynamic_to_expr(value.clone(), Position::none()).map(Box::new)
} else {
@@ -233,6 +246,8 @@ impl<'a> Scope<'a> {
value: value.into(),
expr,
});
self
}
/// Truncate (rewind) the Scope to a previous size.
@@ -261,8 +276,9 @@ impl<'a> Scope<'a> {
/// assert_eq!(my_scope.len(), 0);
/// assert!(my_scope.is_empty());
/// ```
pub fn rewind(&mut self, size: usize) {
pub fn rewind(&mut self, size: usize) -> &mut Self {
self.0.truncate(size);
self
}
/// Does the scope contain the entry?
@@ -341,14 +357,17 @@ impl<'a> Scope<'a> {
/// my_scope.set_value("x", 0_i64);
/// assert_eq!(my_scope.get_value::<i64>("x").unwrap(), 0);
/// ```
pub fn set_value<T: Variant + Clone>(&mut self, name: &'a str, value: T) {
pub fn set_value<T: Variant + Clone>(&mut self, name: &'a str, value: T) -> &mut Self {
match self.get_index(name) {
None => self.push(name, value),
None => {
self.push(name, value);
}
Some((_, EntryType::Constant)) => panic!("variable {} is constant", name),
Some((index, EntryType::Normal)) => {
self.0.get_mut(index).unwrap().value = Dynamic::from(value)
self.0.get_mut(index).unwrap().value = Dynamic::from(value);
}
}
self
}
/// Get a mutable reference to an entry in the Scope.
@@ -358,9 +377,10 @@ impl<'a> Scope<'a> {
}
/// Update the access type of an entry in the Scope.
pub(crate) fn set_entry_alias(&mut self, index: usize, alias: String) {
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");
entry.alias = Some(Box::new(alias));
self
}
/// Get an iterator to entries in the Scope.

View File

@@ -9,26 +9,19 @@ impl Engine {
///
/// When searching for functions, packages loaded later are preferred.
/// In other words, loaded packages are searched in reverse order.
pub fn load_package(&mut self, package: PackageLibrary) {
// Push the package to the top - packages are searched in reverse order
self.packages.push(package);
}
/// Load a new package into the `Engine`.
///
/// When searching for functions, packages loaded later are preferred.
/// In other words, loaded packages are searched in reverse order.
pub fn load_packages(&mut self, package: PackageLibrary) {
pub fn load_package(&mut self, package: PackageLibrary) -> &mut Self {
// Push the package to the top - packages are searched in reverse order
self.packages.push(package);
self
}
/// Control whether and how the `Engine` will optimize an AST after compilation.
///
/// Not available under the `no_optimize` feature.
#[cfg(not(feature = "no_optimize"))]
pub fn set_optimization_level(&mut self, optimization_level: OptimizationLevel) {
self.optimization_level = optimization_level
pub fn set_optimization_level(&mut self, optimization_level: OptimizationLevel) -> &mut Self {
self.optimization_level = optimization_level;
self
}
/// The current optimization level.
@@ -43,8 +36,9 @@ impl Engine {
/// Set the maximum levels of function calls allowed for a script in order to avoid
/// infinite recursion and stack overflows.
#[cfg(not(feature = "unchecked"))]
pub fn set_max_call_levels(&mut self, levels: usize) {
self.max_call_stack_depth = levels
pub fn set_max_call_levels(&mut self, levels: usize) -> &mut Self {
self.max_call_stack_depth = levels;
self
}
/// The maximum levels of function calls allowed for a script.
@@ -56,12 +50,13 @@ impl Engine {
/// Set the maximum number of operations allowed for a script to run to avoid
/// consuming too much resources (0 for unlimited).
#[cfg(not(feature = "unchecked"))]
pub fn set_max_operations(&mut self, operations: u64) {
pub fn set_max_operations(&mut self, operations: u64) -> &mut Self {
self.max_operations = if operations == u64::MAX {
0
} else {
operations
};
self
}
/// The maximum number of operations allowed for a script to run (0 for unlimited).
@@ -72,8 +67,9 @@ impl Engine {
/// Set the maximum number of imported modules allowed for a script.
#[cfg(not(feature = "unchecked"))]
pub fn set_max_modules(&mut self, modules: usize) {
pub fn set_max_modules(&mut self, modules: usize) -> &mut Self {
self.max_modules = modules;
self
}
/// The maximum number of imported modules allowed for a script.
@@ -84,7 +80,11 @@ impl Engine {
/// Set the depth limits for expressions (0 for unlimited).
#[cfg(not(feature = "unchecked"))]
pub fn set_max_expr_depths(&mut self, max_expr_depth: usize, max_function_expr_depth: usize) {
pub fn set_max_expr_depths(
&mut self,
max_expr_depth: usize,
max_function_expr_depth: usize,
) -> &mut Self {
self.max_expr_depth = if max_expr_depth == usize::MAX {
0
} else {
@@ -95,6 +95,7 @@ impl Engine {
} else {
max_function_expr_depth
};
self
}
/// The depth limit for expressions (0 for unlimited).
@@ -111,8 +112,9 @@ impl Engine {
/// Set the maximum length of strings (0 for unlimited).
#[cfg(not(feature = "unchecked"))]
pub fn set_max_string_size(&mut self, max_size: usize) {
pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self {
self.max_string_size = if max_size == usize::MAX { 0 } else { max_size };
self
}
/// The maximum length of strings (0 for unlimited).
@@ -124,8 +126,9 @@ impl Engine {
/// Set the maximum length of arrays (0 for unlimited).
#[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))]
pub fn set_max_array_size(&mut self, max_size: usize) {
pub fn set_max_array_size(&mut self, max_size: usize) -> &mut Self {
self.max_array_size = if max_size == usize::MAX { 0 } else { max_size };
self
}
/// The maximum length of arrays (0 for unlimited).
@@ -138,8 +141,9 @@ impl Engine {
/// Set the maximum length of object maps (0 for unlimited).
#[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))]
pub fn set_max_map_size(&mut self, max_size: usize) {
pub fn set_max_map_size(&mut self, max_size: usize) -> &mut Self {
self.max_map_size = if max_size == usize::MAX { 0 } else { max_size };
self
}
/// The maximum length of object maps (0 for unlimited).
@@ -153,8 +157,12 @@ impl Engine {
///
/// Not available under the `no_module` feature.
#[cfg(not(feature = "no_module"))]
pub fn set_module_resolver(&mut self, resolver: Option<impl ModuleResolver + 'static>) {
pub fn set_module_resolver(
&mut self,
resolver: Option<impl ModuleResolver + 'static>,
) -> &mut Self {
self.module_resolver = resolver.map(|f| Box::new(f) as Box<dyn ModuleResolver>);
self
}
/// Disable a particular keyword or operator in the language.
@@ -194,7 +202,7 @@ impl Engine {
/// # Ok(())
/// # }
/// ```
pub fn disable_symbol(&mut self, symbol: &str) {
pub fn disable_symbol(&mut self, symbol: &str) -> &mut Self {
if self.disabled_symbols.is_none() {
self.disabled_symbols = Some(Default::default());
}
@@ -203,6 +211,8 @@ impl Engine {
.as_mut()
.unwrap()
.insert(symbol.into());
self
}
/// Register a custom operator into the language.
@@ -235,7 +245,7 @@ impl Engine {
&mut self,
keyword: &str,
precedence: u8,
) -> Result<(), String> {
) -> Result<&mut Self, String> {
if !is_valid_identifier(keyword.chars()) {
return Err(format!("not a valid identifier: '{}'", keyword).into());
}
@@ -249,6 +259,6 @@ impl Engine {
.unwrap()
.insert(keyword.into(), precedence);
Ok(())
Ok(self)
}
}

View File

@@ -39,7 +39,7 @@ pub type FnCustomSyntaxEval = dyn Fn(
&mut State,
&Module,
&mut Option<&mut Dynamic>,
&[Expr],
&[Expression],
usize,
) -> Result<Dynamic, Box<EvalAltResult>>
+ Send
@@ -75,7 +75,7 @@ impl Engine {
) -> Result<Dynamic, Box<EvalAltResult>>
+ SendSync
+ 'static,
) -> Result<(), Box<LexError>> {
) -> Result<self, Box<LexError>> {
if value.is_empty() {
return Err(Box::new(LexError::ImproperSymbol("".to_string())));
}
@@ -145,6 +145,6 @@ impl Engine {
.unwrap()
.insert(key, syntax.into());
Ok(())
Ok(self)
}
}