use crate::core::ir::{ParamDef, PrimitiveType, TypeRef};
use std::collections::HashSet;
pub(super) struct NativeArg {
pub key: String,
pub binding: String,
pub owned_expr: String,
}
pub(super) fn build_native_args(params: &[ParamDef], struct_param_types: &HashSet<String>) -> Vec<NativeArg> {
params
.iter()
.map(|p| {
let key = p.name.strip_prefix('_').unwrap_or(&p.name).to_string();
NativeArg {
key,
binding: format!("{}_arg", p.name),
owned_expr: owned_arg_expr(p, struct_param_types),
}
})
.collect()
}
fn owned_arg_expr(p: &ParamDef, struct_param_types: &HashSet<String>) -> String {
let name = &p.name;
if let TypeRef::Named(n) = &p.ty {
if struct_param_types.contains(n) {
if p.is_ref {
return format!("{n}::from((*{name}).clone())");
}
return format!("{n}::from({name}.clone())");
}
}
if p.optional && matches!(&p.ty, TypeRef::String) {
return format!("{name}.map(|s| s.to_string())");
}
match &p.ty {
TypeRef::String | TypeRef::Char => {
if p.is_ref {
format!("{name}.to_string()")
} else {
format!("{name}.clone()")
}
}
TypeRef::Primitive(
PrimitiveType::Bool
| PrimitiveType::U8
| PrimitiveType::U16
| PrimitiveType::U32
| PrimitiveType::U64
| PrimitiveType::Usize
| PrimitiveType::I8
| PrimitiveType::I16
| PrimitiveType::I32
| PrimitiveType::I64
| PrimitiveType::Isize
| PrimitiveType::F32
| PrimitiveType::F64,
) => name.clone(),
TypeRef::Vec(_) => {
if p.is_ref {
format!("{name}.to_vec()")
} else {
format!("{name}.clone()")
}
}
_ => format!("format!(\"{{:?}}\", {name})"),
}
}