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

gluesql / gluesql / 19022945282

03 Nov 2025 03:23AM UTC coverage: 97.993%. Remained the same
19022945282

push

github

web-flow
Apply clippy::needless_pass_by_value clippy rule (#1837)

This pull request applies `clippy::needless_pass_by_value1`
Most changes convert parameter types to references when the value is not consumed in the body, but I made `ShowOption` in `cli/src/command.rs` implement `Copy` (and `Clone`) because the type's size seemed small enough to be a copy rather than a reference.

Co-authored-by: Claude <noreply@anthropic.com>

435 of 438 new or added lines in 36 files covered. (99.32%)

39493 of 40302 relevant lines covered (97.99%)

73243.33 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> {
101,094✔
31
        match self {
101,094✔
32
            Some(v) => Continue(v),
96,222✔
33
            None => Break(BreakCase::Err(err)),
4,872✔
34
        }
35
    }
101,094✔
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,744✔
44
        match self {
9,744✔
45
            Err(err) => Break(BreakCase::Err(err)),
×
46
            Ok(value) if value.is_null() => Break(BreakCase::Null),
9,744✔
47
            Ok(value) => Continue(value),
8,526✔
48
        }
49
    }
9,744✔
50
}
51

52
impl BreakIfNull<Value> for Result<Value> {
53
    fn break_if_null(self) -> ControlFlow<Value> {
1,256,197✔
54
        match self {
1,256,197✔
55
            Err(err) => Break(BreakCase::Err(err)),
×
56
            Ok(value) if value.is_null() => Break(BreakCase::Null),
1,256,197✔
57
            Ok(value) => Continue(value),
1,177,027✔
58
        }
59
    }
1,256,197✔
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>
662,592✔
70
    where
662,592✔
71
        F: FnOnce(T) -> U,
662,592✔
72
    {
73
        match self {
662,592✔
74
            Continue(v) => Continue(f(v)),
566,370✔
75
            Break(v) => Break(v),
96,222✔
76
        }
77
    }
662,592✔
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>
58,464✔
88
    where
58,464✔
89
        F: FnOnce(Error) -> Error,
58,464✔
90
    {
91
        match self {
4,872✔
92
            Continue(v) => Continue(v),
53,592✔
93
            Break(BreakCase::Null) => Break(BreakCase::Null),
3,654✔
94
            Break(BreakCase::Err(err)) => Break(BreakCase::Err(f(err))),
1,218✔
95
        }
96
    }
58,464✔
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> {
346,350✔
105
        match self {
346,350✔
106
            Err(err) => Break(BreakCase::Err(err)),
79,170✔
107
            Ok(value) => Continue(value),
267,180✔
108
        }
109
    }
346,350✔
110
}
111

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

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

130
fn eval_to_float(name: &str, evaluated: Evaluated<'_>) -> ControlFlow<f64> {
333,732✔
131
    match evaluated.try_into().break_if_null()? {
333,732✔
132
        Value::I64(v) => Continue(v as f64),
88,914✔
133
        Value::F32(v) => Continue(v.into()),
×
134
        Value::F64(v) => Continue(v),
160,776✔
135
        _ => Break(BreakCase::Err(
52,374✔
136
            EvaluateError::FunctionRequiresFloatValue(name.to_owned()).into(),
52,374✔
137
        )),
52,374✔
138
    }
139
}
333,732✔
140

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

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

159
    value.continue_or_break(EvaluateError::EmptyArgNotAllowedInConcat.into())
6,090✔
160
}
7,308✔
161

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

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

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

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

188
pub fn initcap<'a>(name: &str, expr: Evaluated<'a>) -> ControlFlow<Evaluated<'a>> {
12,180✔
189
    let string = eval_to_str(name, expr)?
12,180✔
190
        .chars()
7,308✔
191
        .scan(true, |state, c| {
43,848✔
192
            let c = if *state {
43,848✔
193
                c.to_ascii_uppercase()
21,924✔
194
            } else {
195
                c.to_ascii_lowercase()
21,924✔
196
            };
197
            *state = !c.is_alphanumeric();
43,848✔
198
            Some(c)
43,848✔
199
        })
43,848✔
200
        .collect();
7,308✔
201

202
    Continue(Evaluated::Value(Value::Str(string)))
7,308✔
203
}
12,180✔
204

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

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

