fn emit_value_type_shims(
out: &mut String,
ty: &TypeDef,
package: &str,
bridge: &str,
serde_type_names: &std::collections::HashSet<&str>,
) {
for method in bridgeable_value_methods(ty, serde_type_names) {
let symbol = jni_symbol(package, bridge, &bridge_method_name(&ty.name, &method.name));
emit_value_method_shim(out, &symbol, &ty.name, method);
}
}
fn emit_value_method_shim(out: &mut String, symbol: &str, type_name: &str, method: &MethodDef) {
let rust_method = method.name.replace('-', "_");
let returns_receiver = is_functional_ref_mut_value_method(method);
let return_type = value_method_return_type(type_name, method);
let ret_decl = method_return_type_decl(&return_type);
let ret_null = method_return_null(&return_type);
let request_param = if method.params.is_empty() {
String::new()
} else {
" request_json: JString,\n".to_string()
};
out.push_str(&template_env::render(
"value_method_shim_open.rs.jinja",
context! {
symbol => symbol,
request_param => request_param,
ret_decl => ret_decl,
},
));
out.push_str(&template_env::render(
"value_method_receiver.rs.jinja",
context! {
type_name => type_name,
ret_null => ret_null,
},
));
let call_args = emit_value_param_unmarshal(out, &method.params, ret_null);
let call_expr = if returns_receiver {
format!("{{ client.{rust_method}({call_args}); client }}")
} else {
format!("client.{rust_method}({call_args})")
};
if method.error_type.is_some() {
let mut ok_body = String::new();
emit_return_marshal(&mut ok_body, &return_type, ret_null);
render_call_result_body(out, &call_expr, false, true, ret_null, &ok_body, "");
} else {
let mut value_body = String::new();
emit_return_marshal_with_indent(&mut value_body, &return_type, " ", ret_null);
render_call_result_body(out, &call_expr, false, false, ret_null, "", &value_body);
}
}
fn emit_value_param_unmarshal(out: &mut String, params: &[ParamDef], ret_null: &str) -> String {
if params.is_empty() {
return String::new();
}
out.push_str(&template_env::render(
"request_map_unmarshal.rs.jinja",
context! {
ret_null => ret_null,
},
));
let mut args = Vec::with_capacity(params.len());
for param in params {
let rust_name = param.name.replace('-', "_");
let is_path = matches!(¶m.ty, TypeRef::Path);
let type_path = if is_path {
"String".to_string()
} else {
type_ref_to_core_path_with_btree(¶m.ty, "core_crate", param.map_is_btree)
};
out.push_str(&template_env::render(
"request_map_param_unmarshal.rs.jinja",
context! {
name => rust_name,
type_path => type_path,
ret_null => ret_null,
},
));
if is_path {
out.push_str(&format!(
" let {rust_name} = std::path::PathBuf::from({rust_name});\n"
));
}
if needs_vec_string_refs(param, ¶m.ty) {
out.push_str(&render_vec_string_refs_binding(&rust_name));
args.push(vec_string_refs_arg(&rust_name));
} else if param.is_ref {
args.push(format!("&{rust_name}"));
} else {
args.push(rust_name);
}
}
args.join(", ")
}