2019-03-27 18:08:47 +00:00
|
|
|
use error::{EvalexprError, EvalexprResult};
|
2019-03-15 15:40:38 +00:00
|
|
|
|
2019-03-19 14:54:52 +00:00
|
|
|
mod display;
|
2019-03-27 15:38:59 +00:00
|
|
|
pub mod value_type;
|
2019-03-19 14:54:52 +00:00
|
|
|
|
2019-03-20 14:18:52 +00:00
|
|
|
/// The type used to represent integers in `Value::Int`.
|
2019-03-15 15:40:38 +00:00
|
|
|
pub type IntType = i64;
|
2019-03-20 14:18:52 +00:00
|
|
|
|
|
|
|
/// The type used to represent floats in `Value::Float`.
|
2019-03-15 15:40:38 +00:00
|
|
|
pub type FloatType = f64;
|
|
|
|
|
2019-03-20 14:39:27 +00:00
|
|
|
/// The type used to represent tuples in `Value::Tuple`.
|
|
|
|
pub type TupleType = Vec<Value>;
|
|
|
|
|
2019-03-28 08:56:30 +00:00
|
|
|
/// The type used to represent empty values in `Value::Empty`.
|
|
|
|
pub type EmptyType = ();
|
|
|
|
|
2019-03-28 09:22:04 +00:00
|
|
|
/// The value of the empty type to be used in rust.
|
|
|
|
pub const EMPTY_VALUE: () = ();
|
|
|
|
|
2019-03-19 18:30:59 +00:00
|
|
|
/// The value type used by the parser.
|
|
|
|
/// Values can be of different subtypes that are the variants of this enum.
|
2019-03-15 15:11:31 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub enum Value {
|
2019-03-19 18:30:59 +00:00
|
|
|
/// A string value.
|
2019-03-15 15:11:31 +00:00
|
|
|
String(String),
|
2019-03-19 18:30:59 +00:00
|
|
|
/// A float value.
|
2019-03-15 15:40:38 +00:00
|
|
|
Float(FloatType),
|
2019-03-19 18:30:59 +00:00
|
|
|
/// An integer value.
|
2019-03-15 15:40:38 +00:00
|
|
|
Int(IntType),
|
2019-03-19 18:30:59 +00:00
|
|
|
/// A boolean value.
|
2019-03-15 15:11:31 +00:00
|
|
|
Boolean(bool),
|
2019-03-19 18:30:59 +00:00
|
|
|
/// A tuple value.
|
2019-03-20 14:39:27 +00:00
|
|
|
Tuple(TupleType),
|
2019-03-28 08:56:30 +00:00
|
|
|
/// An empty value.
|
|
|
|
Empty,
|
2019-03-15 15:11:31 +00:00
|
|
|
}
|
2019-03-15 15:40:38 +00:00
|
|
|
|
|
|
|
impl Value {
|
2019-03-20 15:22:14 +00:00
|
|
|
/// Returns true if `self` is a `Value::String`.
|
|
|
|
pub fn is_string(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::String(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2019-03-19 18:30:59 +00:00
|
|
|
/// Returns true if `self` is a `Value::Int`.
|
2019-03-15 15:40:38 +00:00
|
|
|
pub fn is_int(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Int(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-19 18:30:59 +00:00
|
|
|
/// Returns true if `self` is a `Value::Float`.
|
2019-03-15 15:40:38 +00:00
|
|
|
pub fn is_float(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Float(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:45:33 +00:00
|
|
|
/// Returns true if `self` is a `Value::Int` or `Value::Float`.
|
|
|
|
pub fn is_number(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Int(_) | Value::Float(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-20 15:22:14 +00:00
|
|
|
/// Returns true if `self` is a `Value::Boolean`.
|
|
|
|
pub fn is_boolean(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Boolean(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if `self` is a `Value::Tuple`.
|
|
|
|
pub fn is_tuple(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Tuple(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-28 08:56:30 +00:00
|
|
|
/// Returns true if `self` is a `Value::Empty`.
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Empty => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-20 15:22:14 +00:00
|
|
|
/// Clones the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`.
|
2019-03-27 18:08:47 +00:00
|
|
|
pub fn as_string(&self) -> EvalexprResult<String> {
|
2019-03-20 15:22:14 +00:00
|
|
|
match self {
|
|
|
|
Value::String(string) => Ok(string.clone()),
|
2019-03-27 15:33:46 +00:00
|
|
|
value => Err(EvalexprError::expected_string(value.clone())),
|
2019-03-20 15:22:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Clones the value stored in `self` as `IntType`, or returns `Err` if `self` is not a `Value::Int`.
|
2019-03-27 18:08:47 +00:00
|
|
|
pub fn as_int(&self) -> EvalexprResult<IntType> {
|
2019-03-15 15:40:38 +00:00
|
|
|
match self {
|
|
|
|
Value::Int(i) => Ok(*i),
|
2019-03-27 15:33:46 +00:00
|
|
|
value => Err(EvalexprError::expected_int(value.clone())),
|
2019-03-15 15:40:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:45:33 +00:00
|
|
|
/// Clones the value stored in `self` as `FloatType`, or returns `Err` if `self` is not a `Value::Float`.
|
2019-03-27 18:08:47 +00:00
|
|
|
pub fn as_float(&self) -> EvalexprResult<FloatType> {
|
2019-03-27 17:45:33 +00:00
|
|
|
match self {
|
|
|
|
Value::Float(f) => Ok(*f),
|
|
|
|
value => Err(EvalexprError::expected_float(value.clone())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-20 15:22:14 +00:00
|
|
|
/// Clones the value stored in `self` as `FloatType`, or returns `Err` if `self` is not a `Value::Float` or `Value::Int`.
|
|
|
|
/// Note that this method silently converts `IntType` to `FloatType`, if `self` is a `Value::Int`.
|
2019-03-27 18:08:47 +00:00
|
|
|
pub fn as_number(&self) -> EvalexprResult<FloatType> {
|
2019-03-15 15:40:38 +00:00
|
|
|
match self {
|
|
|
|
Value::Float(f) => Ok(*f),
|
|
|
|
Value::Int(i) => Ok(*i as FloatType),
|
2019-03-27 15:33:46 +00:00
|
|
|
value => Err(EvalexprError::expected_number(value.clone())),
|
2019-03-15 15:40:38 +00:00
|
|
|
}
|
|
|
|
}
|
2019-03-20 15:22:14 +00:00
|
|
|
|
|
|
|
/// Clones the value stored in `self` as `bool`, or returns `Err` if `self` is not a `Value::Boolean`.
|
2019-03-27 18:08:47 +00:00
|
|
|
pub fn as_boolean(&self) -> EvalexprResult<bool> {
|
2019-03-20 15:22:14 +00:00
|
|
|
match self {
|
|
|
|
Value::Boolean(boolean) => Ok(*boolean),
|
2019-03-27 15:33:46 +00:00
|
|
|
value => Err(EvalexprError::expected_boolean(value.clone())),
|
2019-03-20 15:22:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-28 08:56:30 +00:00
|
|
|
/// Clones the value stored in `self` as `TupleType`, or returns`Err` if `self` is not a `Value::Tuple`.
|
2019-03-27 18:08:47 +00:00
|
|
|
pub fn as_tuple(&self) -> EvalexprResult<TupleType> {
|
2019-03-20 15:22:14 +00:00
|
|
|
match self {
|
|
|
|
Value::Tuple(tuple) => Ok(tuple.clone()),
|
2019-03-27 15:33:46 +00:00
|
|
|
value => Err(EvalexprError::expected_tuple(value.clone())),
|
2019-03-20 15:22:14 +00:00
|
|
|
}
|
|
|
|
}
|
2019-03-28 08:56:30 +00:00
|
|
|
|
|
|
|
/// 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())),
|
|
|
|
}
|
|
|
|
}
|
2019-03-15 15:40:38 +00:00
|
|
|
}
|
2019-03-19 10:01:06 +00:00
|
|
|
|
|
|
|
impl From<String> for Value {
|
|
|
|
fn from(string: String) -> Self {
|
|
|
|
Value::String(string)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&str> for Value {
|
|
|
|
fn from(string: &str) -> Self {
|
|
|
|
Value::String(string.to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<FloatType> for Value {
|
|
|
|
fn from(float: FloatType) -> Self {
|
|
|
|
Value::Float(float)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<IntType> for Value {
|
|
|
|
fn from(int: IntType) -> Self {
|
|
|
|
Value::Int(int)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<bool> for Value {
|
|
|
|
fn from(boolean: bool) -> Self {
|
|
|
|
Value::Boolean(boolean)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-20 14:39:27 +00:00
|
|
|
impl From<TupleType> for Value {
|
|
|
|
fn from(tuple: TupleType) -> Self {
|
2019-03-19 14:54:52 +00:00
|
|
|
Value::Tuple(tuple)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 18:08:47 +00:00
|
|
|
impl From<Value> for EvalexprResult<Value> {
|
2019-03-19 10:01:06 +00:00
|
|
|
fn from(value: Value) -> Self {
|
|
|
|
Ok(value)
|
|
|
|
}
|
2019-03-19 14:54:52 +00:00
|
|
|
}
|
2019-03-20 15:22:14 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use value::{TupleType, Value};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_value_conversions() {
|
|
|
|
assert_eq!(
|
2019-03-27 15:14:27 +00:00
|
|
|
Value::from("string").as_string(),
|
|
|
|
Ok(String::from("string"))
|
2019-03-20 15:22:14 +00:00
|
|
|
);
|
2019-03-27 15:14:27 +00:00
|
|
|
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));
|
2019-03-20 15:22:14 +00:00
|
|
|
assert_eq!(
|
2019-03-27 15:14:27 +00:00
|
|
|
Value::from(TupleType::new()).as_tuple(),
|
|
|
|
Ok(TupleType::new())
|
2019-03-20 15:22:14 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_value_checks() {
|
|
|
|
assert!(Value::from("string").is_string());
|
|
|
|
assert!(Value::from(3).is_int());
|
|
|
|
assert!(Value::from(3.3).is_float());
|
|
|
|
assert!(Value::from(true).is_boolean());
|
|
|
|
assert!(Value::from(TupleType::new()).is_tuple());
|
|
|
|
}
|
|
|
|
}
|