223
    let converted = if name == "LEFT" {
18,270✔
224
        string.get(..size).map(|v| v.to_owned()).unwrap_or(string)
13,398✔
225
    } else {
226
        let start_pos = if size > string.len() {
4,872✔
227
            0
1,218✔
228
        } else {
229
            string.len() - size
3,654✔
230
        };
231

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

238
    Continue(Evaluated::Value(Value::Str(converted)))
18,270✔
239
}
25,578✔
240

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

253
    let fill = match fill {
24,360✔
254
        Some(expr) => eval_to_str(name, expr)?,
12,180✔
255
        None => " ".to_owned(),
12,180✔
256
    };
257

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

264
        if name == "LPAD" {
12,180✔
265
            fill + &string
7,308✔
266
        } else {
267
            string + &fill
4,872✔
268
        }
269
    } else {
270
        string[0..size].to_owned()
9,744✔
271
    };
272

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

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

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

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

291
    Continue(Evaluated::Value(Value::Str(value)))
2,436✔
292
}
6,090✔
293

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

305
    Continue(Evaluated::Value(Value::Str(value)))
2,436✔
306
}
6,090✔
307

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

312
    match (iter.next(), iter.next()) {
29,232✔
313
        (Some(c), None) => {
21,924✔
314
            if c.is_ascii() {
21,924✔
315
                Continue(Evaluated::Value(Value::U8(c as u8)))
20,706✔
316
            } else {
317
                Err(EvaluateError::NonAsciiCharacterNotAllowed.into()).into_control_flow()
1,218✔
318
            }
319
        }
320
        _ => {
321
            Err(EvaluateError::AsciiFunctionRequiresSingleCharacterValue.into()).into_control_flow()
7,308✔
322
        }
323
    }
324
}
30,450✔
325

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

329
    match expr {
23,142✔
330
        0..=255 => {
23,142✔
331
            let expr = expr as u8;
19,488✔
332

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

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

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

350
pub fn hex<'a>(name: &str, expr: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
10,962✔
351
    match expr.try_into().break_if_null()? {
10,962✔
352
        Value::I64(number) => {
3,654✔
353
            let result = format!("{number:X}");
3,654✔
354
            Continue(Evaluated::Value(Value::Str(result)))
3,654✔
355
        }
356
        Value::Str(string) => {
4,872✔
357
            use std::fmt::Write;
358

359
            let result = string.as_bytes().iter().fold(String::new(), |mut acc, b| {
20,706✔
360
                let _ = write!(acc, "{b:02X}");
20,706✔
361
                acc
20,706✔
362
            });
20,706✔
363

364
            Continue(Evaluated::Value(Value::Str(result)))
4,872✔
365
        }
366
        _ => Break(BreakCase::Err(
1,218✔
367
            EvaluateError::FunctionRequiresIntegerOrStringValue(name.to_owned()).into(),
1,218✔
368
        )),
1,218✔
369
    }
370
}
10,962✔
371

372
// --- float ---
373

374
pub fn abs<'a>(name: &str, n: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
29,232✔
375
    let value = match n.try_into().break_if_null()? {
29,232✔
376
        Value::I8(v) => Value::I8(v.abs()),
1,218✔
377
        Value::I32(v) => Value::I32(v.abs()),
×
378
        Value::I64(v) => Value::I64(v.abs()),
18,270✔
379
        Value::I128(v) => Value::I128(v.abs()),
×
380
        Value::Decimal(v) => Value::Decimal(v.abs()),
1,218✔
381
        Value::F32(v) => Value::F32(v.abs()),
×
382
        Value::F64(v) => Value::F64(v.abs()),
3,654✔
383
        _ => {
384
            return Err(EvaluateError::FunctionRequiresFloatValue(name.to_owned()).into())
3,654✔
385
                .into_control_flow();
3,654✔
386
        }
387
    };
388

389
    Continue(Evaluated::Value(value))
24,360✔
390
}
29,232✔
391

392
pub fn ifnull<'a>(expr: Evaluated<'a>, then: Evaluated<'a>) -> ControlFlow<Evaluated<'a>> {
35,322✔
393
    Continue(if expr.is_null() { then } else { expr })
35,322✔
394
}
35,322✔
395

396
pub fn nullif<'a>(expr1: Evaluated<'a>, expr2: &Evaluated<'a>) -> ControlFlow<Evaluated<'a>> {
7,308✔
397
    Continue(if &expr1 == expr2 {
7,308✔
398
        Evaluated::Value(Value::Null)
3,654✔
399
    } else {
400
        expr1
3,654✔
401
    })
402
}
7,308✔
403

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

515
// --- integer ---
516

