• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gluesql / gluesql / 18519170559

15 Oct 2025 05:50AM UTC coverage: 97.964% (+0.02%) from 97.941%
18519170559

push

github

web-flow
Add JSON -> operator support  (#1807)

Adds Arrow operator (->): AST variant and SQL emission, translator mapping, evaluator dispatch, a new select function for Map/List, two new EvaluateError variants, duplicate Evaluated::arrow implementations, and new tests exercising arrow behavior.

52 of 59 new or added lines in 5 files covered. (88.14%)

38438 of 39237 relevant lines covered (97.96%)

72244.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.33
/core/src/executor/evaluate/function.rs
1
use {
2
    super::{EvaluateError, Evaluated},
3
    crate::{
4
        ast::DateTimeField,
5
        data::{Key, Point, Value},
6
        result::{Error, Result},
7
    },
8
    chrono::{Datelike, Duration, Months},
9
    md5::{Digest, Md5},
10
    rand::{Rng, SeedableRng, rngs::StdRng},
11
    std::{
12
        borrow::Cow,
13
        ops::ControlFlow::{self as StdControlFlow, Break, Continue},
14
    },
15
    uuid::Uuid,
16
};
17

18
type ControlFlow<T> = std::ops::ControlFlow<BreakCase, T>;
19

20
pub enum BreakCase {
21
    Null,
22
    Err(Error),
23
}
24

25
trait ContinueOrBreak<T> {
26
    fn continue_or_break(self, err: Error) -> ControlFlow<T>;
27
}
28

29
impl<T> ContinueOrBreak<T> for Option<T> {
30
    fn continue_or_break(self, err: Error) -> ControlFlow<T> {
98,770✔
31
        match self {
98,770✔
32
            Some(v) => Continue(v),
94,010✔
33
            None => Break(BreakCase::Err(err)),
4,760✔
34
        }
35
    }
98,770✔
36
}
37

38
trait BreakIfNull<T> {
39
    fn break_if_null(self) -> ControlFlow<T>;
40
}
41

42
impl<'a> BreakIfNull<Evaluated<'a>> for Result<Evaluated<'a>> {
43
    fn break_if_null(self) -> ControlFlow<Evaluated<'a>> {
9,520✔
44
        match self {
9,520✔
45
            Err(err) => Break(BreakCase::Err(err)),
×
46
            Ok(value) if value.is_null() => Break(BreakCase::Null),
9,520✔
47
            Ok(value) => Continue(value),
8,330✔
48
        }
49
    }
9,520✔
50
}
51

52
impl BreakIfNull<Value> for Result<Value> {
53
    fn break_if_null(self) -> ControlFlow<Value> {
1,227,319✔
54
        match self {
1,227,319✔
55
            Err(err) => Break(BreakCase::Err(err)),
×
56
            Ok(value) if value.is_null() => Break(BreakCase::Null),
1,227,319✔
57
            Ok(value) => Continue(value),
1,149,969✔
58
        }
59
    }
1,227,319✔
60
}
61

62
trait ControlFlowMap<T, U, F> {
63
    fn map(self, f: F) -> ControlFlow<U>
64
    where
65
        F: FnOnce(T) -> U;
66
}
67

68
impl<T, U, F> ControlFlowMap<T, U, F> for ControlFlow<T> {
69
    fn map(self, f: F) -> ControlFlow<U>
647,360✔
70
    where
647,360✔
71
        F: FnOnce(T) -> U,
647,360✔
72
    {
73
        match self {
647,360✔
74
            Continue(v) => Continue(f(v)),
553,350✔
75
            Break(v) => Break(v),
94,010✔
76
        }
77
    }
647,360✔
78
}
79

80
trait ControlFlowMapErr<T, F> {
81
    fn map_err(self, f: F) -> ControlFlow<T>
82
    where
83
        F: FnOnce(Error) -> Error;
84
}
85

86
impl<T, F> ControlFlowMapErr<T, F> for ControlFlow<T> {
87
    fn map_err(self, f: F) -> ControlFlow<T>
57,120✔
88
    where
57,120✔
89
        F: FnOnce(Error) -> Error,
57,120✔
90
    {
91
        match self {
4,760✔
92
            Continue(v) => Continue(v),
52,360✔
93
            Break(BreakCase::Null) => Break(BreakCase::Null),
3,570✔
94
            Break(BreakCase::Err(err)) => Break(BreakCase::Err(f(err))),
1,190✔
95
        }
96
    }
57,120✔
97
}
98

99
pub trait IntoControlFlow<T> {
100
    fn into_control_flow(self) -> ControlFlow<T>;
101
}
102

103
impl<T> IntoControlFlow<T> for Result<T> {
104
    fn into_control_flow(self) -> ControlFlow<T> {
338,388✔
105
        match self {
338,388✔
106
            Err(err) => Break(BreakCase::Err(err)),
77,350✔
107
            Ok(value) => Continue(value),
261,038✔
108
        }
109
    }
338,388✔
110
}
111

112
fn eval_to_str(name: &str, evaluated: Evaluated<'_>) -> ControlFlow<String> {
368,902✔
113
    match evaluated.try_into().break_if_null()? {
368,902✔
114
        Value::Str(value) => Continue(value),
330,822✔
115
        _ => Break(BreakCase::Err(
10,710✔
116
            EvaluateError::FunctionRequiresStringValue(name.to_owned()).into(),
10,710✔
117
        )),
10,710✔
118
    }
119
}
368,902✔
120

121
fn eval_to_int(name: &str, evaluated: Evaluated<'_>) -> ControlFlow<i64> {
254,660✔
122
    match evaluated.try_into().break_if_null()? {
254,660✔
123
        Value::I64(num) => Continue(num),
227,290✔
124
        _ => Break(BreakCase::Err(
16,660✔
125
            EvaluateError::FunctionRequiresIntegerValue(name.to_owned()).into(),
16,660✔
126
        )),
16,660✔
127
    }
128
}
254,660✔
129

130
fn eval_to_float(name: &str, evaluated: Evaluated<'_>) -> ControlFlow<f64> {
326,060✔
131
    match evaluated.try_into().break_if_null()? {
326,060✔
132
        Value::I64(v) => Continue(v as f64),
86,870✔
133
        Value::F32(v) => Continue(v.into()),
×
134
        Value::F64(v) => Continue(v),
157,080✔
135
        _ => Break(BreakCase::Err(
51,170✔
136
            EvaluateError::FunctionRequiresFloatValue(name.to_owned()).into(),
51,170✔
137
        )),
51,170✔
138
    }
139
}
326,060✔
140

141
fn eval_to_point(name: &str, evaluated: Evaluated<'_>) -> ControlFlow<Point> {
7,140✔
142
    match evaluated.try_into().break_if_null()? {
7,140✔
143
        Value::Point(v) => Continue(v),
4,760✔
144
        _ => Break(BreakCase::Err(
1,190✔
145
            EvaluateError::FunctionRequiresPointValue(name.to_owned()).into(),
1,190✔
146
        )),
1,190✔
147
    }
148
}
7,140✔
149

