use super::optional_renderers::{push_key_field_name, push_key_index_suffix};
use super::renderers::render_dot_access;
use super::types::PathSegment;
use std::collections::HashSet;
pub(super) fn render_python_with_optionals(
segments: &[PathSegment],
result_var: &str,
optional_fields: &HashSet<String>,
) -> String {
let last_index = segments.len().saturating_sub(1);
let mut crossings: Vec<usize> = Vec::new();
let mut path_so_far = String::new();
for (index, segment) in segments.iter().enumerate() {
push_key_field_name(&mut path_so_far, segment);
if index != last_index && optional_fields.contains(&path_so_far) {
crossings.push(index);
}
push_key_index_suffix(&mut path_so_far, segment);
}
let mut expression = render_dot_access(segments, result_var, "python");
for &index in crossings.iter().rev() {
let condition = render_dot_access(&field_only_prefix(segments, index), result_var, "python");
expression = format!("({expression} if {condition} else None)");
}
expression
}
fn field_only_prefix(segments: &[PathSegment], index: usize) -> Vec<PathSegment> {
let mut prefix: Vec<PathSegment> = segments[..index].to_vec();
prefix.push(match &segments[index] {
PathSegment::ArrayField { name, .. } => PathSegment::Field(name.clone()),
PathSegment::MapAccess { field, .. } => PathSegment::Field(field.clone()),
other => other.clone(),
});
prefix
}