517
pub fn div<'a>(
30,450✔
518
    name: &str,
30,450✔
519
    dividend: Evaluated<'_>,
30,450✔
520
    divisor: Evaluated<'_>,
30,450✔
521
) -> ControlFlow<Evaluated<'a>> {
30,450✔
522
    let dividend = eval_to_float(name, dividend)
30,450✔
523
        .map_err(|_| EvaluateError::FunctionRequiresFloatOrIntegerValue(name.to_owned()).into())?;
30,450✔
524
    let divisor = eval_to_float(name, divisor)
28,014✔
525
        .map_err(|_| EvaluateError::FunctionRequiresFloatOrIntegerValue(name.to_owned()).into())?;
28,014✔
526

527
    if divisor == 0.0 {
25,578✔
528
        return Err(EvaluateError::DivisorShouldNotBeZero.into()).into_control_flow();
2,436✔
529
    }
23,142✔
530

531
    Continue(Evaluated::Value(Value::I64((dividend / divisor) as i64)))
23,142✔
532
}
30,450✔
533

534
pub fn gcd<'a>(
28,014✔
535
    name: &str,
28,014✔
536
    left: Evaluated<'_>,
28,014✔
537
    right: Evaluated<'_>,
28,014✔
538
) -> ControlFlow<Evaluated<'a>> {
28,014✔
539
    let left = eval_to_int(name, left)?;
28,014✔
540
    let right = eval_to_int(name, right)?;
24,360✔
541

542
    gcd_i64(left, right).map(|gcd| Evaluated::Value(Value::I64(gcd)))
21,924✔
543
}
28,014✔
544

545
pub fn lcm<'a>(
28,014✔
546
    name: &str,
28,014✔
547
    left: Evaluated<'_>,
28,014✔
548
    right: Evaluated<'_>,
28,014✔
549
) -> ControlFlow<Evaluated<'a>> {
28,014✔
550
    fn lcm(a: i64, b: i64) -> ControlFlow<i64> {
23,142✔
551
        let gcd_val: i128 = gcd_i64(a, b)?.into();
23,142✔
552

553
        let a: i128 = a.into();
21,924✔
554
        let b: i128 = b.into();
21,924✔
555

556
        // lcm(a, b) = abs(a * b) / gcd(a, b)   if gcd(a, b) != 0
557
        // lcm(a, b) = 0                        if gcd(a, b) == 0
558
        let result = (a * b).abs().checked_div(gcd_val).unwrap_or(0);
21,924✔
559

560
        i64::try_from(result)
21,924✔
561
            .map_err(|_| EvaluateError::LcmResultOutOfRange.into())
21,924✔
562
            .into_control_flow()
21,924✔
563
    }
23,142✔
564

565
    let left = eval_to_int(name, left)?;
28,014✔
566
    let right = eval_to_int(name, right)?;
25,578✔
567

568
    lcm(left, right).map(|lcm| Evaluated::Value(Value::I64(lcm)))
23,142✔
569
}
28,014✔
570

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

579
    while b > 0 {
127,890✔
580
        (a, b) = (b, a % b);
85,260✔
581
    }
85,260✔
582

583
    Continue(a)
42,630✔
584
}
45,066✔
585

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

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

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

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

613
pub fn skip<'a>(
8,526✔
614
    name: &str,
8,526✔
615
    expr: Evaluated<'_>,
8,526✔
616
    size: Evaluated<'_>,
8,526✔
617
) -> ControlFlow<Evaluated<'a>> {
8,526✔
618
    let expr = expr.try_into().break_if_null()?;
8,526✔
619
    let size: usize = match size.try_into().break_if_null()? {
7,308✔
620
        Value::I64(number) => usize::try_from(number)
4,872✔
621
            .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.to_owned()).into()),
4,872✔
622
        _ => Err(EvaluateError::FunctionRequiresIntegerValue(name.to_owned()).into()),
1,218✔
623
    }
624
    .into_control_flow()?;
6,090✔
625

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

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

