use super::super::super::types::{FieldResolver, SwiftFirstClassMap};
impl FieldResolver {
pub(crate) fn swift_indexed_element_uses_bridge(&self, field: &str) -> Option<bool> {
let path = self.resolve(field);
let (collection, index) = path.strip_suffix(']')?.rsplit_once('[')?;
index.parse::<usize>().ok()?;
if !self.is_collection_root(collection) {
return None;
}
self.swift_leaf_fact(collection, |map, owner, leaf, opaque| {
map.json_bridged_getter(owner, leaf).map(|json| opaque && !json)
})
}
pub(crate) fn swift_lossless_text_leaf_is_opaque(&self, field: &str) -> Option<bool> {
self.swift_leaf_fact(field, |_, owner, leaf, opaque| {
self.swift_lossless_text_fields
.get(owner)?
.contains(leaf)
.then_some(opaque)
})
}
pub fn leaf_is_json_bridged_via_swift_map(&self, field: &str) -> bool {
if let Some(answer) = self.swift_leaf_is_json_bridged(field) {
return answer;
}
let leaf = field.split('.').next_back().unwrap_or(field);
let leaf = leaf.split('[').next().unwrap_or(leaf);
self.swift_first_class_map.is_json_bridged_field_name(leaf)
}
pub fn swift_leaf_is_json_bridged(&self, field: &str) -> Option<bool> {
self.swift_leaf_fact(field, |map, owner, leaf, opaque| {
if opaque {
map.json_bridged_getter(owner, leaf)
} else {
Some(false)
}
})
}
pub(super) fn swift_leaf_fact(
&self,
field: &str,
fact: impl Fn(&SwiftFirstClassMap, &str, &str, bool) -> Option<bool>,
) -> Option<bool> {
let map = &self.swift_first_class_map;
let resolved = self.resolve(field);
let segments: Vec<&str> = resolved.split('.').filter(|s| !s.is_empty()).collect();
let last = segments.len().checked_sub(1)?;
let mut current = self
.ir_collection_map
.root_type
.clone()
.or_else(|| self.ir_enum_map.root_type.clone())
.or_else(|| map.root_type.clone())?;
let mut opaque = false;
for (index, segment) in segments.iter().enumerate() {
opaque |= !map.is_first_class(Some(¤t));
let bare = segment.split('[').next().unwrap_or(segment);
if index == last && !segment.contains('[') {
return fact(map, ¤t, bare, opaque);
}
current = map.advance(Some(¤t), bare)?;
}
None
}
pub fn swift_leaf_getter_is_optional(&self, field: &str) -> Option<bool> {
self.swift_leaf_fact(field, |map, owner, leaf, opaque| {
if opaque {
map.getter_is_optional(owner, leaf)
} else {
Some(self.is_optional(field))
}
})
}
}