use std::collections::HashMap;
use std::fmt::Write as FmtWrite;
use crate::e2e::fixture::Assertion;
use super::{is_primitive_c_type, json_to_c};
#[derive(Debug, PartialEq, Eq)]
pub(super) enum NestedLeafOutcome {
Typed(String),
Wildcard { array_var: String, key_snake: String },
}
pub(super) fn classify_nested_leaf(
outcome: NestedLeafOutcome,
local_var: &str,
primitive_locals: &mut HashMap<String, String>,
opaque_handle_locals: &mut HashMap<String, String>,
wildcard_locals: &mut HashMap<String, (String, String)>,
) {
match outcome {
NestedLeafOutcome::Typed(type_name) => {
if type_name == "__skip__" || is_primitive_c_type(&type_name) {
primitive_locals.insert(local_var.to_string(), type_name);
} else {
opaque_handle_locals.insert(local_var.to_string(), type_name);
}
}
NestedLeafOutcome::Wildcard { array_var, key_snake } => {
wildcard_locals.insert(local_var.to_string(), (array_var, key_snake));
}
}
}
pub(super) fn render_wildcard_assertion(out: &mut String, assertion: &Assertion, array_var: &str, key_snake: &str) {
match assertion.assertion_type.as_str() {
"contains" => {
if let Some(expected) = &assertion.value {
render_quantifier(
out,
array_var,
key_snake,
&[json_to_c(expected)],
false,
"contains",
"expected some element to contain a substring",
);
}
}
"contains_all" => {
if let Some(values) = &assertion.values {
for val in values {
render_quantifier(
out,
array_var,
key_snake,
&[json_to_c(val)],
false,
"contains",
"expected some element to contain a substring",
);
}
}
}
"contains_any" => {
if let Some(values) = &assertion.values {
let needles: Vec<String> = values.iter().map(json_to_c).collect();
render_quantifier(
out,
array_var,
key_snake,
&needles,
false,
"contains",
"expected some element to contain at least one of the specified values",
);
}
}
"not_contains" => {
if let Some(expected) = &assertion.value {
render_quantifier(
out,
array_var,
key_snake,
&[json_to_c(expected)],
true,
"contains",
"expected no element to contain a substring",
);
}
}
"equals" => {
if let Some(expected) = &assertion.value {
render_quantifier(
out,
array_var,
key_snake,
&[json_to_c(expected)],
false,
"equals",
"expected some element to equal the expected value",
);
}
}
other => {
let field = assertion.field.as_deref().unwrap_or("");
let _ = writeln!(
out,
" // skipped: unsupported traversal assertion '{other}' on '{field}'"
);
}
}
}
fn render_quantifier(
out: &mut String,
array_var: &str,
key_snake: &str,
needles: &[String],
negate: bool,
compare_mode: &str,
message: &str,
) {
out.push_str(&crate::e2e::template_env::render(
"c/wildcard_collection_assertion.jinja",
minijinja::context! {
array_var => array_var,
key_snake => key_snake,
needles => needles,
negate => negate,
compare_mode => compare_mode,
message => message,
},
));
}