150
// --- text ---
151
pub fn concat(exprs: Vec<Evaluated<'_>>) -> ControlFlow<Evaluated<'_>> {
7,140✔
152
    let value = exprs
7,140✔
153
        .into_iter()
7,140✔
154
        .try_fold(None, |left: Option<Evaluated>, right| match left {
15,470✔
155
            None => Continue(Some(right)),
5,950✔
156
            Some(left) => left.concat(right).break_if_null().map(Some),
9,520✔
157
        })?;
15,470✔
158

159
    value.continue_or_break(EvaluateError::EmptyArgNotAllowedInConcat.into())
5,950✔
160
}
7,140✔
161

162
pub fn concat_ws<'a>(
9,520✔
163
    name: String,
9,520✔
164
    separator: Evaluated<'a>,
9,520✔
165
    exprs: Vec<Evaluated<'a>>,
9,520✔
166
) -> ControlFlow<Evaluated<'a>> {
9,520✔
167
    let separator = eval_to_str(&name, separator)?;
9,520✔
168

169
    let result = exprs
9,520✔
170
        .into_iter()
9,520✔
171
        .map(Value::try_from)
9,520✔
172
        .filter(|value| !matches!(value, Ok(Value::Null)))
29,750✔
173
        .map(|value| Ok(String::from(value?)))
27,370✔
174
        .collect::<Result<Vec<_>>>()
9,520✔
175
        .into_control_flow()?
9,520✔
176
        .join(&separator);
9,520✔
177

178
    Continue(Evaluated::Value(Value::Str(result)))
9,520✔
179
}
9,520✔
180

181
pub fn lower(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'_>> {
45,220✔
182
    eval_to_str(&name, expr)
45,220✔
183
        .map(|value| value.to_lowercase())
45,220✔
184
        .map(Value::Str)
45,220✔
185
        .map(Evaluated::Value)
45,220✔
186
}
45,220✔
187

188
pub fn initcap(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'_>> {
11,900✔
189
    let string = eval_to_str(&name, expr)?
11,900✔
190
        .chars()
7,140✔
191
        .scan(true, |state, c| {
42,840✔
192
            let c = if *state {
42,840✔
193
                c.to_ascii_uppercase()
21,420✔
194
            } else {
195
                c.to_ascii_lowercase()
21,420✔
196
            };
197
            *state = !c.is_alphanumeric();
42,840✔
198
            Some(c)
42,840✔
199
        })
42,840✔
200
        .collect();
7,140✔
201

202
    Continue(Evaluated::Value(Value::Str(string)))
7,140✔
203
}
11,900✔
204

205
pub fn upper(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'_>> {
28,560✔
206
    eval_to_str(&name, expr)
28,560✔
207
        .map(|value| value.to_uppercase())
28,560✔
208
        .map(Value::Str)
28,560✔
209
        .map(Evaluated::Value)
28,560✔
210
}
28,560✔
211

212
pub fn left_or_right<'a>(
24,990✔
213
    name: String,
24,990✔
214
    expr: Evaluated<'_>,
24,990✔
215
    size: Evaluated<'_>,
24,990✔
216
) -> ControlFlow<Evaluated<'a>> {
24,990✔
217
    let string = eval_to_str(&name, expr)?;
24,990✔
218
    let size = eval_to_int(&name, size)
21,420✔
219
        .map(usize::try_from)?
21,420✔
220
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.clone()).into())
19,040✔
221
        .into_control_flow()?;
19,040✔
222

223
    let converted = if name == "LEFT" {
17,850✔
224
        string.get(..size).map(|v| v.to_owned()).unwrap_or(string)
13,090✔
225
    } else {
226
        let start_pos = if size > string.len() {
4,760✔
227
            0
1,190✔
228
        } else {
229
            string.len() - size
3,570✔
230
        };
231

232
        string
4,760✔
233
            .get(start_pos..)
4,760✔
234
            .map(|value| value.to_owned())
4,760✔
235
            .unwrap_or(string)
4,760✔
236
    };
237

238
    Continue(Evaluated::Value(Value::Str(converted)))
17,850✔
239
}
24,990✔
240

241
pub fn lpad_or_rpad<'a>(
38,080✔
242
    name: String,
38,080✔
243
    expr: Evaluated<'_>,
38,080✔
244
    size: Evaluated<'_>,
38,080✔
245
    fill: Option<Evaluated<'_>>,
38,080✔
246
) -> ControlFlow<Evaluated<'a>> {
38,080✔
247
    let string = eval_to_str(&name, expr)?;
38,080✔
248
    let size = eval_to_int(&name, size)
30,940✔
249
        .map(usize::try_from)?
30,940✔
250
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.clone()).into())
26,180✔
251
        .into_control_flow()?;
26,180✔
252

253
    let fill = match fill {
23,800✔
254
        Some(expr) => eval_to_str(&name, expr)?,
11,900✔
255
        None => " ".to_owned(),
11,900✔
256
    };
257

258
    let result = if size > string.len() {
21,420✔
259
        let padding_size = size - string.len();
11,900✔
260
        let repeat_count = padding_size / fill.len();
11,900✔
261
        let plus_count = padding_size % fill.len();
11,900✔
262
        let fill = fill.repeat(repeat_count) + &fill[0..plus_count];
11,900✔
263

264
        if name == "LPAD" {
11,900✔
265
            fill + &string
7,140✔
266
        } else {
267
            string + &fill
4,760✔
268
        }
269
    } else {
270
        string[0..size].to_owned()
9,520✔
271
    };
272

273
    Continue(Evaluated::Value(Value::Str(result)))
21,420✔
274
}
38,080✔
275

276
pub fn reverse(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'_>> {
4,760✔
277
    let value = eval_to_str(&name, expr)?.chars().rev().collect::<String>();
4,760✔
278

279
    Continue(Evaluated::Value(Value::Str(value)))
2,380✔
280
}
4,760✔
281

282
pub fn repeat<'a>(
5,950✔
283
    name: String,
5,950✔
284
    expr: Evaluated<'_>,
5,950✔
285
    num: Evaluated<'_>,
5,950✔
286
) -> ControlFlow<Evaluated<'a>> {
5,950✔
287
    let expr = eval_to_str(&name, expr)?;
5,950✔
288
    let num = eval_to_int(&name, num)? as usize;
3,570✔
289
    let value = expr.repeat(num);
2,380✔
290

291
    Continue(Evaluated::Value(Value::Str(value)))
2,380✔
292
}
5,950✔
293

294
pub fn replace<'a>(
5,950✔
295
    name: String,
5,950✔
296
    expr: Evaluated<'_>,
5,950✔
297
    old: Evaluated<'_>,
5,950✔
298
    new: Evaluated<'_>,
