impl {{ core_import }}::{{ trait_name }} for {{ bridge_name }} {
fn {{ dispatch_name }}(
&self{{ extra_param }},
{{ wire_name }}: {{ req_path }},
) -> std::pin::Pin<Box<dyn std::future::Future<Output = {{ output_type }}> + Send + '_>> {
Box::pin(async move {
let outcome: {{ wire_output }} = async move {
let req_json = serde_json::to_string(&{{ wire_name }})
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)?;
let result_json = {
let env = self.jvm.attach_current_thread()
.map_err(|e| Box::new(std::io::Error::new(
std::io::ErrorKind::Other,
format!("failed to attach JVM thread: {}", e)
)) as Box<dyn std::error::Error + Send + Sync>)?;
let req_jni = env.new_string(&req_json)
.map_err(|e| Box::new(std::io::Error::new(
std::io::ErrorKind::Other,
format!("failed to create JNI string: {}", e)
)) as Box<dyn std::error::Error + Send + Sync>)?;
let result: jni::sys::jstring = unsafe {
// SAFETY: method_id was validated when bridge was created.
// self.global_ref is valid for the JVM's lifetime.
env.call_method_unchecked(
self.global_ref.as_obj(),
self.method_id,
jni::sys::JNI_ABORT,
&[jni::objects::JValue::from(&req_jni)],
)?
.l()?
.as_raw()
};
let result_obj = unsafe {
// SAFETY: result is a valid jstring from the JNI call.
jni::objects::JString::from_raw(result)
};
env.get_string(&result_obj)?
.into_string()
.map_err(|e| Box::new(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("response is not valid UTF-8: {}", e)
)) as Box<dyn std::error::Error + Send + Sync>)?
};
let response: {{ resp_path }} = serde_json::from_str(&result_json)
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)?;
Ok(response)
}.await;
{{ tail }}
})
}
}