1
2use crate::{Function, Functions, Value, to_value};
3use crate::math::Math;
4use crate::error::Error;
5
6
7pub struct BuiltIn {}
8
9impl BuiltIn {
10 pub fn new() -> Functions {
11 let mut functions = Functions::new();
12 functions.insert("min".to_owned(), create_min_fuction());
13 functions.insert("max".to_owned(), create_max_fuction());
14 functions.insert("len".to_owned(), create_len_fuction());
15 functions.insert("is_empty".to_owned(), create_is_empty_fuction());
16 functions.insert("array".to_owned(), create_array_function());
17 functions
18 }
19}
20
21#[derive(PartialEq)]
22enum Compare {
23 Min,
24 Max,
25}
26
27fn create_min_fuction() -> Function {
28 compare(Compare::Min)
29}
30
31fn create_max_fuction() -> Function {
32 compare(Compare::Max)
33}
34
35fn compare(compare: Compare) -> Function {
36 Function {
37 max_args: None,
38 min_args: Some(1),
39 compiled: Box::new(move |values| {
40 let mut prev: Result<Value, Error> = Err(Error::Custom("can't find min value."
41 .to_owned()));
42
43 for value in values {
44 match value {
45 Value::Array(array) => {
46 for value in array {
47 if prev.is_ok() {
48 if compare == Compare::Min {
49 if value.lt(prev.as_ref().unwrap())? == to_value(true) {
50 prev = Ok(value)
51 }
52 } else if value.gt(prev.as_ref().unwrap())? == to_value(true) {
53 prev = Ok(value)
54 }
55 } else {
56 prev = Ok(value);
57 }
58 }
59 }
60 _ => {
61 if prev.is_ok() {
62 if compare == Compare::Min {
63 if value.lt(prev.as_ref().unwrap())? == to_value(true) {
64 prev = Ok(value)
65 }
66 } else if value.gt(prev.as_ref().unwrap())? == to_value(true) {
67 prev = Ok(value)
68 }
69 } else {
70 prev = Ok(value);
71 }
72 }
73 }
74 }
75 prev
76 }),
77 }
78}
79
80
81fn create_is_empty_fuction() -> Function {
82 Function {
83 max_args: Some(1),
84 min_args: Some(1),
85 compiled: Box::new(|values| match *values.first().unwrap() {
86 Value::String(ref string) => Ok(to_value(string.is_empty())),
87 Value::Array(ref array) => Ok(to_value(array.is_empty())),
88 Value::Object(ref object) => Ok(to_value(object.is_empty())),
89 Value::Null => Ok(to_value(true)),
90 _ => Ok(to_value(false)),
91 }),
92 }
93}
94
95fn create_len_fuction() -> Function {
96 Function {
97 max_args: Some(1),
98 min_args: Some(1),
99 compiled: Box::new(|values| {
100 let value = values.first().unwrap();
101 match *value {
102 Value::String(ref string) => Ok(to_value(string.len())),
103 Value::Array(ref array) => Ok(to_value(array.len())),
104 Value::Object(ref object) => Ok(to_value(object.len())),
105 Value::Null => Ok(to_value(0)),
106 _ => {
107 Err(Error::Custom(format!("len() only accept string, array, object and \
108 null. But the given is: {:?}",
109 value)))
110 }
111 }
112 }),
113 }
114}
115
116fn create_array_function() -> Function {
117 Function::new(|values| Ok(to_value(values)))
118}