5,950✔
299
) -> ControlFlow<Evaluated<'a>> {
5,950✔
300
    let expr = eval_to_str(&name, expr)?;
5,950✔
301
    let old = eval_to_str(&name, old)?;
3,570✔
302
    let new = eval_to_str(&name, new)?;
2,380✔
303
    let value = expr.replace(&old, &new);
2,380✔
304

305
    Continue(Evaluated::Value(Value::Str(value)))
2,380✔
306
}
5,950✔
307

308
pub fn ascii<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
29,750✔
309
    let string = eval_to_str(&name, expr)?;
29,750✔
310
    let mut iter = string.chars();
28,560✔
311

312
    match (iter.next(), iter.next()) {
28,560✔
313
        (Some(c), None) => {
21,420✔
314
            if c.is_ascii() {
21,420✔
315
                Continue(Evaluated::Value(Value::U8(c as u8)))
20,230✔
316
            } else {
317
                Err(EvaluateError::NonAsciiCharacterNotAllowed.into()).into_control_flow()
1,190✔
318
            }
319
        }
320
        _ => {
321
            Err(EvaluateError::AsciiFunctionRequiresSingleCharacterValue.into()).into_control_flow()
7,140✔
322
        }
323
    }
324
}
29,750✔
325

326
pub fn chr<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
23,800✔
327
    let expr = eval_to_int(&name, expr)?;
23,800✔
328

329
    match expr {
22,610✔
330
        0..=255 => {
22,610✔
331
            let expr = expr as u8;
19,040✔
332

333
            Continue(Evaluated::Value(Value::Str((expr as char).to_string())))
19,040✔
334
        }
335
        _ => Err(EvaluateError::ChrFunctionRequiresIntegerValueInRange0To255.into())
3,570✔
336
            .into_control_flow(),
3,570✔
337
    }
338
}
23,800✔
339

340
pub fn md5<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
3,570✔
341
    let string = eval_to_str(&name, expr)?;
3,570✔
342
    let mut hasher = Md5::new();
2,380✔
343
    hasher.update(string.as_bytes());
2,380✔
344
    let result = hasher.finalize();
2,380✔
345
    let result = format!("{result:x}");
2,380✔
346

347
    Continue(Evaluated::Value(Value::Str(result)))
2,380✔
348
}
3,570✔
349

350
pub fn hex<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
10,710✔
351
    match expr.try_into().break_if_null()? {
10,710✔
352
        Value::I64(number) => {
3,570✔
353
            let result = format!("{number:X}");
3,570✔
354
            Continue(Evaluated::Value(Value::Str(result)))
3,570✔
355
        }
356
        Value::Str(string) => {
4,760✔
357
            let result = string
4,760✔
358
                .as_bytes()
4,760✔
359
                .iter()
4,760✔
360
                .map(|b| format!("{b:02X}"))
20,230✔
361
                .collect::<String>();
4,760✔
362

363
            Continue(Evaluated::Value(Value::Str(result)))
4,760✔
364
        }
365
        _ => Break(BreakCase::Err(
1,190✔
366
            EvaluateError::FunctionRequiresIntegerOrStringValue(name).into(),
1,190✔
367
        )),
1,190✔
368
    }
369
}
10,710✔
370

371
// --- float ---
372

373
pub fn abs<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
28,560✔
374
    let value = match n.try_into().break_if_null()? {
28,560✔
375
        Value::I8(v) => Value::I8(v.abs()),
1,190✔
376
        Value::I32(v) => Value::I32(v.abs()),
×
377
        Value::I64(v) => Value::I64(v.abs()),
17,850✔
378
        Value::I128(v) => Value::I128(v.abs()),
×
379
        Value::Decimal(v) => Value::Decimal(v.abs()),
1,190✔
380
        Value::F32(v) => Value::F32(v.abs()),
×
381
        Value::F64(v) => Value::F64(v.abs()),
3,570✔
382
        _ => {
383
            return Err(EvaluateError::FunctionRequiresFloatValue(name).into()).into_control_flow();
3,570✔
384
        }
385
    };
386

387
    Continue(Evaluated::Value(value))
23,800✔
388
}
28,560✔
389

390
pub fn ifnull<'a>(expr: Evaluated<'a>, then: Evaluated<'a>) -> ControlFlow<Evaluated<'a>> {
34,510✔
391
    Continue(match expr.is_null() {
34,510✔
392
        true => then,
16,660✔
393
        false => expr,
17,850✔
394
    })
395
}
34,510✔
396

397
pub fn nullif<'a>(expr1: Evaluated<'a>, expr2: Evaluated<'a>) -> ControlFlow<Evaluated<'a>> {
7,140✔
398
    Continue(match expr1 == expr2 {
7,140✔
399
        true => Evaluated::Value(Value::Null),
3,570✔
400
        false => expr1,
3,570✔
401
    })
402
}
7,140✔
403

404
pub fn sign(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'_>> {
19,040✔
405
    let x = eval_to_float(&name, n)?;
19,040✔
406
    if x == 0.0 {
14,280✔
407
        return Continue(Evaluated::Value(Value::I8(0)));
7,140✔
408
    }
7,140✔
409

410
    Continue(Evaluated::Value(Value::I8(x.signum() as i8)))
7,140✔
411
}
19,040✔
412

413
pub fn sqrt<'a>(n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
7,140✔
414
    Value::try_from(n)
7,140✔
415
        .and_then(|v| v.sqrt())
7,140✔
416
        .into_control_flow()
7,140✔
417
        .map(Evaluated::Value)
7,140✔
418
}
7,140✔
419

420
pub fn power<'a>(
13,090✔
421
    name: String,
13,090✔
422
    expr: Evaluated<'_>,
13,090✔
423
    power: Evaluated<'_>,
13,090✔
424
) -> ControlFlow<Evaluated<'a>> {
13,090✔
425
    let expr = eval_to_float(&name, expr)?;
13,090✔
426
    let power = eval_to_float(&name, power)?;
8,330✔
427

428
    Continue(Evaluated::Value(Value::F64(expr.powf(power))))
5,950✔
429
}
13,090✔
430

431
pub fn ceil<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
19,040✔
432
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.ceil())))
19,040✔
433
}
19,040✔
434

435
pub fn rand<'a>(name: String, seed: Option<Evaluated<'_>>) -> ControlFlow<Evaluated<'a>> {
9,520✔
436
    let seed = if let Some(v) = seed {
9,520✔
437
        StdRng::seed_from_u64(eval_to_float(&name, v)? as u64).r#gen()
8,330✔
438
    } else {
439
        rand::random()
1,190✔
440
    };
441
    Continue(Evaluated::Value(Value::F64(seed)))
4,760✔
442
}
9,520✔
443

444
pub fn round<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
21,420✔
445
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.round())))
21,420✔
446
}
21,420✔
447

448
pub fn trunc<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
19,040✔
449
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.trunc())))
19,040✔
450
}
19,040✔
451

