use std::collections::{HashMap, HashSet};
pub(super) fn is_assertion_field_swift_excluded(
field_path: &str,
root_type: Option<&str>,
field_types: &HashMap<String, HashMap<String, String>>,
excluded_fields_by_type: &HashMap<String, HashSet<String>>,
excluded_types: &HashSet<String>,
) -> bool {
if excluded_fields_by_type.is_empty() && excluded_types.is_empty() {
return false;
}
let segments: Vec<&str> = field_path
.split(['.', '[', ']'])
.filter(|s| !s.is_empty() && !s.chars().all(|c: char| c.is_ascii_digit()))
.collect();
let mut current_type: Option<String> = root_type.map(|s| s.to_string());
let mut every_segment_walked = current_type.is_some();
for &segment in &segments {
let Some(owner_str) = current_type.as_deref() else {
every_segment_walked = false;
break;
};
if excluded_fields_by_type
.get(owner_str)
.is_some_and(|fields| fields.contains(segment))
{
return true;
}
let next: Option<String> = field_types.get(owner_str).and_then(|m| m.get(segment).cloned());
if let Some(ref next_type) = next
&& excluded_types.contains(next_type.as_str())
{
return true;
}
current_type = next;
}
if every_segment_walked {
return false;
}
segments
.iter()
.any(|segment| excluded_fields_by_type.values().any(|fields| fields.contains(*segment)))
}