639
    match expr {
12,180✔
640
        Value::List(l) => {
10,962✔
641
            let mut l: Vec<(Key, Value)> = l
10,962✔
642
                .into_iter()
10,962✔
643
                .map(|v| match Key::try_from(&v) {
38,976✔
644
                    Ok(key) => Ok((key, v)),
37,758✔
645
                    Err(_) => Err(EvaluateError::InvalidSortType.into()),
1,218✔
646
                })
38,976✔
647
                .collect::<Result<Vec<(Key, Value)>>>()
10,962✔
648
                .into_control_flow()?;
10,962✔
649

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

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

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

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

682
    match expr {
12,180✔
683
        Value::List(l) => {
10,962✔
684
            if start < 0 {
10,962✔
685
                start += l.len() as i64;
3,654✔
686
            }
7,308✔
687
            if start < 0 {
10,962✔
688
                start = 0;
1,218✔
689
            }
9,744✔
690

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

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

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

711
    match expr {
7,308✔
712
        Value::List(l) => {
6,090✔
713
            let l = l.into_iter().take(size).collect();
6,090✔
714
            Continue(Evaluated::Value(Value::List(l)))
6,090✔
715
        }
716
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,218✔
717
    }
718
}
12,180✔
719

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

730
    Continue(Evaluated::Value(Value::Bool(length == 0)))
12,180✔
731
}
13,398✔
732

733
// --- etc ---
734

735
pub fn unwrap<'a>(
42,630✔
736
    name: &str,
42,630✔
737
    expr: Evaluated<'a>,
42,630✔
738
    selector: Evaluated<'_>,
42,630✔
739
) -> ControlFlow<Evaluated<'a>> {
42,630✔
740
    let value = match expr {
40,194✔
741
        _ if expr.is_null() => return Continue(expr),
42,630✔
742
        Evaluated::Value(value) => value,
38,976✔
743
        _ => {
744
            return Err(EvaluateError::FunctionRequiresMapValue(name.to_owned()).into())
1,218✔
745
                .into_control_flow();
1,218✔
746
        }
747
    };
748
    let selector = eval_to_str(name, selector)?;
38,976✔
749

750
    value
37,758✔
751
        .selector(&selector)
37,758✔
752
        .into_control_flow()
37,758✔
753
        .map(Evaluated::Value)
37,758✔
754
}
42,630✔
755

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

760
pub fn greatest<'a>(name: &str, exprs: Vec<Evaluated<'a>>) -> Result<Evaluated<'a>> {
9,744✔
761
    exprs
9,744✔
762
        .into_iter()
9,744✔
763
        .try_fold(None, |greatest, expr| -> Result<_> {
35,322✔
764
            let Some(greatest) = greatest else {
35,322✔
765
                return Ok(Some(expr));
9,744✔
766
            };
767

768
            match greatest.evaluate_cmp(&expr) {
25,578✔
769
                Some(std::cmp::Ordering::Less) => Ok(Some(expr)),
12,180✔
770
                Some(_) => Ok(Some(greatest)),
9,744✔
771
                None => Err(EvaluateError::NonComparableArgumentError(name.to_owned()).into()),
3,654✔
772
            }
773
        })?
35,322✔
774
        .ok_or(EvaluateError::FunctionRequiresAtLeastOneArgument(name.to_owned()).into())
6,090✔
775
}
9,744✔
776

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

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

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

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

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

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

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

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

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

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

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

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

913
    from.position(&sub)
6,091✔
914
        .map(Evaluated::Value)
6,091✔
915
        .into_control_flow()
6,091✔
916
}
7,309✔
917

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

927
    match start {
14,617✔
928
        Some(start) => {
8,526✔
929
            let start = eval_to_int(name, start)?;
8,526✔
930
            Value::find_idx(
7,308✔
931
                &Value::Str(from_expr),
7,308✔
932
                &Value::Str(sub_expr),
7,308✔
933
                &Value::I64(start),
7,308✔
934
            )
935
        }
936
        None => Value::position(&Value::Str(from_expr), &Value::Str(sub_expr)),
6,091✔
937
    }
938
    .map(Evaluated::Value)
13,399✔
939
    .into_control_flow()
13,399✔
940
}
17,053✔
941

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

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

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

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

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

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

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

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

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

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

1011
    match control_flow {
47,502✔
1012
        StdControlFlow::Break(Ok(value)) => Ok(Evaluated::Value(value)),
47,502✔
1013
        StdControlFlow::Break(Err(err)) => Err(err),
×
1014
        StdControlFlow::Continue(()) => Ok(Evaluated::Value(Value::Null)),
4,872✔
1015
    }
1016
}
54,810✔
1017

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

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

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

1050
pub fn splice<'a>(
7,308✔
1051
    name: &str,
7,308✔
1052
    list_data: Evaluated<'_>,
7,308✔
1053
    begin_index: Evaluated<'_>,
7,308✔
1054
    end_index: Evaluated<'_>,