452
pub fn floor<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
19,040✔
453
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.floor())))
19,040✔
454
}
19,040✔
455

456
pub fn radians<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
21,420✔
457
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.to_radians())))
21,420✔
458
}
21,420✔
459

460
pub fn degrees<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
19,040✔
461
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.to_degrees())))
19,040✔
462
}
19,040✔
463

464
pub fn exp<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
465
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.exp())))
5,950✔
466
}
5,950✔
467

468
pub fn log<'a>(
8,330✔
469
    name: String,
8,330✔
470
    antilog: Evaluated<'_>,
8,330✔
471
    base: Evaluated<'_>,
8,330✔
472
) -> ControlFlow<Evaluated<'a>> {
8,330✔
473
    let antilog = eval_to_float(&name, antilog)?;
8,330✔
474
    let base = eval_to_float(&name, base)?;
5,950✔
475

476
    Continue(Evaluated::Value(Value::F64(antilog.log(base))))
3,570✔
477
}
8,330✔
478

479
pub fn ln<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
480
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.ln())))
5,950✔
481
}
5,950✔
482

483
pub fn log2<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
484
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.log2())))
5,950✔
485
}
5,950✔
486

487
pub fn log10<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
488
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.log10())))
5,950✔
489
}
5,950✔
490

491
pub fn sin<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
7,140✔
492
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.sin())))
7,140✔
493
}
7,140✔
494

495
pub fn cos<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
7,140✔
496
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.cos())))
7,140✔
497
}
7,140✔
498

499
pub fn tan<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
7,140✔
500
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.tan())))
7,140✔
501
}
7,140✔
502

503
pub fn asin<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
4,760✔
504
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.asin())))
4,760✔
505
}
4,760✔
506

507
pub fn acos<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
508
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.acos())))
5,950✔
509
}
5,950✔
510

511
pub fn atan<'a>(name: String, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
7,140✔
512
    eval_to_float(&name, n).map(|n| Evaluated::Value(Value::F64(n.atan())))
7,140✔
513
}
7,140✔
514

515
// --- integer ---
516

517
pub fn div<'a>(
29,750✔
518
    name: String,
29,750✔
519
    dividend: Evaluated<'_>,
29,750✔
520
    divisor: Evaluated<'_>,
29,750✔
521
) -> ControlFlow<Evaluated<'a>> {
29,750✔
522
    let dividend = eval_to_float(&name, dividend)
29,750✔
523
        .map_err(|_| EvaluateError::FunctionRequiresFloatOrIntegerValue(name.clone()).into())?;
29,750✔
524
    let divisor = eval_to_float(&name, divisor)
27,370✔
525
        .map_err(|_| EvaluateError::FunctionRequiresFloatOrIntegerValue(name.clone()).into())?;
27,370✔
526

527
    if divisor == 0.0 {
24,990✔
528
        return Err(EvaluateError::DivisorShouldNotBeZero.into()).into_control_flow();
2,380✔
529
    }
22,610✔
530

531
    Continue(Evaluated::Value(Value::I64((dividend / divisor) as i64)))
22,610✔
532
}
29,750✔
533

534
pub fn gcd<'a>(
27,370✔
535
    name: String,
27,370✔
536
    left: Evaluated<'_>,
27,370✔
537
    right: Evaluated<'_>,
27,370✔
538
) -> ControlFlow<Evaluated<'a>> {
27,370✔
539
    let left = eval_to_int(&name, left)?;
27,370✔
540
    let right = eval_to_int(&name, right)?;
23,800✔
541

542
    gcd_i64(left, right).map(|gcd| Evaluated::Value(Value::I64(gcd)))
21,420✔
543
}
27,370✔
544

545
pub fn lcm<'a>(
27,370✔
546
    name: String,
27,370✔
547
    left: Evaluated<'_>,
27,370✔
548
    right: Evaluated<'_>,
27,370✔
549
) -> ControlFlow<Evaluated<'a>> {
27,370✔
550
    let left = eval_to_int(&name, left)?;
27,370✔
551
    let right = eval_to_int(&name, right)?;
24,990✔
552

553
    fn lcm(a: i64, b: i64) -> ControlFlow<i64> {
22,610✔
554
        let gcd_val: i128 = gcd_i64(a, b)?.into();
22,610✔
555

556
        let a: i128 = a.into();
21,420✔
557
        let b: i128 = b.into();
21,420✔
558

559
        // lcm(a, b) = abs(a * b) / gcd(a, b)   if gcd(a, b) != 0
560
        // lcm(a, b) = 0                        if gcd(a, b) == 0
561
        let result = (a * b).abs().checked_div(gcd_val).unwrap_or(0);
21,420✔
562

563
        i64::try_from(result)
21,420✔
564
            .map_err(|_| EvaluateError::LcmResultOutOfRange.into())
21,420✔
565
            .into_control_flow()
21,420✔
566
    }
22,610✔
567

568
    lcm(left, right).map(|lcm| Evaluated::Value(Value::I64(lcm)))
22,610✔
569
}
27,370✔
570

571
fn gcd_i64(a: i64, b: i64) -> ControlFlow<i64> {
44,030✔
572
    let mut a = a
44,030✔
573
        .checked_abs()
44,030✔
574
        .continue_or_break(EvaluateError::GcdLcmOverflow(a).into())?;
44,030✔
575
    let mut b = b
41,650✔
576
        .checked_abs()
41,650✔
577
        .continue_or_break(EvaluateError::GcdLcmOverflow(b).into())?;
41,650✔
578

579
    while b > 0 {
124,950✔
580
        (a, b) = (b, a % b);
83,300✔
581
    }
83,300✔
582

583
    Continue(a)
41,650✔
584
}
44,030✔
585

586
// --- list ---
587
pub fn append<'a>(expr: Evaluated<'_>, value: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
4,760✔
588
    let expr = expr.try_into().break_if_null()?;
4,760✔
589
    let value = value.try_into().break_if_null()?;
4,760✔
590

591
    match (expr, value) {
4,760✔
592
        (Value::List(mut l), v) => {
3,570✔
593
            l.push(v);
3,570✔
594
            Continue(Evaluated::Value(Value::List(l)))
3,570✔
595
        }
596
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
597
    }
598
}
4,760✔
599

600
pub fn prepend<'a>(expr: Evaluated<'_>, value: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
4,760✔
601
    let expr = expr.try_into().break_if_null()?;
4,760✔
602
    let value = value.try_into().break_if_null()?;
4,760✔
603

604
    match (expr, value) {
4,760✔
605
        (Value::List(mut l), v) => {
3,570✔
606
            l.insert(0, v);
3,570✔
607
            Continue(Evaluated::Value(Value::List(l)))
3,570✔
608
        }
609
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
610
    }
611
}
4,760✔
612

613
pub fn skip<'a>(
8,330✔
614
    name: String,
8,330✔
615
    expr: Evaluated<'_>,
