From 2f395492de5a9ce4c253ec227cdfc02f7ad83108 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Thu, 6 Aug 2020 10:17:32 +0800 Subject: [PATCH] Simply error code. --- doc/src/engine/custom-syntax.md | 6 +- doc/src/rust/modules/imp-resolver.md | 2 +- src/api.rs | 31 ++---- src/engine.rs | 148 +++++++++++---------------- src/fn_call.rs | 80 ++++++++------- src/fn_native.rs | 5 +- src/module.rs | 12 +-- src/packages/arithmetic.rs | 93 +++++++++-------- src/packages/array_basic.rs | 5 +- src/packages/math_basic.rs | 10 +- src/packages/string_more.rs | 8 +- src/packages/time_basic.rs | 12 +-- src/result.rs | 6 ++ src/serde/de.rs | 10 +- src/serde/ser.rs | 38 +++---- src/serde/str.rs | 5 +- 16 files changed, 228 insertions(+), 243 deletions(-) diff --git a/doc/src/engine/custom-syntax.md b/doc/src/engine/custom-syntax.md index 8f308106..8d0820c8 100644 --- a/doc/src/engine/custom-syntax.md +++ b/doc/src/engine/custom-syntax.md @@ -200,8 +200,10 @@ fn implementation_func( // Evaluate the condition expression let stop = !engine.eval_expression_tree(context, scope, condition)? - .as_bool().map_err(|_| EvalAltResult::ErrorBooleanArgMismatch( - "do-while".into(), expr.position()))?; + .as_bool() + .map_err(|_| EvalAltResult::ErrorBooleanArgMismatch( + "do-while".into(), expr.position() + ))?; if stop { break; diff --git a/doc/src/rust/modules/imp-resolver.md b/doc/src/rust/modules/imp-resolver.md index 55d68315..d1d9ed38 100644 --- a/doc/src/rust/modules/imp-resolver.md +++ b/doc/src/rust/modules/imp-resolver.md @@ -38,7 +38,7 @@ impl ModuleResolver for MyModuleResolver { let module: Module = load_secret_module(path); Ok(module) } else { - Err(Box::new(EvalAltResult::ErrorModuleNotFound(path.into(), pos))) + Err(EvalAltResult::ErrorModuleNotFound(path.into(), pos).into()) } } } diff --git a/src/api.rs b/src/api.rs index cdb4a801..34af07a1 100644 --- a/src/api.rs +++ b/src/api.rs @@ -608,21 +608,13 @@ impl Engine { #[cfg(not(target_arch = "wasm32"))] fn read_file(path: PathBuf) -> Result> { let mut f = File::open(path.clone()).map_err(|err| { - Box::new(EvalAltResult::ErrorReadingScriptFile( - path.clone(), - Position::none(), - err, - )) + EvalAltResult::ErrorReadingScriptFile(path.clone(), Position::none(), err) })?; let mut contents = String::new(); f.read_to_string(&mut contents).map_err(|err| { - Box::new(EvalAltResult::ErrorReadingScriptFile( - path.clone(), - Position::none(), - err, - )) + EvalAltResult::ErrorReadingScriptFile(path.clone(), Position::none(), err) })?; Ok(contents) @@ -1042,11 +1034,12 @@ impl Engine { let typ = self.map_type_name(result.type_name()); return result.try_cast::().ok_or_else(|| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), typ.into(), Position::none(), - )) + ) + .into() }); } @@ -1190,11 +1183,12 @@ impl Engine { let typ = self.map_type_name(result.type_name()); return result.try_cast().ok_or_else(|| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), typ.into(), Position::none(), - )) + ) + .into() }); } @@ -1278,13 +1272,8 @@ impl Engine { ) -> FuncReturn { let lib = lib.as_ref(); let mut args: StaticVec<_> = arg_values.iter_mut().collect(); - let fn_def = - get_script_function_by_signature(lib, name, args.len(), true).ok_or_else(|| { - Box::new(EvalAltResult::ErrorFunctionNotFound( - name.into(), - Position::none(), - )) - })?; + let fn_def = get_script_function_by_signature(lib, name, args.len(), true) + .ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), Position::none()))?; let mut state = State::new(); let mut mods = Imports::new(); diff --git a/src/engine.rs b/src/engine.rs index d485f22b..9a771ac6 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -228,9 +228,7 @@ impl Target<'_> { #[cfg(not(feature = "no_object"))] Self::LockGuard((r, _)) => **r = new_val, Self::Value(_) => { - return Err(Box::new(EvalAltResult::ErrorAssignmentToUnknownLHS( - Position::none(), - ))) + return EvalAltResult::ErrorAssignmentToUnknownLHS(Position::none()).into(); } #[cfg(not(feature = "no_index"))] Self::StringChar(string, index, _) if string.is::() => { @@ -517,12 +515,7 @@ pub fn search_imports<'s>( .rev() .find(|(n, _)| n == root) .map(|(_, m)| m) - .ok_or_else(|| { - Box::new(EvalAltResult::ErrorModuleNotFound( - root.to_string(), - *root_pos, - )) - })? + .ok_or_else(|| EvalAltResult::ErrorModuleNotFound(root.to_string(), *root_pos))? }) } @@ -550,12 +543,7 @@ pub fn search_imports_mut<'s>( .rev() .find(|(n, _)| n == root) .map(|(_, m)| m) - .ok_or_else(|| { - Box::new(EvalAltResult::ErrorModuleNotFound( - root.to_string(), - *root_pos, - )) - })? + .ok_or_else(|| EvalAltResult::ErrorModuleNotFound(root.to_string(), *root_pos))? }) } @@ -577,10 +565,11 @@ pub fn search_namespace<'s, 'a>( .get_qualified_var_mut(*hash_var) .map_err(|err| match *err { EvalAltResult::ErrorVariableNotFound(_, _) => { - Box::new(EvalAltResult::ErrorVariableNotFound( + EvalAltResult::ErrorVariableNotFound( format!("{}{}", modules, name), *pos, - )) + ) + .into() } _ => err.new_position(*pos), })?; @@ -612,7 +601,7 @@ pub fn search_scope_only<'s, 'a>( if let Some(val) = this_ptr { return Ok(((*val).into(), KEYWORD_THIS, ScopeEntryType::Normal, *pos)); } else { - return Err(Box::new(EvalAltResult::ErrorUnboundThis(*pos))); + return EvalAltResult::ErrorUnboundThis(*pos).into(); } } @@ -625,7 +614,7 @@ pub fn search_scope_only<'s, 'a>( // Find the variable in the scope scope .get_index(name) - .ok_or_else(|| Box::new(EvalAltResult::ErrorVariableNotFound(name.into(), *pos)))? + .ok_or_else(|| EvalAltResult::ErrorVariableNotFound(name.into(), *pos))? .0 }; @@ -634,7 +623,7 @@ pub fn search_scope_only<'s, 'a>( // Check for data race - probably not necessary because the only place it should conflict is in a method call // when the object variable is also used as a parameter. // if cfg!(not(feature = "no_closure")) && val.is_locked() { - // return Err(Box::new(EvalAltResult::ErrorDataRace(name.into(), *pos))); + // return EvalAltResult::ErrorDataRace(name.into(), *pos).into(); // } Ok((val, name, typ, *pos)) @@ -966,10 +955,7 @@ impl Engine { } } // Syntax error - _ => Err(Box::new(EvalAltResult::ErrorDotExpr( - "".into(), - rhs.position(), - ))), + _ => EvalAltResult::ErrorDotExpr("".into(), rhs.position()).into(), } } @@ -1016,10 +1002,8 @@ impl Engine { // Constants cannot be modified match typ { ScopeEntryType::Constant if new_val.is_some() => { - return Err(Box::new(EvalAltResult::ErrorAssignmentToConstant( - var_name.to_string(), - pos, - ))); + return EvalAltResult::ErrorAssignmentToConstant(var_name.to_string(), pos) + .into(); } ScopeEntryType::Constant | ScopeEntryType::Normal => (), } @@ -1033,9 +1017,7 @@ impl Engine { } // {expr}.??? = ??? or {expr}[???] = ??? expr if new_val.is_some() => { - return Err(Box::new(EvalAltResult::ErrorAssignmentToUnknownLHS( - expr.position(), - ))); + return EvalAltResult::ErrorAssignmentToUnknownLHS(expr.position()).into(); } // {expr}.??? or {expr}[???] expr => { @@ -1160,12 +1142,10 @@ impl Engine { arr.get_mut(index as usize) .map(Target::from) .ok_or_else(|| { - Box::new(EvalAltResult::ErrorArrayBounds(arr_len, index, idx_pos)) + EvalAltResult::ErrorArrayBounds(arr_len, index, idx_pos).into() }) } else { - Err(Box::new(EvalAltResult::ErrorArrayBounds( - arr_len, index, idx_pos, - ))) + EvalAltResult::ErrorArrayBounds(arr_len, index, idx_pos).into() } } @@ -1200,13 +1180,11 @@ impl Engine { if index >= 0 { let offset = index as usize; let ch = s.chars().nth(offset).ok_or_else(|| { - Box::new(EvalAltResult::ErrorStringBounds(chars_len, index, idx_pos)) + EvalAltResult::ErrorStringBounds(chars_len, index, idx_pos) })?; Ok(Target::StringChar(val, offset, ch.into())) } else { - Err(Box::new(EvalAltResult::ErrorStringBounds( - chars_len, index, idx_pos, - ))) + EvalAltResult::ErrorStringBounds(chars_len, index, idx_pos).into() } } @@ -1227,10 +1205,11 @@ impl Engine { }) } - _ => Err(Box::new(EvalAltResult::ErrorIndexingType( + _ => EvalAltResult::ErrorIndexingType( self.map_type_name(val.type_name()).into(), Position::none(), - ))), + ) + .into(), } } @@ -1284,15 +1263,15 @@ impl Engine { // Only allows String or char Dynamic(Union::Str(s)) => Ok(rhs_value.contains_key(&s).into()), Dynamic(Union::Char(c)) => Ok(rhs_value.contains_key(&c.to_string()).into()), - _ => Err(Box::new(EvalAltResult::ErrorInExpr(lhs.position()))), + _ => EvalAltResult::ErrorInExpr(lhs.position()).into(), }, Dynamic(Union::Str(rhs_value)) => match lhs_value { // Only allows String or char Dynamic(Union::Str(s)) => Ok(rhs_value.contains(s.as_str()).into()), Dynamic(Union::Char(c)) => Ok(rhs_value.contains(c).into()), - _ => Err(Box::new(EvalAltResult::ErrorInExpr(lhs.position()))), + _ => EvalAltResult::ErrorInExpr(lhs.position()).into(), }, - _ => Err(Box::new(EvalAltResult::ErrorInExpr(rhs.position()))), + _ => EvalAltResult::ErrorInExpr(rhs.position()).into(), } } @@ -1323,7 +1302,7 @@ impl Engine { if let Some(val) = this_ptr { Ok(val.clone()) } else { - Err(Box::new(EvalAltResult::ErrorUnboundThis((x.0).1))) + EvalAltResult::ErrorUnboundThis((x.0).1).into() } } Expr::Variable(_) => { @@ -1454,16 +1433,13 @@ impl Engine { Ok(Default::default()) } // Error assignment to constant - expr if expr.is_constant() => { - Err(Box::new(EvalAltResult::ErrorAssignmentToConstant( - expr.get_constant_str(), - expr.position(), - ))) - } - // Syntax error - expr => Err(Box::new(EvalAltResult::ErrorAssignmentToUnknownLHS( + expr if expr.is_constant() => EvalAltResult::ErrorAssignmentToConstant( + expr.get_constant_str(), expr.position(), - ))), + ) + .into(), + // Syntax error + expr => EvalAltResult::ErrorAssignmentToUnknownLHS(expr.position()).into(), } } @@ -1632,7 +1608,7 @@ impl Engine { self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)? .as_bool() - .map_err(|_| Box::new(EvalAltResult::ErrorLogicGuard(expr.position()))) + .map_err(|_| EvalAltResult::ErrorLogicGuard(expr.position()).into()) .and_then(|guard_val| { if guard_val { self.eval_stmt(scope, mods, state, lib, this_ptr, if_block, level) @@ -1665,9 +1641,7 @@ impl Engine { } } Ok(false) => return Ok(Default::default()), - Err(_) => { - return Err(Box::new(EvalAltResult::ErrorLogicGuard(expr.position()))) - } + Err(_) => return EvalAltResult::ErrorLogicGuard(expr.position()).into(), } }, @@ -1727,43 +1701,45 @@ impl Engine { state.scope_level -= 1; Ok(Default::default()) } else { - Err(Box::new(EvalAltResult::ErrorFor(x.1.position()))) + EvalAltResult::ErrorFor(x.1.position()).into() } } // Continue statement - Stmt::Continue(pos) => Err(Box::new(EvalAltResult::ErrorLoopBreak(false, *pos))), + Stmt::Continue(pos) => EvalAltResult::ErrorLoopBreak(false, *pos).into(), // Break statement - Stmt::Break(pos) => Err(Box::new(EvalAltResult::ErrorLoopBreak(true, *pos))), + Stmt::Break(pos) => EvalAltResult::ErrorLoopBreak(true, *pos).into(), // Return value Stmt::ReturnWithVal(x) if x.1.is_some() && (x.0).0 == ReturnType::Return => { let expr = x.1.as_ref().unwrap(); - Err(Box::new(EvalAltResult::Return( + EvalAltResult::Return( self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?, (x.0).1, - ))) + ) + .into() } // Empty return Stmt::ReturnWithVal(x) if (x.0).0 == ReturnType::Return => { - Err(Box::new(EvalAltResult::Return(Default::default(), (x.0).1))) + EvalAltResult::Return(Default::default(), (x.0).1).into() } // Throw value Stmt::ReturnWithVal(x) if x.1.is_some() && (x.0).0 == ReturnType::Exception => { let expr = x.1.as_ref().unwrap(); let val = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?; - Err(Box::new(EvalAltResult::ErrorRuntime( + EvalAltResult::ErrorRuntime( val.take_string().unwrap_or_else(|_| "".into()), (x.0).1, - ))) + ) + .into() } // Empty throw Stmt::ReturnWithVal(x) if (x.0).0 == ReturnType::Exception => { - Err(Box::new(EvalAltResult::ErrorRuntime("".into(), (x.0).1))) + EvalAltResult::ErrorRuntime("".into(), (x.0).1).into() } Stmt::ReturnWithVal(_) => unreachable!(), @@ -1811,7 +1787,7 @@ impl Engine { // Guard against too many modules #[cfg(not(feature = "unchecked"))] if state.modules >= self.limits.max_modules { - return Err(Box::new(EvalAltResult::ErrorTooManyModules(*_pos))); + return EvalAltResult::ErrorTooManyModules(*_pos).into(); } if let Some(path) = self @@ -1830,13 +1806,13 @@ impl Engine { Ok(Default::default()) } else { - Err(Box::new(EvalAltResult::ErrorModuleNotFound( - path.to_string(), - expr.position(), - ))) + Err( + EvalAltResult::ErrorModuleNotFound(path.to_string(), expr.position()) + .into(), + ) } } else { - Err(Box::new(EvalAltResult::ErrorImportExpr(expr.position()))) + EvalAltResult::ErrorImportExpr(expr.position()).into() } } @@ -1849,10 +1825,7 @@ impl Engine { let alias = rename.as_ref().map(|(n, _)| n).unwrap_or_else(|| id); scope.set_entry_alias(index, alias.clone()); } else { - return Err(Box::new(EvalAltResult::ErrorVariableNotFound( - id.into(), - *id_pos, - ))); + return EvalAltResult::ErrorVariableNotFound(id.into(), *id_pos).into(); } } Ok(Default::default()) @@ -1976,26 +1949,29 @@ impl Engine { let (arr, map, s) = calc_size(result.as_ref().unwrap()); if s > self.limits.max_string_size { - Err(Box::new(EvalAltResult::ErrorDataTooLarge( + EvalAltResult::ErrorDataTooLarge( "Length of string".to_string(), self.limits.max_string_size, s, Position::none(), - ))) + ) + .into() } else if arr > self.limits.max_array_size { - Err(Box::new(EvalAltResult::ErrorDataTooLarge( + EvalAltResult::ErrorDataTooLarge( "Size of array".to_string(), self.limits.max_array_size, arr, Position::none(), - ))) + ) + .into() } else if map > self.limits.max_map_size { - Err(Box::new(EvalAltResult::ErrorDataTooLarge( + EvalAltResult::ErrorDataTooLarge( "Number of properties in object map".to_string(), self.limits.max_map_size, map, Position::none(), - ))) + ) + .into() } else { result } @@ -2009,16 +1985,14 @@ impl Engine { #[cfg(not(feature = "unchecked"))] // Guard against too many operations if self.limits.max_operations > 0 && state.operations > self.limits.max_operations { - return Err(Box::new(EvalAltResult::ErrorTooManyOperations( - Position::none(), - ))); + return EvalAltResult::ErrorTooManyOperations(Position::none()).into(); } // Report progress - only in steps if let Some(progress) = &self.progress { if !progress(&state.operations) { // Terminate script if progress returns false - return Err(Box::new(EvalAltResult::ErrorTerminated(Position::none()))); + return EvalAltResult::ErrorTerminated(Position::none()).into(); } } diff --git a/src/fn_call.rs b/src/fn_call.rs index d93ba533..20557748 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -178,10 +178,11 @@ pub fn ensure_no_data_race( .enumerate() .find(|(_, a)| a.is_locked()) { - return Err(Box::new(EvalAltResult::ErrorDataRace( + return EvalAltResult::ErrorDataRace( format!("argument #{} of function '{}'", n + 1 + skip, fn_name), Position::none(), - ))); + ) + .into(); } } @@ -237,22 +238,22 @@ impl Engine { return Ok(match fn_name { KEYWORD_PRINT => ( (self.print)(result.as_str().map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), typ.into(), Position::none(), - )) + ) })?) .into(), false, ), KEYWORD_DEBUG => ( (self.debug)(result.as_str().map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), typ.into(), Position::none(), - )) + ) })?) .into(), false, @@ -276,56 +277,60 @@ impl Engine { // Getter function not found? if let Some(prop) = extract_prop_from_getter(fn_name) { - return Err(Box::new(EvalAltResult::ErrorDotExpr( + return EvalAltResult::ErrorDotExpr( format!( "Unknown property '{}' for {}, or it is write-only", prop, self.map_type_name(args[0].type_name()) ), Position::none(), - ))); + ) + .into(); } // Setter function not found? if let Some(prop) = extract_prop_from_setter(fn_name) { - return Err(Box::new(EvalAltResult::ErrorDotExpr( + return EvalAltResult::ErrorDotExpr( format!( "Unknown property '{}' for {}, or it is read-only", prop, self.map_type_name(args[0].type_name()) ), Position::none(), - ))); + ) + .into(); } // index getter function not found? #[cfg(not(feature = "no_index"))] if fn_name == FN_IDX_GET && args.len() == 2 { - return Err(Box::new(EvalAltResult::ErrorFunctionNotFound( + return EvalAltResult::ErrorFunctionNotFound( format!( "{} [{}]", self.map_type_name(args[0].type_name()), self.map_type_name(args[1].type_name()), ), Position::none(), - ))); + ) + .into(); } // index setter function not found? #[cfg(not(feature = "no_index"))] if fn_name == FN_IDX_SET { - return Err(Box::new(EvalAltResult::ErrorFunctionNotFound( + return EvalAltResult::ErrorFunctionNotFound( format!( "{} [{}]=", self.map_type_name(args[0].type_name()), self.map_type_name(args[1].type_name()), ), Position::none(), - ))); + ) + .into(); } // Raise error - Err(Box::new(EvalAltResult::ErrorFunctionNotFound( + EvalAltResult::ErrorFunctionNotFound( format!( "{} ({})", fn_name, @@ -339,7 +344,8 @@ impl Engine { .join(", ") ), Position::none(), - ))) + ) + .into() } /// Call a script-defined function. @@ -400,17 +406,15 @@ impl Engine { // Convert return statement to return value EvalAltResult::Return(x, _) => Ok(x), EvalAltResult::ErrorInFunctionCall(name, err, _) => { - Err(Box::new(EvalAltResult::ErrorInFunctionCall( + EvalAltResult::ErrorInFunctionCall( format!("{} > {}", fn_name, name), err, Position::none(), - ))) + ) + .into() } - _ => Err(Box::new(EvalAltResult::ErrorInFunctionCall( - fn_name.to_string(), - err, - Position::none(), - ))), + _ => EvalAltResult::ErrorInFunctionCall(fn_name.to_string(), err, Position::none()) + .into(), }); // Remove all local variables @@ -482,20 +486,22 @@ impl Engine { KEYWORD_FN_PTR if args.len() == 1 && !self.has_override(lib, hash_fn, hash_script, pub_only) => { - Err(Box::new(EvalAltResult::ErrorRuntime( + EvalAltResult::ErrorRuntime( "'Fn' should not be called in method style. Try Fn(...);".into(), Position::none(), - ))) + ) + .into() } // eval - reaching this point it must be a method-style call KEYWORD_EVAL if args.len() == 1 && !self.has_override(lib, hash_fn, hash_script, pub_only) => { - Err(Box::new(EvalAltResult::ErrorRuntime( + EvalAltResult::ErrorRuntime( "'eval' should not be called in method style. Try eval(...);".into(), Position::none(), - ))) + ) + .into() } // Normal script function call @@ -783,11 +789,12 @@ impl Engine { return arg_value .take_immutable_string() .map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), typ.into(), expr.position(), - )) + ) + .into() }) .and_then(|s| FnPtr::try_from(s)) .map(Into::::into) @@ -801,11 +808,12 @@ impl Engine { let fn_ptr = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?; if !fn_ptr.is::() { - return Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + return EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), self.map_type_name(fn_ptr.type_name()).into(), expr.position(), - ))); + ) + .into(); } let (fn_name, fn_curry) = fn_ptr.cast::().take_data(); @@ -855,11 +863,12 @@ impl Engine { // Recalculate hash hash_script = calc_fn_hash(empty(), name, curry.len() + args_expr.len(), empty()); } else { - return Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + return EvalAltResult::ErrorMismatchOutputType( self.map_type_name(type_name::()).into(), fn_name.type_name().into(), expr.position(), - ))); + ) + .into(); } } @@ -1048,7 +1057,7 @@ impl Engine { } Some(f) => f.get_native_fn()(self, lib, args.as_mut()), None if def_val.is_some() => Ok(def_val.unwrap().into()), - None => Err(Box::new(EvalAltResult::ErrorFunctionNotFound( + None => EvalAltResult::ErrorFunctionNotFound( format!( "{}{} ({})", modules, @@ -1063,7 +1072,8 @@ impl Engine { .join(", ") ), Position::none(), - ))), + ) + .into(), } } } diff --git a/src/fn_native.rs b/src/fn_native.rs index 149e720e..cc3ed0dc 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -175,10 +175,7 @@ impl TryFrom for FnPtr { if is_valid_identifier(value.chars()) { Ok(Self(value, Default::default())) } else { - Err(Box::new(EvalAltResult::ErrorFunctionNotFound( - value.into(), - Position::none(), - ))) + EvalAltResult::ErrorFunctionNotFound(value.into(), Position::none()).into() } } } diff --git a/src/module.rs b/src/module.rs index 57fe8eb5..b3bd5598 100644 --- a/src/module.rs +++ b/src/module.rs @@ -248,10 +248,7 @@ impl Module { hash_var: u64, ) -> Result<&mut Dynamic, Box> { self.all_variables.get_mut(&hash_var).ok_or_else(|| { - Box::new(EvalAltResult::ErrorVariableNotFound( - String::new(), - Position::none(), - )) + EvalAltResult::ErrorVariableNotFound(String::new(), Position::none()).into() }) } @@ -1517,7 +1514,7 @@ mod stat { self.0 .get(path) .cloned() - .ok_or_else(|| Box::new(EvalAltResult::ErrorModuleNotFound(path.into(), pos))) + .ok_or_else(|| EvalAltResult::ErrorModuleNotFound(path.into(), pos).into()) } } } @@ -1597,10 +1594,7 @@ mod collection { } } - Err(Box::new(EvalAltResult::ErrorModuleNotFound( - path.into(), - pos, - ))) + EvalAltResult::ErrorModuleNotFound(path.into(), pos).into() } } } diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index d8e256cc..f40f1d11 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -17,7 +17,6 @@ use num_traits::{ use num_traits::float::Float; use crate::stdlib::{ - boxed::Box, fmt::Display, format, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub}, @@ -26,28 +25,31 @@ use crate::stdlib::{ // Checked add pub fn add(x: T, y: T) -> FuncReturn { x.checked_add(&y).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Addition overflow: {} + {}", x, y), Position::none(), - )) + ) + .into() }) } // Checked subtract pub fn sub(x: T, y: T) -> FuncReturn { x.checked_sub(&y).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Subtraction underflow: {} - {}", x, y), Position::none(), - )) + ) + .into() }) } // Checked multiply pub fn mul(x: T, y: T) -> FuncReturn { x.checked_mul(&y).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Multiplication overflow: {} * {}", x, y), Position::none(), - )) + ) + .into() }) } // Checked divide @@ -57,26 +59,26 @@ where { // Detect division by zero if y == T::zero() { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Division by zero: {} / {}", x, y), Position::none(), - ))); + ) + .into(); } x.checked_div(&y).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Division overflow: {} / {}", x, y), Position::none(), - )) + ) + .into() }) } // Checked negative - e.g. -(i32::MIN) will overflow i32::MAX pub fn neg(x: T) -> FuncReturn { x.checked_neg().ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( - format!("Negation overflow: -{}", x), - Position::none(), - )) + EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none()) + .into() }) } // Checked absolute @@ -87,10 +89,8 @@ pub fn abs(x: T) -> FuncReturn { Ok(x) } else { x.checked_neg().ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( - format!("Negation overflow: -{}", x), - Position::none(), - )) + EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none()) + .into() }) } } @@ -140,34 +140,38 @@ fn binary_xor(x: T, y: T) -> FuncReturn<::Output> { pub fn shl(x: T, y: INT) -> FuncReturn { // Cannot shift by a negative number of bits if y < 0 { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Left-shift by a negative number: {} << {}", x, y), Position::none(), - ))); + ) + .into(); } CheckedShl::checked_shl(&x, y as u32).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Left-shift by too many bits: {} << {}", x, y), Position::none(), - )) + ) + .into() }) } // Checked right-shift pub fn shr(x: T, y: INT) -> FuncReturn { // Cannot shift by a negative number of bits if y < 0 { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Right-shift by a negative number: {} >> {}", x, y), Position::none(), - ))); + ) + .into(); } CheckedShr::checked_shr(&x, y as u32).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Right-shift by too many bits: {} % {}", x, y), Position::none(), - )) + ) + .into() }) } // Unchecked left-shift - may panic if shifting by a negative number of bits @@ -181,10 +185,11 @@ pub fn shr_u>(x: T, y: T) -> FuncReturn<>::Output> { // Checked modulo pub fn modulo(x: T, y: T) -> FuncReturn { x.checked_rem(&y).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Modulo division by zero or overflow: {} % {}", x, y), Position::none(), - )) + ) + .into() }) } // Unchecked modulo - may panic if dividing by zero @@ -195,35 +200,40 @@ fn modulo_u(x: T, y: T) -> FuncReturn<::Output> { pub fn pow_i_i(x: INT, y: INT) -> FuncReturn { if cfg!(not(feature = "only_i32")) { if y > (u32::MAX as INT) { - Err(Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Integer raised to too large an index: {} ~ {}", x, y), Position::none(), - ))) + ) + .into() } else if y < 0 { - Err(Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Integer raised to a negative index: {} ~ {}", x, y), Position::none(), - ))) + ) + .into() } else { x.checked_pow(y as u32).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Power overflow: {} ~ {}", x, y), Position::none(), - )) + ) + .into() }) } } else { if y < 0 { - Err(Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Integer raised to a negative index: {} ~ {}", x, y), Position::none(), - ))) + ) + .into() } else { x.checked_pow(y as u32).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( + EvalAltResult::ErrorArithmetic( format!("Power overflow: {} ~ {}", x, y), Position::none(), - )) + ) + .into() }) } } @@ -242,10 +252,11 @@ pub fn pow_f_f(x: FLOAT, y: FLOAT) -> FuncReturn { pub fn pow_f_i(x: FLOAT, y: INT) -> FuncReturn { // Raise to power that is larger than an i32 if y > (i32::MAX as INT) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Number raised to too large an index: {} ~ {}", x, y), Position::none(), - ))); + ) + .into(); } Ok(x.powi(y as i32)) diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 5574a4f5..fc6ca5ec 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -43,12 +43,13 @@ fn pad( && len > 0 && (len as usize) > _engine.limits.max_array_size { - return Err(Box::new(EvalAltResult::ErrorDataTooLarge( + return EvalAltResult::ErrorDataTooLarge( "Size of array".to_string(), _engine.limits.max_array_size, len as usize, Position::none(), - ))); + ) + .into(); } if len > 0 { diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index f8fd2d33..0818e8fe 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -12,7 +12,7 @@ use crate::{result::EvalAltResult, token::Position}; use num_traits::float::Float; #[cfg(not(feature = "no_float"))] -use crate::stdlib::{boxed::Box, format}; +use crate::stdlib::format; #[allow(dead_code)] #[cfg(feature = "only_i32")] @@ -109,10 +109,10 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, { "to_int", |x: f32| { if x > (MAX_INT as f32) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Integer overflow: to_int({})", x), Position::none(), - ))); + ).into(); } Ok(x.trunc() as INT) @@ -122,10 +122,10 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, { "to_int", |x: FLOAT| { if x > (MAX_INT as FLOAT) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Integer overflow: to_int({})", x), Position::none(), - ))); + ).into(); } Ok(x.trunc() as INT) diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index 149823c4..0b58c19d 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -231,12 +231,12 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str // Check if string will be over max size limit #[cfg(not(feature = "unchecked"))] if _engine.limits.max_string_size > 0 && len > 0 && (len as usize) > _engine.limits.max_string_size { - return Err(Box::new(EvalAltResult::ErrorDataTooLarge( + return EvalAltResult::ErrorDataTooLarge( "Length of string".to_string(), _engine.limits.max_string_size, len as usize, Position::none(), - ))); + ).into(); } if len > 0 { @@ -254,12 +254,12 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str #[cfg(not(feature = "unchecked"))] if _engine.limits.max_string_size > 0 && s.len() > _engine.limits.max_string_size { - return Err(Box::new(EvalAltResult::ErrorDataTooLarge( + return EvalAltResult::ErrorDataTooLarge( "Length of string".to_string(), _engine.limits.max_string_size, s.len(), Position::none(), - ))); + ).into(); } } } diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index d554b68e..34f6821d 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -41,13 +41,13 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { #[cfg(not(feature = "unchecked"))] if seconds > (MAX_INT as u64) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!( "Integer overflow for timestamp duration: {}", -(seconds as i64) ), Position::none(), - ))); + ).into(); } return Ok(-(seconds as INT)); @@ -62,10 +62,10 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { #[cfg(not(feature = "unchecked"))] if seconds > (MAX_INT as u64) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Integer overflow for timestamp duration: {}", seconds), Position::none(), - ))); + ).into(); } return Ok(seconds as INT); @@ -92,10 +92,10 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { #[cfg(not(feature = "unchecked"))] if seconds > (MAX_INT as u64) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( + return EvalAltResult::ErrorArithmetic( format!("Integer overflow for timestamp.elapsed: {}", seconds), Position::none(), - ))); + ).into(); } Ok(seconds as INT) diff --git a/src/result.rs b/src/result.rs index cecd14bd..40f2935c 100644 --- a/src/result.rs +++ b/src/result.rs @@ -361,3 +361,9 @@ impl EvalAltResult { self } } + +impl From for Result> { + fn from(err: EvalAltResult) -> Self { + Err(err.into()) + } +} diff --git a/src/serde/de.rs b/src/serde/de.rs index f6d328db..843c00d2 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -53,11 +53,12 @@ impl<'de> DynamicDeserializer<'de> { } /// Shortcut for a type conversion error. fn type_error_str(&self, error: &str) -> Result> { - Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( error.into(), self.value.type_name().into(), Position::none(), - ))) + ) + .into() } fn deserialize_int>( &mut self, @@ -134,10 +135,7 @@ pub fn from_dynamic<'de, T: Deserialize<'de>>( impl Error for Box { fn custom(err: T) -> Self { - Box::new(EvalAltResult::ErrorParsing( - ParseErrorType::BadInput(err.to_string()), - Position::none(), - )) + EvalAltResult::ErrorParsing(ParseErrorType::BadInput(err.to_string()), Position::none()) } } diff --git a/src/serde/ser.rs b/src/serde/ser.rs index c11c7f1c..1f0d153d 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -99,10 +99,7 @@ pub fn to_dynamic(value: T) -> Result> impl Error for Box { fn custom(err: T) -> Self { - Box::new(EvalAltResult::ErrorRuntime( - err.to_string(), - Position::none(), - )) + EvalAltResult::ErrorRuntime(err.to_string(), Position::none()) } } @@ -298,22 +295,24 @@ impl Serializer for &mut DynamicSerializer { make_variant(_variant, content) } #[cfg(feature = "no_object")] - return Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + return EvalAltResult::ErrorMismatchOutputType( "Dynamic".into(), "map".into(), Position::none(), - ))); + ) + .into(); } fn serialize_seq(self, _len: Option) -> Result> { #[cfg(not(feature = "no_index"))] return Ok(DynamicSerializer::new(Array::new().into())); #[cfg(feature = "no_index")] - return Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + return EvalAltResult::ErrorMismatchOutputType( "Dynamic".into(), "array".into(), Position::none(), - ))); + ) + .into(); } fn serialize_tuple(self, len: usize) -> Result> { @@ -346,11 +345,12 @@ impl Serializer for &mut DynamicSerializer { let err_type = "map"; #[cfg(not(feature = "no_object"))] let err_type = "array"; - Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( "Dynamic".into(), err_type.into(), Position::none(), - ))) + ) + .into() } } @@ -358,11 +358,12 @@ impl Serializer for &mut DynamicSerializer { #[cfg(not(feature = "no_object"))] return Ok(DynamicSerializer::new(Map::new().into())); #[cfg(feature = "no_object")] - return Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + return EvalAltResult::ErrorMismatchOutputType( "Dynamic".into(), "map".into(), Position::none(), - ))); + ) + .into(); } fn serialize_struct( @@ -386,11 +387,12 @@ impl Serializer for &mut DynamicSerializer { map: Map::with_capacity(_len), }); #[cfg(feature = "no_object")] - return Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + return EvalAltResult::ErrorMismatchOutputType( "Dynamic".into(), "map".into(), Position::none(), - ))); + ) + .into(); } } @@ -499,11 +501,11 @@ impl SerializeMap for DynamicSerializer { let key = mem::take(&mut self._key) .take_immutable_string() .map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( "string".into(), typ.into(), Position::none(), - )) + ) })?; let _value = _value.serialize(&mut *self)?; let map = self._value.downcast_mut::().unwrap(); @@ -523,11 +525,11 @@ impl SerializeMap for DynamicSerializer { { let _key: Dynamic = _key.serialize(&mut *self)?; let _key = _key.take_immutable_string().map_err(|typ| { - Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( "string".into(), typ.into(), Position::none(), - )) + ) })?; let _value = _value.serialize(&mut *self)?; let map = self._value.downcast_mut::().unwrap(); diff --git a/src/serde/str.rs b/src/serde/str.rs index 7fb1c9cc..8283cc79 100644 --- a/src/serde/str.rs +++ b/src/serde/str.rs @@ -20,11 +20,12 @@ impl<'a> ImmutableStringDeserializer<'a> { } /// Shortcut for a type conversion error. fn type_error(&self) -> Result> { - Err(Box::new(EvalAltResult::ErrorMismatchOutputType( + EvalAltResult::ErrorMismatchOutputType( type_name::().into(), "string".into(), Position::none(), - ))) + ) + .into() } }