use crate::backends::pyo3::type_map::Pyo3Mapper;
pub(super) fn variant_wrapper_constructor_body(typ: &crate::core::ir::TypeDef, mapper: &Pyo3Mapper) -> Option<String> {
use crate::codegen::type_mapper::TypeMapper as _;
let ctor = typ.methods.iter().find(|m| m.name == "new" && m.receiver.is_none())?;
let map_fn = |t: &crate::core::ir::TypeRef| mapper.map_type(t);
let sig_params = crate::codegen::shared::function_params(&ctor.params, &map_fn);
let call_args = ctor
.params
.iter()
.map(|p| p.name.as_str())
.collect::<Vec<_>>()
.join(", ");
let body = if call_args.is_empty() {
"Self::new()".to_string()
} else {
format!("Self::new({call_args})")
};
Some(format!(
" #[new]\n pub fn py_new({sig_params}) -> Self {{\n {body}\n }}\n"
))
}
pub(super) fn should_emit_default_impl(typ: &crate::core::ir::TypeDef, impl_block: &str) -> bool {
if !typ.has_default {
return false;
}
if impl_block.contains("impl Default") {
return false;
}
typ.methods.iter().any(|m| {
m.name == "new" && m.params.is_empty() && m.receiver.is_none() })
}
pub(super) fn emit_default_impl(type_name: &str) -> String {
format!("impl Default for {type_name} {{\n fn default() -> Self {{\n Self::new()\n }}\n}}\n")
}
pub(super) fn inject_into_impl_block(impl_block: &str, body: &str) -> String {
let trimmed = impl_block.trim_end();
let Some(close_idx) = trimmed.rfind('}') else {
return impl_block.to_string();
};
let (head, tail) = trimmed.split_at(close_idx);
let head_trimmed = head.trim_end();
format!("{head_trimmed}\n\n{body}{tail}\n")
}