use crate::e2e::field_access::{FieldResolver, push_owner_segment};
#[derive(Clone, Copy)]
pub(super) enum Unwrap {
Panic,
Error,
}
const WILDCARD_MISSING_FIELD_ERROR: &str = "error.WildcardElementFieldMissing";
pub(super) fn json_path_expr_with(
result_var: &str,
anchor_prefix: &str,
field_path: &str,
unwrap: Unwrap,
field_resolver: &FieldResolver,
) -> String {
if anchor_prefix.is_empty()
&& let Some(expression) = super::enum_collection::accessor(result_var, field_path, field_resolver)
{
return expression;
}
let segments: Vec<&str> = field_path.split('.').collect();
let mut expr = result_var.to_string();
let mut owner_path = anchor_prefix.to_string();
for seg in &segments {
let bare = seg.split('[').next().unwrap_or(seg);
if field_resolver.is_internally_tagged_variant_segment(&owner_path, bare) {
push_owner_segment(&mut owner_path, bare);
continue;
}
if let Some(key) = seg.strip_suffix("[]") {
expr = format!("{}.array.items[0]", json_get(&expr, key, unwrap, field_resolver));
} else if let Some(bracket_pos) = seg.find('[') {
if let Some(end_pos) = seg.find(']')
&& end_pos > bracket_pos + 1
&& end_pos == seg.len() - 1
{
let key = &seg[..bracket_pos];
let idx = &seg[bracket_pos + 1..end_pos];
if idx.chars().all(|c| c.is_ascii_digit()) {
expr = format!("{}.array.items[{idx}]", json_get(&expr, key, unwrap, field_resolver));
push_owner_segment(&mut owner_path, bare);
continue;
}
expr = json_get(
&json_get(&expr, key, unwrap, field_resolver),
idx,
unwrap,
field_resolver,
);
push_owner_segment(&mut owner_path, bare);
continue;
}
expr = json_get(&expr, seg, unwrap, field_resolver);
} else {
expr = json_get(&expr, seg, unwrap, field_resolver);
}
push_owner_segment(&mut owner_path, bare);
}
expr
}
fn json_get(expr: &str, key: &str, unwrap: Unwrap, field_resolver: &FieldResolver) -> String {
if field_resolver.is_wire_optional_key(key) {
return format!("({expr}.object.get(\"{key}\") orelse std.json.Value{{ .null = {{}} }})");
}
match unwrap {
Unwrap::Panic => format!("{expr}.object.get(\"{key}\").?"),
Unwrap::Error => format!("({expr}.object.get(\"{key}\") orelse return {WILDCARD_MISSING_FIELD_ERROR})"),
}
}