8,330✔
616
    size: Evaluated<'_>,
8,330✔
617
) -> ControlFlow<Evaluated<'a>> {
8,330✔
618
    let expr = expr.try_into().break_if_null()?;
8,330✔
619
    let size: usize = match size.try_into().break_if_null()? {
7,140✔
620
        Value::I64(number) => usize::try_from(number)
4,760✔
621
            .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name).into()),
4,760✔
622
        _ => Err(EvaluateError::FunctionRequiresIntegerValue(name).into()),
1,190✔
623
    }
624
    .into_control_flow()?;
5,950✔
625

626
    match expr {
3,570✔
627
        Value::List(l) => {
2,380✔
628
            let l = l.into_iter().skip(size).collect();
2,380✔
629
            Continue(Evaluated::Value(Value::List(l)))
2,380✔
630
        }
631
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
632
    }
633
}
8,330✔
634

635
pub fn sort<'a>(expr: Evaluated<'_>, order: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
11,900✔
636
    let expr = expr.try_into().break_if_null()?;
11,900✔
637
    let order = order.try_into().break_if_null()?;
11,900✔
638

639
    match expr {
11,900✔
640
        Value::List(l) => {
10,710✔
641
            let mut l: Vec<(Key, Value)> = l
10,710✔
642
                .into_iter()
10,710✔
643
                .map(|v| match Key::try_from(&v) {
38,080✔
644
                    Ok(key) => Ok((key, v)),
36,890✔
645
                    Err(_) => Err(EvaluateError::InvalidSortType.into()),
1,190✔
646
                })
38,080✔
647
                .collect::<Result<Vec<(Key, Value)>>>()
10,710✔
648
                .into_control_flow()?;
10,710✔
649

650
            let asc = match order {
9,520✔
651
                Value::Str(s) => match s.to_uppercase().as_str() {
8,330✔
652
                    "ASC" => true,
8,330✔
653
                    "DESC" => false,
3,570✔
654
                    _ => return Err(EvaluateError::InvalidSortOrder.into()).into_control_flow(),
1,190✔
655
                },
656
                _ => return Err(EvaluateError::InvalidSortOrder.into()).into_control_flow(),
1,190✔
657
            };
658

659
            l.sort_by(|a, b| if asc { a.0.cmp(&b.0) } else { b.0.cmp(&a.0) });
24,990✔
660

661
            Continue(Evaluated::Value(Value::List(
662
                l.into_iter().map(|(_, v)| v).collect(),
7,140✔
663
            )))
664
        }
665
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
666
    }
667
}
11,900✔
668

669
pub fn slice<'a>(
14,280✔
670
    name: String,
14,280✔
671
    expr: Evaluated<'_>,
14,280✔
672
    start: Evaluated<'_>,
14,280✔
673
    length: Evaluated<'_>,
14,280✔
674
) -> ControlFlow<Evaluated<'a>> {
14,280✔
675
    let expr = expr.try_into().break_if_null()?;
14,280✔
676
    let mut start = eval_to_int(&name, start)?;
14,280✔
677
    let length = eval_to_int(&name, length)
13,090✔
678
        .map(usize::try_from)?
13,090✔
679
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.clone()).into())
11,900✔
680
        .into_control_flow()?;
11,900✔
681

682
    match expr {
11,900✔
683
        Value::List(l) => {
10,710✔
684
            if start < 0 {
10,710✔
685
                start += l.len() as i64;
3,570✔
686
            }
7,140✔
687
            if start < 0 {
10,710✔
688
                start = 0;
1,190✔
689
            }
9,520✔
690

691
            let start_usize = start as usize;
10,710✔
692

693
            let l = l.into_iter().skip(start_usize).take(length).collect();
10,710✔
694
            Continue(Evaluated::Value(Value::List(l)))
10,710✔
695
        }
696
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
697
    }
698
}
14,280✔
699

700
pub fn take<'a>(
11,900✔
701
    name: String,
11,900✔
702
    expr: Evaluated<'_>,
11,900✔
703
    size: Evaluated<'_>,
11,900✔
704
) -> ControlFlow<Evaluated<'a>> {
11,900✔
705
    let expr = expr.try_into().break_if_null()?;
11,900✔
706
    let size = eval_to_int(&name, size)
10,710✔
707
        .map(usize::try_from)?
10,710✔
708
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.clone()).into())
8,330✔
709
        .into_control_flow()?;
8,330✔
710

711
    match expr {
7,140✔
712
        Value::List(l) => {
5,950✔
713
            let l = l.into_iter().take(size).collect();
5,950✔
714
            Continue(Evaluated::Value(Value::List(l)))
5,950✔
715
        }
716
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
717
    }
718
}
11,900✔
719

720
pub fn is_empty<'a>(expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
13,090✔
721
    let expr = expr.try_into().break_if_null()?;
13,090✔
722
    let length = match expr {
13,090✔
723
        Value::List(l) => l.len(),
5,950✔
724
        Value::Map(m) => m.len(),
5,950✔
725
        _ => {
726
            return Err(EvaluateError::MapOrListTypeRequired.into()).into_control_flow();
1,190✔
727
        }
728
    };
729

730
    Continue(Evaluated::Value(Value::Bool(length == 0)))
11,900✔
731
}
13,090✔
732

733
// --- etc ---
734

735
pub fn unwrap<'a>(
41,650✔
736
    name: String,
41,650✔
737
    expr: Evaluated<'a>,
41,650✔
738
    selector: Evaluated<'_>,
41,650✔
739
) -> ControlFlow<Evaluated<'a>> {
41,650✔
740
    let value = match expr {
39,270✔
741
        _ if expr.is_null() => return Continue(expr),
41,650✔
742
        Evaluated::Value(value) => value,
38,080✔
743
        _ => {
744
            return Err(EvaluateError::FunctionRequiresMapValue(name).into()).into_control_flow();
1,190✔
745
        }
746
    };
747
    let selector = eval_to_str(&name, selector)?;
38,080✔
748

749
    value
36,890✔
750
        .selector(&selector)
36,890✔
751
        .into_control_flow()
36,890✔
752
        .map(Evaluated::Value)
36,890✔
753
}
41,650✔
754

755
pub fn generate_uuid<'a>() -> Evaluated<'a> {
10,711✔
756
    Evaluated::Value(Value::Uuid(Uuid::new_v4().as_u128()))
10,711✔
757
}
10,711✔
758

