diff --git a/src/error/display.rs b/src/error/display.rs index 40b53f2..1d212b4 100644 --- a/src/error/display.rs +++ b/src/error/display.rs @@ -28,6 +28,7 @@ impl fmt::Display for EvalexprError { write!(f, "Expected a Value::Boolean, but got {:?}.", actual) }, ExpectedTuple { actual } => write!(f, "Expected a Value::Tuple, but got {:?}.", actual), + ExpectedEmpty { actual } => write!(f, "Expected a Value::Empty, but got {:?}.", actual), EmptyExpression => write!( f, "Got an empty expression that cannot be parsed into a node tree, because it \ diff --git a/src/error/mod.rs b/src/error/mod.rs index d96cd4d..ab28874 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -6,7 +6,7 @@ //! They are meant as shortcuts to not write the same error checking code everywhere. use token::PartialToken; -use value::{value_type::ValueType, TupleType}; +use value::{TupleType, value_type::ValueType}; use crate::value::Value; @@ -68,6 +68,12 @@ pub enum EvalexprError { actual: Value, }, + /// An empty value was expected. + ExpectedEmpty { + /// The actual value. + actual: Value, + }, + /// The given expression is empty EmptyExpression, @@ -178,36 +184,41 @@ impl EvalexprError { EvalexprError::TypeError { actual, expected } } - /// Constructs `Error::ExpectedString(actual)`. + /// Constructs `Error::ExpectedString{actual}`. pub fn expected_string(actual: Value) -> Self { EvalexprError::ExpectedString { actual } } - /// Constructs `Error::ExpectedInt(actual)`. + /// Constructs `Error::ExpectedInt{actual}`. pub fn expected_int(actual: Value) -> Self { EvalexprError::ExpectedInt { actual } } - /// Constructs `Error::ExpectedFloat(actual)`. + /// Constructs `Error::ExpectedFloat{actual}`. pub fn expected_float(actual: Value) -> Self { EvalexprError::ExpectedFloat { actual } } - /// Constructs `Error::ExpectedNumber(actual)`. + /// Constructs `Error::ExpectedNumber{actual}`. pub fn expected_number(actual: Value) -> Self { EvalexprError::ExpectedNumber { actual } } - /// Constructs `Error::ExpectedBoolean(actual)`. + /// Constructs `Error::ExpectedBoolean{actual}`. pub fn expected_boolean(actual: Value) -> Self { EvalexprError::ExpectedBoolean { actual } } - /// Constructs `Error::ExpectedTuple(actual)`. + /// Constructs `Error::ExpectedTuple{actual}`. pub fn expected_tuple(actual: Value) -> Self { EvalexprError::ExpectedTuple { actual } } + /// Constructs `Error::ExpectedEmpty{actual}`. + pub fn expected_empty(actual: Value) -> Self { + EvalexprError::ExpectedEmpty { actual } + } + /// Constructs an error that expresses that the type of `expected` was expected, but `actual` was found. pub(crate) fn expected_type(expected: &Value, actual: Value) -> Self { match ValueType::from(expected) { @@ -216,6 +227,7 @@ impl EvalexprError { ValueType::Float => Self::expected_float(actual), ValueType::Boolean => Self::expected_boolean(actual), ValueType::Tuple => Self::expected_tuple(actual), + ValueType::Empty => Self::expected_empty(actual), } } diff --git a/src/lib.rs b/src/lib.rs index 7220858..2ea1942 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -282,7 +282,7 @@ pub use error::{EvalexprError, EvalexprResult}; pub use function::Function; pub use interface::*; pub use tree::Node; -pub use value::{FloatType, IntType, TupleType, Value, value_type::ValueType}; +pub use value::{EmptyType, FloatType, IntType, TupleType, Value, value_type::ValueType}; mod context; pub mod error; diff --git a/src/value/display.rs b/src/value/display.rs index d8595f1..4e98d39 100644 --- a/src/value/display.rs +++ b/src/value/display.rs @@ -1,4 +1,5 @@ use std::fmt::{Display, Error, Formatter}; + use Value; impl Display for Value { @@ -21,6 +22,7 @@ impl Display for Value { } write!(f, ")") }, + Value::Empty => write!(f, "()"), } } } diff --git a/src/value/mod.rs b/src/value/mod.rs index 1de2200..bd2a72a 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -12,6 +12,9 @@ pub type FloatType = f64; /// The type used to represent tuples in `Value::Tuple`. pub type TupleType = Vec; +/// The type used to represent empty values in `Value::Empty`. +pub type EmptyType = (); + /// The value type used by the parser. /// Values can be of different subtypes that are the variants of this enum. #[derive(Clone, Debug, PartialEq)] @@ -26,6 +29,8 @@ pub enum Value { Boolean(bool), /// A tuple value. Tuple(TupleType), + /// An empty value. + Empty, } impl Value { @@ -76,6 +81,14 @@ impl Value { } } + /// Returns true if `self` is a `Value::Empty`. + pub fn is_empty(&self) -> bool { + match self { + Value::Empty => true, + _ => false, + } + } + /// Clones the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`. pub fn as_string(&self) -> EvalexprResult { match self { @@ -118,13 +131,21 @@ impl Value { } } - /// Clones the value stored in `self` as `TupleType`, or returns`Err` if `self` is not a `Value::Tuple`. + /// Clones the value stored in `self` as `TupleType`, or returns`Err` if `self` is not a `Value::Tuple`. pub fn as_tuple(&self) -> EvalexprResult { match self { Value::Tuple(tuple) => Ok(tuple.clone()), value => Err(EvalexprError::expected_tuple(value.clone())), } } + + /// Returns `()`, or returns`Err` if `self` is not a `Value::Tuple`. + pub fn as_empty(&self) -> EvalexprResult<()> { + match self { + Value::Empty => Ok(()), + value => Err(EvalexprError::expected_empty(value.clone())), + } + } } impl From for Value { diff --git a/src/value/value_type.rs b/src/value/value_type.rs index 8c5081c..997b09e 100644 --- a/src/value/value_type.rs +++ b/src/value/value_type.rs @@ -13,6 +13,8 @@ pub enum ValueType { Boolean, /// The `Value::Tuple` type. Tuple, + /// The `Value::Empty` type. + Empty, } impl From<&Value> for ValueType { @@ -23,6 +25,7 @@ impl From<&Value> for ValueType { Value::Int(_) => ValueType::Int, Value::Boolean(_) => ValueType::Boolean, Value::Tuple(_) => ValueType::Tuple, + Value::Empty => ValueType::Empty, } } }