Skip to main content

rl_lang/interpreter/stdlib/array/
arr_flat_map.rs

1use crate::{
2    ast::statements::TypeAnnotation,
3    interpreter::{evaluator::Evaluator, values::Value},
4    utils::{errors::Error, span::Span},
5};
6
7pub fn std_arr_flat_map(
8    eval: &mut Evaluator,
9    array: Value,
10    function: Value,
11    span: Span,
12) -> Result<Value, Error> {
13    let (items_type, items) = match array {
14        Value::Values { items_type, items } => (items_type, items),
15
16        other => {
17            return Err(eval.err(
18                format!(
19                    "arr_flat_map() accepts only arrays found {}",
20                    other.type_name()
21                )
22                .to_string(),
23                span,
24            ));
25        }
26    };
27    let Value::Function(data) = &function else {
28        return Err(eval.err(
29            format!(
30                "arr_flat_map() expected function or lambda found {}",
31                function.type_name()
32            ),
33            span,
34        ));
35    };
36
37    if !matches!(data.return_type, Some(TypeAnnotation::Array(_))) {
38        return Err(eval.err(
39            format!(
40                "arr_flat_map() expected function or lambda with Array return type found {:?}",
41                data.return_type
42            ),
43            span,
44        ));
45    }
46
47    let mut result = Vec::with_capacity(items.len());
48
49    for item in items {
50        let mapped_item = eval.call_value(function.clone(), vec![item.clone()], span)?;
51        if let Value::Values { items, .. } = mapped_item {
52            for item in items {
53                result.push(item)
54            }
55        }
56    }
57
58    Ok(Value::Values {
59        items_type,
60        items: result,
61    })
62}