Add Value::Empty and ValueType::Empty

Relates to #28
This commit is contained in:
Sebastian Schmidt 2019-03-28 09:56:30 +01:00
parent 3c108d5960
commit 88ab1e1987
6 changed files with 48 additions and 9 deletions

View File

@ -28,6 +28,7 @@ impl fmt::Display for EvalexprError {
write!(f, "Expected a Value::Boolean, but got {:?}.", actual) write!(f, "Expected a Value::Boolean, but got {:?}.", actual)
}, },
ExpectedTuple { actual } => write!(f, "Expected a Value::Tuple, 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!( EmptyExpression => write!(
f, f,
"Got an empty expression that cannot be parsed into a node tree, because it \ "Got an empty expression that cannot be parsed into a node tree, because it \

View File

@ -6,7 +6,7 @@
//! They are meant as shortcuts to not write the same error checking code everywhere. //! They are meant as shortcuts to not write the same error checking code everywhere.
use token::PartialToken; use token::PartialToken;
use value::{value_type::ValueType, TupleType}; use value::{TupleType, value_type::ValueType};
use crate::value::Value; use crate::value::Value;
@ -68,6 +68,12 @@ pub enum EvalexprError {
actual: Value, actual: Value,
}, },
/// An empty value was expected.
ExpectedEmpty {
/// The actual value.
actual: Value,
},
/// The given expression is empty /// The given expression is empty
EmptyExpression, EmptyExpression,
@ -178,36 +184,41 @@ impl EvalexprError {
EvalexprError::TypeError { actual, expected } EvalexprError::TypeError { actual, expected }
} }
/// Constructs `Error::ExpectedString(actual)`. /// Constructs `Error::ExpectedString{actual}`.
pub fn expected_string(actual: Value) -> Self { pub fn expected_string(actual: Value) -> Self {
EvalexprError::ExpectedString { actual } EvalexprError::ExpectedString { actual }
} }
/// Constructs `Error::ExpectedInt(actual)`. /// Constructs `Error::ExpectedInt{actual}`.
pub fn expected_int(actual: Value) -> Self { pub fn expected_int(actual: Value) -> Self {
EvalexprError::ExpectedInt { actual } EvalexprError::ExpectedInt { actual }
} }
/// Constructs `Error::ExpectedFloat(actual)`. /// Constructs `Error::ExpectedFloat{actual}`.
pub fn expected_float(actual: Value) -> Self { pub fn expected_float(actual: Value) -> Self {
EvalexprError::ExpectedFloat { actual } EvalexprError::ExpectedFloat { actual }
} }
/// Constructs `Error::ExpectedNumber(actual)`. /// Constructs `Error::ExpectedNumber{actual}`.
pub fn expected_number(actual: Value) -> Self { pub fn expected_number(actual: Value) -> Self {
EvalexprError::ExpectedNumber { actual } EvalexprError::ExpectedNumber { actual }
} }
/// Constructs `Error::ExpectedBoolean(actual)`. /// Constructs `Error::ExpectedBoolean{actual}`.
pub fn expected_boolean(actual: Value) -> Self { pub fn expected_boolean(actual: Value) -> Self {
EvalexprError::ExpectedBoolean { actual } EvalexprError::ExpectedBoolean { actual }
} }
/// Constructs `Error::ExpectedTuple(actual)`. /// Constructs `Error::ExpectedTuple{actual}`.
pub fn expected_tuple(actual: Value) -> Self { pub fn expected_tuple(actual: Value) -> Self {
EvalexprError::ExpectedTuple { actual } 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. /// 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 { pub(crate) fn expected_type(expected: &Value, actual: Value) -> Self {
match ValueType::from(expected) { match ValueType::from(expected) {
@ -216,6 +227,7 @@ impl EvalexprError {
ValueType::Float => Self::expected_float(actual), ValueType::Float => Self::expected_float(actual),
ValueType::Boolean => Self::expected_boolean(actual), ValueType::Boolean => Self::expected_boolean(actual),
ValueType::Tuple => Self::expected_tuple(actual), ValueType::Tuple => Self::expected_tuple(actual),
ValueType::Empty => Self::expected_empty(actual),
} }
} }

View File

@ -282,7 +282,7 @@ pub use error::{EvalexprError, EvalexprResult};
pub use function::Function; pub use function::Function;
pub use interface::*; pub use interface::*;
pub use tree::Node; 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; mod context;
pub mod error; pub mod error;

View File

@ -1,4 +1,5 @@
use std::fmt::{Display, Error, Formatter}; use std::fmt::{Display, Error, Formatter};
use Value; use Value;
impl Display for Value { impl Display for Value {
@ -21,6 +22,7 @@ impl Display for Value {
} }
write!(f, ")") write!(f, ")")
}, },
Value::Empty => write!(f, "()"),
} }
} }
} }

View File

@ -12,6 +12,9 @@ pub type FloatType = f64;
/// The type used to represent tuples in `Value::Tuple`. /// The type used to represent tuples in `Value::Tuple`.
pub type TupleType = Vec<Value>; pub type TupleType = Vec<Value>;
/// The type used to represent empty values in `Value::Empty`.
pub type EmptyType = ();
/// The value type used by the parser. /// The value type used by the parser.
/// Values can be of different subtypes that are the variants of this enum. /// Values can be of different subtypes that are the variants of this enum.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -26,6 +29,8 @@ pub enum Value {
Boolean(bool), Boolean(bool),
/// A tuple value. /// A tuple value.
Tuple(TupleType), Tuple(TupleType),
/// An empty value.
Empty,
} }
impl Value { 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`. /// Clones the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`.
pub fn as_string(&self) -> EvalexprResult<String> { pub fn as_string(&self) -> EvalexprResult<String> {
match self { 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<TupleType> { pub fn as_tuple(&self) -> EvalexprResult<TupleType> {
match self { match self {
Value::Tuple(tuple) => Ok(tuple.clone()), Value::Tuple(tuple) => Ok(tuple.clone()),
value => Err(EvalexprError::expected_tuple(value.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<String> for Value { impl From<String> for Value {

View File

@ -13,6 +13,8 @@ pub enum ValueType {
Boolean, Boolean,
/// The `Value::Tuple` type. /// The `Value::Tuple` type.
Tuple, Tuple,
/// The `Value::Empty` type.
Empty,
} }
impl From<&Value> for ValueType { impl From<&Value> for ValueType {
@ -23,6 +25,7 @@ impl From<&Value> for ValueType {
Value::Int(_) => ValueType::Int, Value::Int(_) => ValueType::Int,
Value::Boolean(_) => ValueType::Boolean, Value::Boolean(_) => ValueType::Boolean,
Value::Tuple(_) => ValueType::Tuple, Value::Tuple(_) => ValueType::Tuple,
Value::Empty => ValueType::Empty,
} }
} }
} }