759
pub fn greatest(name: String, exprs: Vec<Evaluated<'_>>) -> Result<Evaluated<'_>> {
9,520✔
760
    exprs
9,520✔
761
        .into_iter()
9,520✔
762
        .try_fold(None, |greatest, expr| -> Result<_> {
34,510✔
763
            let greatest = match greatest {
34,510✔
764
                Some(greatest) => greatest,
24,990✔
765
                None => return Ok(Some(expr)),
9,520✔
766
            };
767

768
            match greatest.evaluate_cmp(&expr) {
24,990✔
769
                Some(std::cmp::Ordering::Less) => Ok(Some(expr)),
11,900✔
770
                Some(_) => Ok(Some(greatest)),
9,520✔
771
                None => Err(EvaluateError::NonComparableArgumentError(name.to_owned()).into()),
3,570✔
772
            }
773
        })?
34,510✔
774
        .ok_or(EvaluateError::FunctionRequiresAtLeastOneArgument(name.to_owned()).into())
5,950✔
775
}
9,520✔
776

777
pub fn format<'a>(
23,800✔
778
    name: String,
23,800✔
779
    expr: Evaluated<'_>,
23,800✔
780
    format: Evaluated<'_>,
23,800✔
781
) -> ControlFlow<Evaluated<'a>> {
23,800✔
782
    match expr.try_into().break_if_null()? {
23,800✔
783
        Value::Date(expr) => eval_to_str(&name, format)
7,140✔
784
            .map(|format| chrono::NaiveDate::format(&expr, &format).to_string()),
7,140✔
785
        Value::Timestamp(expr) => eval_to_str(&name, format)
9,520✔
786
            .map(|format| chrono::NaiveDateTime::format(&expr, &format).to_string()),
9,520✔
787
        Value::Time(expr) => eval_to_str(&name, format)
5,950✔
788
            .map(|format| chrono::NaiveTime::format(&expr, &format).to_string()),
5,950✔
789
        value => Err(EvaluateError::UnsupportedExprForFormatFunction(value.into()).into())
1,190✔
790
            .into_control_flow(),
1,190✔
791
    }
792
    .map(Value::Str)
23,800✔
793
    .map(Evaluated::Value)
23,800✔
794
}
23,800✔
795

796
pub fn last_day<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
797
    let date = match expr.try_into().break_if_null()? {
5,950✔
798
        Value::Date(date) => date,
2,380✔
799
        Value::Timestamp(timestamp) => timestamp.date(),
2,380✔
800
        _ => {
801
            return Err(EvaluateError::FunctionRequiresDateOrDateTimeValue(name).into())
1,190✔
802
                .into_control_flow();
1,190✔
803
        }
804
    };
805

806
    Continue(Evaluated::Value(Value::Date(
4,760✔
807
        date + Months::new(1) - Duration::days(i64::from(date.day())),
4,760✔
808
    )))
4,760✔
809
}
5,950✔
810

811
pub fn to_date<'a>(
15,470✔
812
    name: String,
15,470✔
813
    expr: Evaluated<'_>,
15,470✔
814
    format: Evaluated<'_>,
15,470✔
815
) -> ControlFlow<Evaluated<'a>> {
15,470✔
816
    match expr.try_into().break_if_null()? {
15,470✔
817
        Value::Str(expr) => {
14,280✔
818
            let format = eval_to_str(&name, format)?;
14,280✔
819

820
            chrono::NaiveDate::parse_from_str(&expr, &format)
14,280✔
821
                .map(Value::Date)
14,280✔
822
                .map(Evaluated::Value)
14,280✔
823
                .map_err(|err| {
14,280✔
824
                    let err: EvaluateError = err.into();
1,190✔
825
                    err.into()
1,190✔
826
                })
1,190✔
827
        }
828
        _ => Err(EvaluateError::FunctionRequiresStringValue(name).into()),
1,190✔
829
    }
830
    .into_control_flow()
15,470✔
831
}
15,470✔
832

833
pub fn to_timestamp<'a>(
15,470✔
834
    name: String,
15,470✔
835
    expr: Evaluated<'_>,
15,470✔
836
    format: Evaluated<'_>,
15,470✔
837
) -> ControlFlow<Evaluated<'a>> {
15,470✔
838
    match expr.try_into().break_if_null()? {
15,470✔
839
        Value::Str(expr) => {
14,280✔
840
            let format = eval_to_str(&name, format)?;
14,280✔
841

842
            chrono::NaiveDateTime::parse_from_str(&expr, &format)
14,280✔
843
                .map(Value::Timestamp)
14,280✔
844
                .map(Evaluated::Value)
14,280✔
845
                .map_err(|err| {
14,280✔
846
                    let err: EvaluateError = err.into();
7,140✔
847
                    err.into()
7,140✔
848
                })
7,140✔
849
        }
850
        _ => Err(EvaluateError::FunctionRequiresStringValue(name).into()),
1,190✔
851
    }
852
    .into_control_flow()
15,470✔
853
}
15,470✔
854

855
pub fn add_month<'a>(
13,090✔
856
    name: String,
13,090✔
857
    expr: Evaluated<'_>,
13,090✔
858
    size: Evaluated<'_>,
13,090✔
859
) -> ControlFlow<Evaluated<'a>> {
13,090✔
860
    let size = eval_to_int(&name, size)?;
13,090✔
861
    let expr = eval_to_str(&name, expr)?;
11,900✔
862
    let expr = chrono::NaiveDate::parse_from_str(&expr, "%Y-%m-%d")
11,900✔
863
        .map_err(EvaluateError::from)
11,900✔
864
        .map_err(Error::from)
11,900✔
865
        .into_control_flow()?;
11,900✔
866
    let date = {
5,950✔
867
        let size_as_u32 = size
8,330✔
868
            .abs()
8,330✔
869
            .try_into()
8,330✔
870
            .map_err(|_| EvaluateError::I64ToU32ConversionFailure(name).into())
8,330✔
871
            .into_control_flow()?;
8,330✔
872
        let new_months = chrono::Months::new(size_as_u32);
7,140✔
873

874
        if size <= 0 {
7,140✔
875
            expr.checked_sub_months(new_months)
2,380✔
876
        } else {
877
            expr.checked_add_months(new_months)
4,760✔
878
        }
879
        .continue_or_break(EvaluateError::ChrFunctionRequiresIntegerValueInRange0To255.into())?
7,140✔
880
    };
881
    Continue(Evaluated::Value(Value::Date(date)))
5,950✔
882
}
13,090✔
883

884
pub fn to_time<'a>(
9,520✔
885
    name: String,
9,520✔
886
    expr: Evaluated<'_>,
9,520✔
887
    format: Evaluated<'_>,
9,520✔
888
) -> ControlFlow<Evaluated<'a>> {
9,520✔
889
    match expr.try_into().break_if_null()? {
9,520✔
890
        Value::Str(expr) => {
8,330✔
891
            let format = eval_to_str(&name, format)?;
8,330✔
892

893
            chrono::NaiveTime::parse_from_str(&expr, &format)
8,330✔
894
                .map(Value::Time)
8,330✔
895
                .map(Evaluated::Value)
8,330✔
896
                .map_err(|err| {
8,330✔
897
                    let err: EvaluateError = err.into();
1,190✔
898
                    err.into()
1,190✔
899
                })
1,190✔
900
        }
901
        _ => Err(EvaluateError::FunctionRequiresStringValue(name).into()),
1,190✔
902
    }
