rl_lang/interpreter/stdlib/array/
arr_sort_by.rs1use crate::{
2 interpreter::{evaluator::Evaluator, values::Value},
3 utils::{errors::Error, span::Span},
4};
5
6pub fn std_arr_sort_by(
7 eval: &mut Evaluator,
8 array: Value,
9 function: Value,
10 span: Span,
11) -> Result<Value, Error> {
12 let (items_type, mut items) = match array {
13 Value::Values { items_type, items } => (items_type, items),
14 other => {
15 return Err(eval.err(
16 format!(
17 "arr_sort_by() accepts only arrays, found {}",
18 other.type_name()
19 ),
20 span,
21 ));
22 }
23 };
24
25 if !matches!(function, Value::Function { .. }) {
26 return Err(eval.err(
27 format!(
28 "arr_sort_by() expected function or lambda, found {}",
29 function.type_name()
30 ),
31 span,
32 ));
33 }
34
35 for i in 1..items.len() {
36 let mut j = i;
37 while j > 0 {
38 let result = eval.call_value(
39 function.clone(),
40 vec![items[j - 1].clone(), items[j].clone()],
41 span,
42 )?;
43
44 match result {
45 Value::Integer(n) if n > 0 => {
46 items.swap(j - 1, j);
47 j -= 1;
48 }
49 Value::Integer(_) => break,
50 other => {
51 return Err(eval.err(
52 format!(
53 "arr_sort_by() comparator must return int (-1, 0, 1), found {}",
54 other.type_name()
55 ),
56 span,
57 ));
58 }
59 }
60 }
61 }
62
63 Ok(Value::Values { items_type, items })
64}