contains + contains_any builtins
This commit is contained in:
parent
76d480c465
commit
8b8af31eb8
@ -148,23 +148,59 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
|
||||
let result_index = if arguments[0].as_boolean()? { 1 } else { 2 };
|
||||
Ok(arguments.swap_remove(result_index))
|
||||
})),
|
||||
"some" => Some(Function::new(move |argument| {
|
||||
let arguments = argument.as_tuple()?;
|
||||
"contains" => Some(Function::new(move |argument| {
|
||||
let arguments = argument.as_fixed_len_tuple(2)?;
|
||||
if let (Value::Tuple(a), b) = (&arguments[0].clone(), &arguments[1].clone()) {
|
||||
if let Value::String(_) | Value::Int(_) | Value::Float(_) | Value::Boolean(_) = b {
|
||||
Ok(a.contains(b).into())
|
||||
} else {
|
||||
Err(EvalexprError::type_error(
|
||||
b.clone(),
|
||||
vec![
|
||||
ValueType::String,
|
||||
ValueType::Int,
|
||||
ValueType::Float,
|
||||
ValueType::Boolean,
|
||||
],
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(EvalexprError::expected_tuple(arguments[0].clone()))
|
||||
}
|
||||
})),
|
||||
"contains_any" => Some(Function::new(move |argument| {
|
||||
let arguments = argument.as_fixed_len_tuple(2)?;
|
||||
if let (Value::Tuple(a), b) = (&arguments[0].clone(), &arguments[1].clone()) {
|
||||
if let Value::Tuple(b) = b {
|
||||
for item in b {
|
||||
if a.contains(item) {
|
||||
return Ok(Value::Boolean(true));
|
||||
}
|
||||
let mut contains = false;
|
||||
for value in b {
|
||||
//if value is not String, Int, Bool, Float error it out
|
||||
if let Value::String(_)
|
||||
| Value::Int(_)
|
||||
| Value::Float(_)
|
||||
| Value::Boolean(_) = value
|
||||
{
|
||||
if a.contains(value) {
|
||||
contains = true;
|
||||
}
|
||||
} else {
|
||||
if a.contains(&b) {
|
||||
return Ok(Value::Boolean(true));
|
||||
return Err(EvalexprError::type_error(
|
||||
value.clone(),
|
||||
vec![
|
||||
ValueType::String,
|
||||
ValueType::Int,
|
||||
ValueType::Float,
|
||||
ValueType::Boolean,
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Value::Boolean(false))
|
||||
Ok(contains.into())
|
||||
} else {
|
||||
Ok(Value::Boolean(false))
|
||||
Err(EvalexprError::expected_tuple(b.clone()))
|
||||
}
|
||||
} else {
|
||||
Err(EvalexprError::expected_tuple(arguments[0].clone()))
|
||||
}
|
||||
})),
|
||||
"len" => Some(Function::new(|argument| {
|
||||
|
@ -328,7 +328,8 @@
|
||||
//! | `round` | 1 | Numeric | Returns the nearest integer to a number. Rounds half-way cases away from 0.0 |
|
||||
//! | `ceil` | 1 | Numeric | Returns the smallest integer greater than or equal to a number |
|
||||
//! | `if` | 3 | Boolean, Any, Any | If the first argument is true, returns the second argument, otherwise, returns the third |
|
||||
//! | `some` | 2 | Tuple, Any | Returns true if second argument exists in first argument(tuple). If second argument is tuple, checks if any exist in first argument. |
|
||||
//! | `contains` | 2 | Tuple, Any non Tuple | Returns true if second argument exists in first argument. |
|
||||
//! | `contains_any` | 2 | Tuple, Tuple of Any Non Tuple | Returns true if one of the values in the tuple of second argument exists in first argument(tuple). |
|
||||
//! | `typeof` | 1 | Any | returns "string", "float", "int", "boolean", "tuple", or "empty" depending on the type of the argument |
|
||||
//! | `math::is_nan` | 1 | Numeric | Returns true if the argument is the floating-point value NaN, false if it is another floating-point value, and throws an error if it is not a number |
|
||||
//! | `math::is_finite` | 1 | Numeric | Returns true if the argument is a finite floating-point number, false otherwise |
|
||||
|
@ -395,6 +395,93 @@ fn test_builtin_functions() {
|
||||
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(\"a\", \"b\")"), Ok(Value::Int(2)));
|
||||
//Contians
|
||||
assert_eq!(
|
||||
eval("contains(1, 2, 3)"),
|
||||
Err(EvalexprError::expected_fixed_len_tuple(
|
||||
2,
|
||||
Value::Tuple(vec![Value::Int(1), Value::Int(2), Value::Int(3)])
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains((\"foo\", \"bar\"), \"bar\")"),
|
||||
Ok(Value::Boolean(true))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains((\"foo\", \"bar\"), \"buzz\")"),
|
||||
Ok(Value::Boolean(false)),
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains(\"foo\", \"bar\")"),
|
||||
Err(EvalexprError::expected_tuple(Value::String("foo".into())))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains((\"foo\", \"bar\", 123), 123)"),
|
||||
Ok(Value::Boolean(true))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains((\"foo\", \"bar\"), (\"buzz\", \"bazz\"))"),
|
||||
Err(EvalexprError::type_error(
|
||||
Value::Tuple(vec![
|
||||
Value::String("buzz".into()),
|
||||
Value::String("bazz".into())
|
||||
]),
|
||||
vec![
|
||||
ValueType::String,
|
||||
ValueType::Int,
|
||||
ValueType::Float,
|
||||
ValueType::Boolean
|
||||
]
|
||||
))
|
||||
);
|
||||
//Contains Any
|
||||
assert_eq!(
|
||||
eval("contains_any(1, 2, 3)"),
|
||||
Err(EvalexprError::expected_fixed_len_tuple(
|
||||
2,
|
||||
Value::Tuple(vec![Value::Int(1), Value::Int(2), Value::Int(3)])
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((\"foo\", \"bar\"), (\"bar\", \"buzz\"))"),
|
||||
Ok(Value::Boolean(true))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((\"foo\", \"bar\"), (\"buzz\", \"bazz\"))"),
|
||||
Ok(Value::Boolean(false)),
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((1,2,3), (3,4,5))"),
|
||||
Ok(Value::Boolean(true))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((1,2,3), (4,5,6))"),
|
||||
Ok(Value::Boolean(false))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((true, false, true, true), (false, false, false))"),
|
||||
Ok(Value::Boolean(true))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any(\"foo\", \"bar\")"),
|
||||
Err(EvalexprError::expected_tuple(Value::String("foo".into())))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((\"foo\", \"bar\"), \"buzz\")"),
|
||||
Err(EvalexprError::expected_tuple(Value::String("buzz".into())))
|
||||
);
|
||||
assert_eq!(
|
||||
eval("contains_any((\"foo\", \"bar\"), (\"buzz\", (1, 2, 3)))"),
|
||||
Err(EvalexprError::type_error(
|
||||
Value::Tuple(vec![Value::Int(1), Value::Int(2), Value::Int(3)]),
|
||||
vec![
|
||||
ValueType::String,
|
||||
ValueType::Int,
|
||||
ValueType::Float,
|
||||
ValueType::Boolean
|
||||
]
|
||||
))
|
||||
);
|
||||
// String
|
||||
assert_eq!(
|
||||
eval("str::to_lowercase(\"FOOBAR\")"),
|
||||
|
Loading…
Reference in New Issue
Block a user