use super::*;
pub(super) fn swift_capsule_return_config<'a>(
func: &FunctionDef,
capsule_types: &'a std::collections::HashMap<String, crate::core::config::HostCapsuleTypeConfig>,
) -> Option<&'a crate::core::config::HostCapsuleTypeConfig> {
if let TypeRef::Named(name) = &func.return_type {
capsule_types.get(name.as_str())
} else {
None
}
}
pub(super) fn emit_capsule_free_function_forwarder(
func: &FunctionDef,
swift_name: &str,
capsule_cfg: &crate::core::config::HostCapsuleTypeConfig,
out: &mut String,
) {
let host_type = match capsule_cfg.required_host_type("Language", "swift") {
Ok(t) => t.to_string(),
Err(e) => {
out.push_str(&format!("// ALEF ERROR: {e}\n"));
return;
}
};
if !func.doc.is_empty() {
emit_doc_comment(&func.doc, "", out);
}
let mut sig_params: Vec<String> = Vec::new();
let mut c_args: Vec<String> = Vec::new();
for param in &func.params {
let swift_param_name = swift_ident(¶m.name.to_lower_camel_case());
let swift_ty = if param.optional { "String?" } else { "String" };
let param_default = if param.optional { " = nil" } else { "" };
sig_params.push(format!("{swift_param_name}: {swift_ty}{param_default}"));
c_args.push(swift_param_name);
}
let sig = sig_params.join(", ");
let is_fallible = func.error_type.is_some();
let throws_clause = if is_fallible { " throws" } else { "" };
let return_clause = if is_fallible {
format!(" -> {host_type}")
} else {
format!(" -> {host_type}?")
};
let c_call = format!("RustBridge.{swift_name}({})", c_args.join(", "));
let construct = match capsule_cfg.construct_required("cLang", "Language", "swift") {
Ok(c) => c,
Err(e) => {
out.push_str(&format!("// ALEF ERROR: {e}\n"));
return;
}
};
let nil_error = format!(
"NSError(domain: \"alef.capsule\", code: 1, userInfo: [NSLocalizedDescriptionKey: \"Capsule function returned null: {swift_name}\"])"
);
let body = if is_fallible {
format!(
"let addr = {c_call}\n guard addr != 0, let cLang = OpaquePointer(bitPattern: addr) else {{ throw {nil_error} }}\n return {construct}"
)
} else {
format!(
"let addr = {c_call}\n guard addr != 0, let cLang = OpaquePointer(bitPattern: addr) else {{ return nil }}\n return {construct}"
)
};
out.push_str(&crate::backends::swift::template_env::render(
"swift_sync_forwarder.swift.jinja",
minijinja::context! {
function_name => swift_name,
params => &sig,
throws_clause => throws_clause,
return_clause => &return_clause,
conversion_lines => "",
body => body,
},
));
}
pub(super) fn emit_async_capsule_free_function_forwarder(
func: &FunctionDef,
swift_name: &str,
capsule_cfg: &crate::core::config::HostCapsuleTypeConfig,
out: &mut String,
) {
let host_type = match capsule_cfg.required_host_type("Language", "swift") {
Ok(t) => t.to_string(),
Err(e) => {
out.push_str(&format!("// ALEF ERROR: {e}\n"));
return;
}
};
if !func.doc.is_empty() {
emit_doc_comment(&func.doc, "", out);
}
let mut sig_params: Vec<String> = Vec::new();
let mut c_args: Vec<String> = Vec::new();
for param in &func.params {
let swift_param_name = swift_ident(¶m.name.to_lower_camel_case());
let swift_ty = if param.optional { "String?" } else { "String" };
let param_default = if param.optional { " = nil" } else { "" };
sig_params.push(format!("{swift_param_name}: {swift_ty}{param_default}"));
c_args.push(swift_param_name);
}
let sig = sig_params.join(", ");
let is_fallible = func.error_type.is_some();
let throws_clause = if is_fallible { " throws" } else { "" };
let return_clause = if is_fallible {
format!(" -> {host_type}")
} else {
format!(" -> {host_type}?")
};
let c_call = format!("RustBridge.{swift_name}({})", c_args.join(", "));
let construct = match capsule_cfg.construct_required("cLang", "Language", "swift") {
Ok(c) => c,
Err(e) => {
out.push_str(&format!("// ALEF ERROR: {e}\n"));
return;
}
};
let nil_error = format!(
"NSError(domain: \"alef.capsule\", code: 1, userInfo: [NSLocalizedDescriptionKey: \"Capsule function returned null: {swift_name}\"])"
);
let body = if is_fallible {
format!(
"let addr = {c_call}\n guard addr != 0, let cLang = OpaquePointer(bitPattern: addr) else {{ throw {nil_error} }}\n return {construct}"
)
} else {
format!(
"let addr = {c_call}\n guard addr != 0, let cLang = OpaquePointer(bitPattern: addr) else {{ return nil }}\n return {construct}"
)
};
out.push_str(&crate::backends::swift::template_env::render(
"swift_async_forwarder.swift.jinja",
minijinja::context! {
function_name => swift_name,
params => &sig,
throws_clause => throws_clause,
return_clause => &return_clause,
body => body,
},
));
}