parent
15cdb3eb50
commit
b9c4b34a2f
@ -282,7 +282,7 @@ This crate offers a set of builtin functions.
|
|||||||
|------------|-----------------|----------------|-------------|
|
|------------|-----------------|----------------|-------------|
|
||||||
| `min` | >= 1 | Numeric | Returns the minimum of the arguments |
|
| `min` | >= 1 | Numeric | Returns the minimum of the arguments |
|
||||||
| `max` | >= 1 | Numeric | Returns the maximum of the arguments |
|
| `max` | >= 1 | Numeric | Returns the maximum of the arguments |
|
||||||
| `len` | 1 | String | Returns the character length of a string |
|
| `len` | 1 | String/Tuple | Returns the character length of a string, or the amount of elements in a tuple (not recursively) |
|
||||||
| `str::regex_matches` | 2 | String, String | Returns true if the first argument matches the regex in the second argument |
|
| `str::regex_matches` | 2 | String, String | Returns true if the first argument matches the regex in the second argument |
|
||||||
| `str::regex_replace` | 3 | String, String, String | Returns the first argument with all matches of the regex in the second argument replaced by the third argument |
|
| `str::regex_replace` | 3 | String, String, String | Returns the first argument with all matches of the regex in the second argument replaced by the third argument |
|
||||||
| `str::to_lowercase` | 1 | String | Returns the lower-case version of the string |
|
| `str::to_lowercase` | 1 | String | Returns the lower-case version of the string |
|
||||||
|
@ -5,10 +5,7 @@
|
|||||||
//! The module also contains some helper functions starting with `expect_` that check for a condition and return `Err(_)` if the condition is not fulfilled.
|
//! The module also contains some helper functions starting with `expect_` that check for a condition and return `Err(_)` if the condition is not fulfilled.
|
||||||
//! 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 crate::{
|
use crate::{token::PartialToken, value::value_type::ValueType};
|
||||||
token::PartialToken,
|
|
||||||
value::{value_type::ValueType, TupleType},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
@ -110,7 +107,7 @@ pub enum EvalexprError {
|
|||||||
/// Only use this if there is no other error that describes the expected and provided types in more detail.
|
/// Only use this if there is no other error that describes the expected and provided types in more detail.
|
||||||
TypeError {
|
TypeError {
|
||||||
/// The expected types.
|
/// The expected types.
|
||||||
expected: TupleType,
|
expected: Vec<ValueType>,
|
||||||
/// The actual value.
|
/// The actual value.
|
||||||
actual: Value,
|
actual: Value,
|
||||||
},
|
},
|
||||||
@ -205,7 +202,7 @@ impl EvalexprError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs `Error::TypeError{actual, expected}`.
|
/// Constructs `Error::TypeError{actual, expected}`.
|
||||||
pub fn type_error(actual: Value, expected: TupleType) -> Self {
|
pub fn type_error(actual: Value, expected: Vec<ValueType>) -> Self {
|
||||||
EvalexprError::TypeError { actual, expected }
|
EvalexprError::TypeError { actual, expected }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use regex::Regex;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
value::{FloatType, IntType},
|
value::{FloatType, IntType},
|
||||||
EvalexprError, Function, Value,
|
EvalexprError, Function, Value, ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn builtin_function(identifier: &str) -> Option<Function> {
|
pub fn builtin_function(identifier: &str) -> Option<Function> {
|
||||||
@ -54,8 +54,16 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
|
|||||||
}))),
|
}))),
|
||||||
|
|
||||||
"len" => Some(Function::new(Box::new(|argument| {
|
"len" => Some(Function::new(Box::new(|argument| {
|
||||||
let subject = argument.as_string()?;
|
if let Ok(subject) = argument.as_string() {
|
||||||
Ok(Value::from(subject.len() as i64))
|
Ok(Value::from(subject.len() as i64))
|
||||||
|
} else if let Ok(subject) = argument.as_tuple() {
|
||||||
|
Ok(Value::from(subject.len() as i64))
|
||||||
|
} else {
|
||||||
|
Err(EvalexprError::type_error(
|
||||||
|
argument.clone(),
|
||||||
|
vec![ValueType::String, ValueType::Tuple],
|
||||||
|
))
|
||||||
|
}
|
||||||
}))),
|
}))),
|
||||||
|
|
||||||
// string functions
|
// string functions
|
||||||
|
@ -269,7 +269,7 @@
|
|||||||
//! |------------|-----------------|----------------|-------------|
|
//! |------------|-----------------|----------------|-------------|
|
||||||
//! | `min` | >= 1 | Numeric | Returns the minimum of the arguments |
|
//! | `min` | >= 1 | Numeric | Returns the minimum of the arguments |
|
||||||
//! | `max` | >= 1 | Numeric | Returns the maximum of the arguments |
|
//! | `max` | >= 1 | Numeric | Returns the maximum of the arguments |
|
||||||
//! | `len` | 1 | String | Returns the character length of a string |
|
//! | `len` | 1 | String/Tuple | Returns the character length of a string, or the amount of elements in a tuple (not recursively) |
|
||||||
//! | `str::regex_matches` | 2 | String, String | Returns true if the first argument matches the regex in the second argument |
|
//! | `str::regex_matches` | 2 | String, String | Returns true if the first argument matches the regex in the second argument |
|
||||||
//! | `str::regex_replace` | 3 | String, String, String | Returns the first argument with all matches of the regex in the second argument replaced by the third argument |
|
//! | `str::regex_replace` | 3 | String, String, String | Returns the first argument with all matches of the regex in the second argument replaced by the third argument |
|
||||||
//! | `str::to_lowercase` | 1 | String | Returns the lower-case version of the string |
|
//! | `str::to_lowercase` | 1 | String | Returns the lower-case version of the string |
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::Value;
|
use crate::Value;
|
||||||
|
|
||||||
/// The type of a `Value`.
|
/// The type of a `Value`.
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
pub enum ValueType {
|
pub enum ValueType {
|
||||||
/// The `Value::String` type.
|
/// The `Value::String` type.
|
||||||
String,
|
String,
|
||||||
|
@ -277,6 +277,7 @@ fn test_builtin_functions() {
|
|||||||
assert_eq!(eval("min(4.0, 3)"), Ok(Value::Int(3)));
|
assert_eq!(eval("min(4.0, 3)"), Ok(Value::Int(3)));
|
||||||
assert_eq!(eval("max(4.0, 3)"), Ok(Value::Float(4.0)));
|
assert_eq!(eval("max(4.0, 3)"), Ok(Value::Float(4.0)));
|
||||||
assert_eq!(eval("len(\"foobar\")"), Ok(Value::Int(6)));
|
assert_eq!(eval("len(\"foobar\")"), Ok(Value::Int(6)));
|
||||||
|
assert_eq!(eval("len(\"a\", \"b\")"), Ok(Value::Int(2)));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
eval("str::to_lowercase(\"FOOBAR\")"),
|
eval("str::to_lowercase(\"FOOBAR\")"),
|
||||||
Ok(Value::from("foobar"))
|
Ok(Value::from("foobar"))
|
||||||
|
@ -27,4 +27,4 @@ fn test_regex_functions() {
|
|||||||
eval("str::regex_replace(\"foobar\", \".*?(i+)\", \"b$1\")"),
|
eval("str::regex_replace(\"foobar\", \".*?(i+)\", \"b$1\")"),
|
||||||
Ok(Value::String("foobar".to_owned()))
|
Ok(Value::String("foobar".to_owned()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user