903
    .into_control_flow()
9,520✔
904
}
9,520✔
905

906
pub fn position<'a>(
7,141✔
907
    from_expr: Evaluated<'_>,
7,141✔
908
    sub_expr: Evaluated<'_>,
7,141✔
909
) -> ControlFlow<Evaluated<'a>> {
7,141✔
910
    let from: Value = from_expr.try_into().break_if_null()?;
7,141✔
911
    let sub = sub_expr.try_into().break_if_null()?;
7,141✔
912

913
    from.position(&sub)
5,951✔
914
        .map(Evaluated::Value)
5,951✔
915
        .into_control_flow()
5,951✔
916
}
7,141✔
917

918
pub fn find_idx<'a>(
16,661✔
919
    name: String,
16,661✔
920
    from: Evaluated<'a>,
16,661✔
921
    sub: Evaluated<'a>,
16,661✔
922
    start: Option<Evaluated<'a>>,
16,661✔
923
) -> ControlFlow<Evaluated<'a>> {
16,661✔
924
    let from_expr = eval_to_str(&name, from)?;
16,661✔
925
    let sub_expr = eval_to_str(&name, sub)?;
16,661✔
926

927
    match start {
14,281✔
928
        Some(start) => {
8,330✔
929
            let start = eval_to_int(&name, start)?;
8,330✔
930
            Value::find_idx(
7,140✔
931
                &Value::Str(from_expr),
7,140✔
932
                &Value::Str(sub_expr),
7,140✔
933
                &Value::I64(start),
7,140✔
934
            )
935
        }
936
        None => Value::position(&Value::Str(from_expr), &Value::Str(sub_expr)),
5,951✔
937
    }
938
    .map(Evaluated::Value)
13,091✔
939
    .into_control_flow()
13,091✔
940
}
16,661✔
941

942
pub fn extract<'a>(field: &DateTimeField, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
20,231✔
943
    Value::try_from(expr)
20,231✔
944
        .and_then(|v| v.extract(field))
20,231✔
945
        .map(Evaluated::Value)
20,231✔
946
        .into_control_flow()
20,231✔
947
}
20,231✔
948

949
pub fn point<'a>(name: String, x: Evaluated<'_>, y: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
11,900✔
950
    let x = eval_to_float(&name, x)?;
11,900✔
951
    let y = eval_to_float(&name, y)?;
11,900✔
952

953
    Continue(Evaluated::Value(Value::Point(Point::new(x, y))))
11,900✔
954
}
11,900✔
955

956
pub fn get_x<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
4,760✔
957
    match expr.try_into().break_if_null()? {
4,760✔
958
        Value::Point(v) => Ok(Evaluated::Value(Value::F64(v.x))),
3,570✔
959
        _ => Err(EvaluateError::FunctionRequiresPointValue(name).into()),
1,190✔
960
    }
961
    .into_control_flow()
4,760✔
962
}
4,760✔
963

964
pub fn get_y<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
4,760✔
965
    match expr.try_into().break_if_null()? {
4,760✔
966
        Value::Point(v) => Ok(Evaluated::Value(Value::F64(v.y))),
3,570✔
967
        _ => Err(EvaluateError::FunctionRequiresPointValue(name).into()),
1,190✔
968
    }
969
    .into_control_flow()
4,760✔
970
}
4,760✔
971

972
pub fn calc_distance<'a>(
3,570✔
973
    name: String,
3,570✔
974
    x: Evaluated<'_>,
3,570✔
975
    y: Evaluated<'_>,
3,570✔
976
) -> ControlFlow<Evaluated<'a>> {
3,570✔
977
    let x = eval_to_point(&name, x)?;
3,570✔
978
    let y = eval_to_point(&name, y)?;
3,570✔
979

980
    Continue(Evaluated::Value(Value::F64(Point::calc_distance(&x, &y))))
1,190✔
981
}
3,570✔
982

983
pub fn length<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
11,135✔
984
    match expr.try_into().break_if_null()? {
11,135✔
985
        Value::Str(expr) => Ok(Evaluated::Value(Value::U64(expr.chars().count() as u64))),
8,755✔
986
        Value::List(expr) => Ok(Evaluated::Value(Value::U64(expr.len() as u64))),
1,190✔
987
        Value::Map(expr) => Ok(Evaluated::Value(Value::U64(expr.len() as u64))),
1,190✔
988
        _ => Err(EvaluateError::FunctionRequiresStrOrListOrMapValue(name).into()),
×
989
    }
990
    .into_control_flow()
11,135✔
991
}
11,135✔
992

993
pub fn coalesce<'a>(exprs: Vec<Evaluated<'_>>) -> Result<Evaluated<'a>> {
53,550✔
994
    if exprs.is_empty() {
53,550✔
995
        return Err((EvaluateError::FunctionRequiresMoreArguments {
2,380✔
996
            function_name: "COALESCE".to_owned(),
2,380✔
997
            required_minimum: 1,
2,380✔
998
            found: exprs.len(),
2,380✔
999
        })
2,380✔
1000
        .into());
2,380✔
1001
    }
51,170✔
1002

1003
    let control_flow = exprs.into_iter().map(|expr| expr.try_into()).try_for_each(
97,580✔
1004
        |item: Result<Value>| match item {
97,580✔
1005
            Ok(value) if value.is_null() => StdControlFlow::Continue(()),
97,580✔
1006
            Ok(value) => StdControlFlow::Break(Ok(value)),
46,410✔
1007
            Err(err) => StdControlFlow::Break(Err(err)),
×
1008
        },
97,580✔
1009
    );
1010

1011
    match control_flow {
46,410✔
1012
        StdControlFlow::Break(Ok(value)) => Ok(Evaluated::Value(value)),
46,410✔
1013
        StdControlFlow::Break(Err(err)) => Err(err),
×
1014
        StdControlFlow::Continue(()) => Ok(Evaluated::Value(Value::Null)),
4,760✔
1015
    }
1016
}
53,550✔
1017

1018
pub fn entries<'a>(name: String, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
2,380✔
1019
    match expr.try_into().break_if_null()? {
2,380✔
1020
        Value::Map(expr) => {
1,190✔
1021
            let entries = expr
1,190✔
1022
                .into_iter()
1,190✔
1023
                .map(|(k, v)| Value::List(vec![Value::Str(k), v]))
1,190✔
1024
                .collect::<Vec<_>>();
1,190✔
1025
            Ok(Evaluated::Value(Value::List(entries)))
1,190✔
1026
        }
1027
        _ => Err(EvaluateError::FunctionRequiresMapValue(name).into()),
1,190✔
1028
    }
1029
    .into_control_flow()
2,380✔
1030
}
2,380✔
1031