7,308✔
1055
    values: Option<Evaluated<'_>>,
7,308✔
1056
) -> ControlFlow<Evaluated<'a>> {
7,308✔
1057
    let Value::List(list_data) = list_data.try_into().break_if_null()? else {
7,308✔
1058
        return Err(EvaluateError::ListTypeRequired.into()).into_control_flow();
1,218✔
1059
    };
1060

1061
    let begin_index = eval_to_int(name, begin_index)?.max(0);
6,090✔
1062
    let begin_index = usize::try_from(begin_index)
6,090✔
1063
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.to_owned()).into())
6,090✔
1064
        .into_control_flow()?;
6,090✔
1065
    let end_index = eval_to_int(name, end_index)?.max(0);
6,090✔
1066
    let end_index = usize::try_from(end_index)
6,090✔
1067
        .map_err(|_| EvaluateError::FunctionRequiresUSizeValue(name.to_owned()).into())
6,090✔
1068
        .into_control_flow()?;
6,090✔
1069

1070
    let (left, right) = {
6,090✔
1071
        let mut list_iter = list_data.into_iter();
6,090✔
1072
        let left: Vec<_> = list_iter.by_ref().take(begin_index).collect();
6,090✔
1073
        let right: Vec<_> = list_iter.skip(end_index - begin_index).collect();
6,090✔
1074
        (left, right)
6,090✔
1075
    };
6,090✔
1076

1077
    let center = match values {
6,090✔
1078
        Some(values) => match values.try_into().break_if_null()? {
4,872✔
1079
            Value::List(list) => list,
3,654✔
1080
            _ => return Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,218✔
1081
        },
1082
        None => vec![],
1,218✔
1083
    };
1084

1085
    let result = {
4,872✔
1086
        let mut result = vec![];
4,872✔
1087
        result.extend(left);
4,872✔
1088
        result.extend(center);
4,872✔
1089
        result.extend(right);
4,872✔
1090
        result
4,872✔
1091
    };
1092

1093
    Continue(Evaluated::Value(Value::List(result)))
4,872✔
1094
}
7,308✔
1095

1096
pub fn dedup<'a>(list: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
3,654✔
1097
    match list.try_into().break_if_null()? {
3,654✔
1098
        Value::List(mut list) => {
2,436✔
1099
            list.dedup();
2,436✔
1100
            Continue(Evaluated::Value(Value::List(list)))
2,436✔
1101
        }
1102
        _ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
1,218✔
1103
    }
1104
}
3,654✔
1105

1106
pub fn select_arrow_value(base: &Value, selector: &Value) -> Result<Value> {
49,938✔
1107
    if base.is_null() {
49,938✔
1108
        return Ok(Value::Null);
×
1109
    }
49,938✔
1110

1111
    match base {
49,938✔
1112
        Value::Map(map) => {
23,142✔
1113
            let key = match selector {
23,142✔
1114
                Value::Str(value) => Cow::Borrowed(value.as_str()),
7,308✔
1115
                Value::I8(value) => Cow::Owned(value.to_string()),
1,218✔
1116
                Value::I16(value) => Cow::Owned(value.to_string()),
2,436✔
1117
                Value::I32(value) => Cow::Owned(value.to_string()),
1,218✔
1118
                Value::I64(value) => Cow::Owned(value.to_string()),
2,436✔
1119
                Value::I128(value) => Cow::Owned(value.to_string()),
1,218✔
1120
                Value::U8(value) => Cow::Owned(value.to_string()),
1,218✔
1121
                Value::U16(value) => Cow::Owned(value.to_string()),
1,218✔
1122
                Value::U32(value) => Cow::Owned(value.to_string()),
1,218✔
1123
                Value::U64(value) => Cow::Owned(value.to_string()),
1,218✔
1124
                Value::U128(value) => Cow::Owned(value.to_string()),
1,218✔
1125
                _ => {
1126
                    return Err(EvaluateError::ArrowSelectorRequiresIntegerOrString(format!(
1,218✔
1127
                        "{selector:?}"
1,218✔
1128
                    ))
1,218✔
1129
                    .into());
1,218✔
1130
                }
1131
            };
1132

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

1156
            Ok(index
23,142✔
1157
                .and_then(|idx| list.get(idx).cloned())
23,142✔
1158
                .unwrap_or(Value::Null))
23,142✔
1159
        }
1160
        _ => Err(EvaluateError::ArrowBaseRequiresMapOrList.into()),
3,654✔
1161
    }
1162
}
49,938✔
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