use super::FieldResolver;
use super::ir_enum::leaf_owner_type_at_path;
impl FieldResolver {
pub(crate) fn with_text_projected_enums(mut self, names: &[String]) -> Self {
self.text_projected_enum_names = names.iter().cloned().collect();
self
}
pub(crate) fn is_text_projected_enum(&self, name: &str) -> bool {
self.text_projected_enum_names.contains(name)
}
pub(crate) fn text_projected_crossing(&self, path: &str) -> Option<String> {
let (_, owner, _, _) = self.ir_tagged_union_split(self.resolve(path))?;
self.is_text_projected_enum(&owner).then_some(owner)
}
pub(crate) fn with_wasm_text_value_fields(
mut self,
types: &[crate::core::ir::TypeDef],
enums: &[crate::core::ir::EnumDef],
exclude_types: &[String],
) -> Self {
use crate::codegen::conversions::helpers::{text_value_companion, text_value_enum_names};
let text_names: ahash::AHashSet<String> = self.text_projected_enum_names.iter().cloned().collect();
let names = text_value_enum_names(enums, &text_names, exclude_types);
self.wasm_text_value_fields = types
.iter()
.filter(|definition| !exclude_types.contains(&definition.name))
.flat_map(|definition| {
let names = &names;
definition.fields.iter().filter_map(move |field| {
text_value_companion(&definition.fields, field, names)
.map(|_| (definition.name.clone(), field.name.clone()))
})
})
.collect();
self
}
pub(crate) fn wasm_text_value_accessor(&self, prefix: &str, owner: &str, result: &str) -> Option<String> {
if !self.is_text_projected_enum(owner) {
return None;
}
let (parent, leaf) = prefix
.rsplit_once('.')
.map_or((None, prefix), |(parent, leaf)| (Some(parent), leaf));
if leaf.is_empty() || leaf.contains('[') {
return None;
}
let declaring_type = leaf_owner_type_at_path(&self.ir_enum_map, prefix)?;
if !self
.wasm_text_value_fields
.contains(&(declaring_type, leaf.to_string()))
{
return None;
}
let getter = crate::codegen::naming::to_node_name(&format!("{leaf}_value"));
let base = parent.map_or_else(
|| result.to_string(),
|parent| self.accessor(parent, "typescript", result),
);
let access = if base.contains("?.") { "?." } else { "." };
Some(format!("{base}{access}{getter}"))
}
pub(crate) fn wasm_text_value_readable(&self, path: &str) -> bool {
let Some((prefix, owner, variant, _)) = self.ir_tagged_union_split(self.resolve(path)) else {
return false;
};
self.union_variant_payload_is_collection(&owner, &variant)
&& self.wasm_text_value_accessor(&prefix, &owner, "result").is_some()
}
}