use crate::codegen::generators::type_paths::resolve_type_path;
use crate::core::ir::EnumDef;
use std::collections::HashMap;
pub(crate) fn emit_enum_wrapper(en: &EnumDef, source_crate: &str, type_paths: &HashMap<String, String>) -> String {
let mut out = String::new();
let source_path = resolve_type_path(&en.name, source_crate, type_paths);
let unit_variants: Vec<&crate::core::ir::EnumVariant> =
en.variants.iter().filter(|v| v.fields.is_empty()).collect();
out.push_str(&crate::backends::swift::template_env::render(
"enum_unit_header.jinja",
minijinja::context! {
name => &en.name,
},
));
for variant in &unit_variants {
out.push_str(&crate::backends::swift::template_env::render(
"enum_unit_variant.jinja",
minijinja::context! {
variant_name => &variant.name,
},
));
}
let has_data_variants = en.variants.len() > unit_variants.len();
if has_data_variants {
out.push_str(" /// Data variants not directly bridgeable — represented as Unknown.\n");
out.push_str(" Unknown,\n");
}
out.push_str("}\n\n");
out.push_str(&crate::backends::swift::template_env::render(
"enum_from_impl_header.jinja",
minijinja::context! {
source_path => &source_path,
name => &en.name,
},
));
out.push_str(" match val {\n");
for variant in &unit_variants {
out.push_str(&crate::backends::swift::template_env::render(
"enum_from_variant.jinja",
minijinja::context! {
source_path => &source_path,
variant_name => &variant.name,
},
));
}
if has_data_variants {
out.push_str(&crate::backends::swift::template_env::render(
"enum_from_wildcard.jinja",
minijinja::context! {},
));
}
out.push_str(" }\n");
out.push_str(" }\n");
out.push_str("}\n\n");
out.push_str(&format!("impl {} {{\n", en.name));
out.push_str(" pub fn to_string(&self) -> String {\n");
out.push_str(" match self {\n");
for variant in &unit_variants {
let serde_name = serde_variant_name(variant, en.serde_rename_all.as_deref());
out.push_str(&format!(
" Self::{} => \"{}\".to_string(),\n",
variant.name, serde_name
));
}
if has_data_variants {
out.push_str(" Self::Unknown => \"unknown\".to_string(),\n");
}
out.push_str(" }\n");
out.push_str(" }\n");
out.push_str("}\n");
out
}
fn serde_variant_name(variant: &crate::core::ir::EnumVariant, rename_all: Option<&str>) -> String {
if let Some(rename) = &variant.serde_rename {
return rename.clone();
}
match rename_all {
Some("snake_case") => crate::codegen::naming::pascal_to_snake(&variant.name),
Some("lowercase") => variant.name.to_lowercase(),
Some("UPPERCASE") => variant.name.to_uppercase(),
Some("camelCase") => {
use heck::ToLowerCamelCase;
variant.name.to_lower_camel_case()
}
Some("PascalCase") | Some("UpperCamelCase") => {
use heck::ToUpperCamelCase;
variant.name.to_upper_camel_case()
}
Some("SCREAMING_SNAKE_CASE") => {
use heck::ToShoutySnakeCase;
variant.name.to_shouty_snake_case()
}
Some("kebab-case") => {
use heck::ToKebabCase;
variant.name.to_kebab_case()
}
Some("SCREAMING-KEBAB-CASE") => {
use heck::ToShoutyKebabCase;
variant.name.to_shouty_kebab_case()
}
_ => variant.name.clone(),
}
}