1032
pub fn keys<'a>(expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
4,760✔
1033
    match expr.try_into().break_if_null()? {
4,760✔
1034
        Value::Map(m) => Ok(Evaluated::Value(Value::List(
3,570✔
1035
            m.into_keys().map(Value::Str).collect(),
3,570✔
1036
        ))),
3,570✔
1037
        _ => Err(EvaluateError::MapTypeRequired.into()),
1,190✔
1038
    }
1039
    .into_control_flow()
4,760✔
1040
}
4,760✔
1041

1042
pub fn values<'a>(expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
5,950✔
1043
    match expr.try_into().break_if_null()? {
5,950✔
1044
        Value::Map(m) => Ok(Evaluated::Value(Value::List(m.into_values().collect()))),
4,760✔
1045
        _ => Err(EvaluateError::MapTypeRequired.into()),
1,190✔
1046
    }
1047
    .into_control_flow()
5,950✔
1048
}
5,950✔
1049

1050
pub fn splice<'a>(
7,140✔
1051
    name: String,
7,140✔
1052
    list_data: Evaluated<'_>,
7,140✔
1053
    begin_index: Evaluated<'_>,
7,140✔
1054
    end_index: Evaluated<'_>,
7,140✔
1055
    values: Option<Evaluated<'_>>,
7,140✔
1056
) -> ControlFlow<Evaluated<'a>> {
7,140✔
1057
    let list_data = match list_data.try_into().break_if_null()? {
7,140✔
1058
        Value::List(list) => list,
5,950✔
1059
        _ => {
1060
            return Err(EvaluateError::ListTypeRequired.into()).into_control_flow();
1,190✔
1061
        }
1062
    };
1063

1064
    let begin_index = eval_to_int(&name, begin_index)?.max(0);
5,950✔
1065
    let begin_index = usize::try_from(begin_index)
5,950✔
1066
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.clone()).into())
5,950✔
1067
        .into_control_flow()?;
5,950✔
1068
    let end_index = eval_to_int(&name, end_index)?.max(0);
5,950✔
1069
    let end_index = usize::try_from(end_index)
5,950✔
1070
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.clone()).into())
5,950✔
1071
        .into_control_flow()?;
5,950✔
1072

1073
    let (left, right) = {
5,950✔
1074
        let mut list_iter = list_data.into_iter();
5,950✔
1075
        let left: Vec<_> = list_iter.by_ref().take(begin_index).collect();
5,950✔
1076
        let right: Vec<_> = list_iter.skip(end_index - begin_index).collect();
5,950✔
1077
        (left, right)
5,950✔
1078
    };
5,950✔
1079

1080
    let center = match values {
5,950✔
1081
        Some(values) => match values.try_into().break_if_null()? {
4,760✔
1082
            Value::List(list) => list,
3,570✔
1083
            _ => return Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
1084
        },
1085
        None => vec![],
1,190✔
1086
    };
1087

1088
    let result = {
4,760✔
1089
        let mut result = vec![];
4,760✔
1090
        result.extend(left);
4,760✔
1091
        result.extend(center);
4,760✔
1092
        result.extend(right);
4,760✔
1093
        result
4,760✔
1094
    };
1095

1096
    Continue(Evaluated::Value(Value::List(result)))
4,760✔
1097
}
7,140✔
1098

1099
pub fn dedup<'a>(list: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
3,570✔
1100
    match list.try_into().break_if_null()? {
3,570✔
1101
        Value::List(mut list) => {
2,380✔
1102
            list.dedup();
2,380✔
1103
            Continue(Evaluated::Value(Value::List(list)))
2,380✔
1104
        }
1105
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,190✔
1106
    }
1107
}
3,570✔
1108

1109
pub fn select_arrow_value(base: &Value, selector: &Value) -> Result<Value> {
48,790✔
1110
    if base.is_null() {
48,790✔
NEW
1111
        return Ok(Value::Null);
×
1112
    }
48,790✔
1113

1114
    match base {
48,790✔
1115
        Value::Map(map) => {
22,610✔
1116
            let key = match selector {
22,610✔
1117
                Value::Str(value) => Cow::Borrowed(value.as_str()),
7,140✔
1118
                Value::I8(value) => Cow::Owned(value.to_string()),
1,190✔
1119
                Value::I16(value) => Cow::Owned(value.to_string()),
2,380✔
1120
                Value::I32(value) => Cow::Owned(value.to_string()),
1,190✔
1121
                Value::I64(value) => Cow::Owned(value.to_string()),
2,380✔
1122
                Value::I128(value) => Cow::Owned(value.to_string()),
1,190✔
1123
                Value::U8(value) => Cow::Owned(value.to_string()),
1,190✔
1124
                Value::U16(value) => Cow::Owned(value.to_string()),
1,190✔
1125
                Value::U32(value) => Cow::Owned(value.to_string()),
1,190✔
1126
                Value::U64(value) => Cow::Owned(value.to_string()),
1,190✔
1127
                Value::U128(value) => Cow::Owned(value.to_string()),
1,190✔
1128
                _ => {
1129
                    return Err(EvaluateError::ArrowSelectorRequiresIntegerOrString(format!(
1,190✔
1130
                        "{selector:?}"
1,190✔
1131
                    ))
1,190✔
1132
                    .into());
1,190✔
1133
                }
1134
            };
1135

1136
            Ok(map.get(key.as_ref()).cloned().unwrap_or(Value::Null))
21,420✔
1137
        }
1138
        Value::List(list) => {
22,610✔
1139
            let index = match selector {
22,610✔
1140
                Value::Str(value) => value.parse::<usize>().ok(),
2,380✔
1141
                Value::I8(value) => usize::try_from(*value).ok(),
1,190✔
1142
                Value::I16(value) => usize::try_from(*value).ok(),
2,380✔
1143
                Value::I32(value) => usize::try_from(*value).ok(),
1,190✔
1144
                Value::I64(value) => usize::try_from(*value).ok(),
8,330✔
1145
                Value::I128(value) => usize::try_from(*value).ok(),
1,190✔
1146
                Value::U8(value) => Some(*value as usize),
1,190✔
1147
                Value::U16(value) => Some(*value as usize),
1,190✔
1148
                Value::U32(value) => usize::try_from(*value).ok(),
1,190✔
1149
                Value::U64(value) => usize::try_from(*value).ok(),
1,190✔
1150
                Value::U128(value) => usize::try_from(*value).ok(),
1,190✔
1151
                _ => {
NEW
1152
                    return Err(EvaluateError::ArrowSelectorRequiresIntegerOrString(format!(
×
NEW
1153
                        "{selector:?}?"
×
NEW
1154
                    ))
×
NEW
1155
                    .into());
×
1156
                }
1157
            };
1158

1159
            Ok(index
22,610✔
1160
                .and_then(|idx| list.get(idx).cloned())
22,610✔
1161
                .unwrap_or(Value::Null))
22,610✔
1162
        }
1163
        _ => Err(EvaluateError::ArrowBaseRequiresMapOrList.into()),
3,570✔
1164
    }
1165
}
48,790✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc