akar_function/scalar/
map_struct.rs1use super::get_string;
2use crate::registry::*;
3use akar_common::types::Value;
4
5pub(crate) fn evaluate_map(op: MapOp, args: &[Value]) -> Result<Value, String> {
8 match op {
9 MapOp::Creation => {
10 if args.len() % 2 != 0 {
12 return Err("Map creation requires an even number of arguments (key-value pairs)".into());
13 }
14 let mut entries = Vec::new();
15 let mut i = 0;
16 while i < args.len() {
17 let key = match &args[i] {
18 Value::String(s) => s.clone(),
19 other => return Err(format!("Map key must be a string, got {:?}", other.logical_type())),
20 };
21 let val = args[i + 1].clone();
22 entries.push((key, val));
23 i += 2;
24 }
25 Ok(Value::Struct(entries))
26 }
27 MapOp::MapFromEntries => {
28 match &args[0] {
29 Value::List(items) => {
30 let mut result_entries = Vec::new();
31 for item in items {
32 match item {
33 Value::Struct(s) => {
34 let mut k = None;
35 let mut v = None;
36 for (fname, fval) in s {
37 if fname == "key" || fname == "k" {
38 k = Some(fval);
39 } else if fname == "value" || fname == "v" {
40 v = Some(fval);
41 }
42 }
43 if let (Some(Value::String(k_str)), Some(val)) = (k, v) {
44 result_entries.push((k_str.clone(), val.clone()));
45 } else {
46 if s.len() >= 2 {
48 if let Value::String(k_str) = &s[0].1 {
49 result_entries.push((k_str.clone(), s[1].1.clone()));
50 }
51 }
52 }
53 }
54 _ => return Err("MapFromEntries requires a list of structs".into()),
55 }
56 }
57 Ok(Value::Struct(result_entries))
58 }
59 _ => Err("MapFromEntries requires a list of structs".into()),
60 }
61 }
62 MapOp::Extract => {
63 let map_val = &args[0];
64 let key = get_string(&args[1])?;
65 match map_val {
66 Value::Struct(entries) => {
67 for (k, v) in entries {
68 if *k == key {
69 return Ok(v.clone());
70 }
71 }
72 Err(format!("Key '{}' not found in map", key))
73 }
74 _ => Err("Expected map/struct".into()),
75 }
76 }
77 MapOp::Keys => match &args[0] {
78 Value::Struct(entries) => Ok(Value::List(
79 entries.iter().map(|(k, _)| Value::String(k.clone())).collect(),
80 )),
81 _ => Err("Expected map/struct".into()),
82 },
83 MapOp::Values => match &args[0] {
84 Value::Struct(entries) => Ok(Value::List(entries.iter().map(|(_, v)| v.clone()).collect())),
85 _ => Err("Expected map/struct".into()),
86 },
87 MapOp::Contains => match &args[0] {
88 Value::Struct(entries) => {
89 let key = get_string(&args[1])?;
90 Ok(Value::Bool(entries.iter().any(|(k, _)| *k == key)))
91 }
92 _ => Err("Expected map/struct".into()),
93 },
94 }
95}
96
97pub(crate) fn evaluate_struct(op: StructOp, args: &[Value]) -> Result<Value, String> {
98 match op {
99 StructOp::Creation => {
100 if args.len() % 2 != 0 {
102 return Err("Struct creation requires an even number of arguments (field-value pairs)".into());
103 }
104 let mut entries = Vec::new();
105 let mut i = 0;
106 while i < args.len() {
107 let field_name = match &args[i] {
108 Value::String(s) => s.clone(),
109 other => {
110 return Err(format!(
111 "Struct field name must be a string, got {:?}",
112 other.logical_type()
113 ));
114 }
115 };
116 let val = args[i + 1].clone();
117 entries.push((field_name, val));
118 i += 2;
119 }
120 Ok(Value::Struct(entries))
121 }
122 StructOp::Extract => {
123 let struct_val = &args[0];
124 let key = get_string(&args[1])?;
125 match struct_val {
126 Value::Struct(entries) => {
127 for (k, v) in entries {
128 if *k == key {
129 return Ok(v.clone());
130 }
131 }
132 Err(format!("Key '{}' not found in struct", key))
133 }
134 _ => Err("Expected struct".into()),
135 }
136 }
137 }
138}