From 8a49bf9c112188b97762c47abd94297e124b3515 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 27 Mar 2019 16:14:27 +0100 Subject: [PATCH] Get rid of some unwraps Relates to #14 --- src/interface/mod.rs | 8 +++--- src/lib.rs | 15 ++++++----- src/operator/mod.rs | 61 +++++++++++++++++--------------------------- src/tree/mod.rs | 18 ++++++++----- src/value/mod.rs | 14 +++++----- 5 files changed, 54 insertions(+), 62 deletions(-) diff --git a/src/interface/mod.rs b/src/interface/mod.rs index bfe12da..f631c0b 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -1,13 +1,13 @@ -use token; -use tree; -use value::TupleType; use Configuration; use EmptyConfiguration; use Error; use FloatType; use IntType; use Node; +use token; +use tree; use Value; +use value::TupleType; /// Evaluate the given expression string. /// @@ -56,7 +56,7 @@ pub fn eval_with_configuration( /// ```rust /// use evalexpr::*; /// -/// let precomputed = build_operator_tree("one + two + three").unwrap(); +/// let precomputed = build_operator_tree("one + two + three").unwrap(); // Do proper error handling here /// /// let mut configuration = HashMapConfiguration::new(); /// configuration.insert_variable("one", 1); diff --git a/src/lib.rs b/src/lib.rs index 120c097..010204d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,7 +71,7 @@ //! ```rust //! use evalexpr::*; //! -//! let precompiled = build_operator_tree("a * b - c > 5").unwrap(); +//! let precompiled = build_operator_tree("a * b - c > 5").unwrap(); // Do proper error handling here //! //! let mut configuration = HashMapConfiguration::new(); //! configuration.insert_variable("a", 6); @@ -269,6 +269,13 @@ extern crate ron; #[cfg(feature = "serde")] extern crate serde; +pub use configuration::{Configuration, EmptyConfiguration, HashMapConfiguration}; +pub use error::Error; +pub use function::Function; +pub use interface::*; +pub use tree::Node; +pub use value::{FloatType, IntType, Value}; + mod configuration; pub mod error; #[cfg(feature = "serde")] @@ -282,9 +289,3 @@ mod value; // Exports -pub use configuration::{Configuration, EmptyConfiguration, HashMapConfiguration}; -pub use error::Error; -pub use function::Function; -pub use interface::*; -pub use tree::Node; -pub use value::{FloatType, IntType, Value}; diff --git a/src/operator/mod.rs b/src/operator/mod.rs index f92b703..cd77ab8 100644 --- a/src/operator/mod.rs +++ b/src/operator/mod.rs @@ -1,7 +1,9 @@ -use crate::{configuration::Configuration, error::*, value::Value}; -use function::builtin::builtin_function; use std::fmt::{Debug, Display}; +use function::builtin::builtin_function; + +use crate::{configuration::Configuration, error::*, value::Value}; + mod display; pub trait Operator: Debug + Display { @@ -140,11 +142,8 @@ impl Operator for Add { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - let result = arguments[0] - .as_int() - .unwrap() - .checked_add(arguments[1].as_int().unwrap()); + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + let result = a.checked_add(b); if let Some(result) = result { Ok(Value::Int(result)) } else { @@ -179,11 +178,8 @@ impl Operator for Sub { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - let result = arguments[0] - .as_int() - .unwrap() - .checked_sub(arguments[1].as_int().unwrap()); + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + let result = a.checked_sub(b); if let Some(result) = result { Ok(Value::Int(result)) } else { @@ -217,8 +213,8 @@ impl Operator for Neg { expect_operator_argument_amount(arguments.len(), 1)?; expect_number(&arguments[0])?; - if arguments[0].is_int() { - let result = arguments[0].as_int().unwrap().checked_neg(); + if let Ok(a) = arguments[0].as_int() { + let result = a.checked_neg(); if let Some(result) = result { Ok(Value::Int(result)) } else { @@ -248,11 +244,8 @@ impl Operator for Mul { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - let result = arguments[0] - .as_int() - .unwrap() - .checked_mul(arguments[1].as_int().unwrap()); + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + let result = a.checked_mul(b); if let Some(result) = result { Ok(Value::Int(result)) } else { @@ -287,11 +280,8 @@ impl Operator for Div { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - let result = arguments[0] - .as_int() - .unwrap() - .checked_div(arguments[1].as_int().unwrap()); + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + let result = a.checked_div(b); if let Some(result) = result { Ok(Value::Int(result)) } else { @@ -326,11 +316,8 @@ impl Operator for Mod { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - let result = arguments[0] - .as_int() - .unwrap() - .checked_rem(arguments[1].as_int().unwrap()); + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + let result = a.checked_rem(b); if let Some(result) = result { Ok(Value::Int(result)) } else { @@ -440,8 +427,8 @@ impl Operator for Gt { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - if arguments[0].as_int().unwrap() > arguments[1].as_int().unwrap() { + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + if a > b { Ok(Value::Boolean(true)) } else { Ok(Value::Boolean(false)) @@ -474,8 +461,8 @@ impl Operator for Lt { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - if arguments[0].as_int().unwrap() < arguments[1].as_int().unwrap() { + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + if a < b { Ok(Value::Boolean(true)) } else { Ok(Value::Boolean(false)) @@ -508,8 +495,8 @@ impl Operator for Geq { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - if arguments[0].as_int().unwrap() >= arguments[1].as_int().unwrap() { + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + if a >= b { Ok(Value::Boolean(true)) } else { Ok(Value::Boolean(false)) @@ -542,8 +529,8 @@ impl Operator for Leq { expect_number(&arguments[0])?; expect_number(&arguments[1])?; - if arguments[0].is_int() && arguments[1].is_int() { - if arguments[0].as_int().unwrap() <= arguments[1].as_int().unwrap() { + if let (Ok(a), Ok(b)) = (arguments[0].as_int(), arguments[1].as_int()) { + if a <= b { Ok(Value::Boolean(true)) } else { Ok(Value::Boolean(false)) diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 5c73845..441e820 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -20,7 +20,7 @@ mod display; /// /// let mut configuration = HashMapConfiguration::new(); /// configuration.insert_variable("alpha", 2); -/// let node = build_operator_tree("1 + alpha").unwrap(); +/// let node = build_operator_tree("1 + alpha").unwrap(); // Do proper error handling here /// assert_eq!(node.eval_with_configuration(&configuration), Ok(Value::from(3))); /// ``` /// @@ -290,14 +290,18 @@ pub(crate) fn tokens_to_operator_tree(tokens: Vec) -> Result if root.len() > 1 { Err(Error::UnmatchedLBrace) - } else if root.len() == 0 { - Err(Error::UnmatchedRBrace) - } else { - let mut root = root.pop().unwrap(); - if root.children().len() == 1 { - Ok(root.children.pop().unwrap()) + } else if let Some(mut root) = root.pop() { + if root.children().len() > 1 { + Err(Error::wrong_operator_argument_amount( + root.children().len(), + 1, + )) + } else if let Some(child) = root.children.pop() { + Ok(child) } else { Err(Error::EmptyExpression) } + } else { + Err(Error::UnmatchedRBrace) } } diff --git a/src/value/mod.rs b/src/value/mod.rs index 0c35624..5fb8392 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -159,15 +159,15 @@ mod tests { #[test] fn test_value_conversions() { assert_eq!( - Value::from("string").as_string().unwrap(), - String::from("string") + Value::from("string").as_string(), + Ok(String::from("string")) ); - assert_eq!(Value::from(3).as_int().unwrap(), 3); - assert_eq!(Value::from(3.3).as_float().unwrap(), 3.3); - assert_eq!(Value::from(true).as_boolean().unwrap(), true); + assert_eq!(Value::from(3).as_int(), Ok(3)); + assert_eq!(Value::from(3.3).as_float(), Ok(3.3)); + assert_eq!(Value::from(true).as_boolean(), Ok(true)); assert_eq!( - Value::from(TupleType::new()).as_tuple().unwrap(), - TupleType::new() + Value::from(TupleType::new()).as_tuple(), + Ok(TupleType::new()) ); }