akar_function/scalar/
union_funcs.rs1use super::get_string;
2use crate::registry::*;
3use akar_common::types::Value;
4
5pub(crate) fn evaluate_union(op: UnionOp, args: &[Value]) -> Result<Value, String> {
9 match op {
10 UnionOp::UnionValue => {
11 let val = args[0].clone();
13 Ok(Value::Struct(vec![
14 ("tag".to_string(), Value::UInt16(0)),
15 ("_value".to_string(), val),
16 ]))
17 }
18 UnionOp::UnionTag => {
19 let entries = match &args[0] {
21 Value::Struct(entries) => entries,
22 _ => return Err("UNION_TAG requires a union argument".into()),
23 };
24 let tag_val = entries
26 .iter()
27 .find(|(k, _)| k == "tag")
28 .ok_or("Union has no tag field".to_string())?;
29 let tag_idx = match &tag_val.1 {
30 Value::UInt16(x) => *x as usize,
31 _ => return Err("Invalid tag field type".into()),
32 };
33 let field_idx = tag_idx + 1;
35 if field_idx >= entries.len() {
36 return Err(format!("Union tag index {} out of range", tag_idx));
37 }
38 Ok(Value::String(entries[field_idx].0.clone()))
39 }
40 UnionOp::UnionExtract => {
41 let struct_val = &args[0];
43 let key = get_string(&args[1])?;
44 match struct_val {
45 Value::Struct(entries) => {
46 for (k, v) in entries {
47 if *k == key {
48 return Ok(v.clone());
49 }
50 }
51 Err(format!("Key '{}' not found in union", key))
52 }
53 _ => Err("UNION_EXTRACT requires a union argument".into()),
54 }
55 }
56 }
57}