alef 0.34.11

Opinionated polyglot binding generator for Rust libraries
Documentation
impl {{ wrapper_name }} {
    /// Create a bridge over the JVM `{{ trait_name }}JniDispatcher` object.
    ///
    /// Caches a global reference, the `JavaVM` for thread attachment, the host's
    /// implemented-method names (for defaulted-method forwarding), and the plugin
    /// name.
    pub fn new(
        env: &mut Env<'_>,
        dispatcher: JObject<'_>,
{% if not has_super_trait %}
        name: String,
{% endif %}
    ) -> std::result::Result<Self, String> {
        let inner = env
            .new_global_ref(&dispatcher)
            .map_err(|e| format!("global ref: {e}"))?;
        let jvm = env.get_java_vm().map_err(|e| format!("JavaVM: {e}"))?;
        let implemented_json = jni_call_string_method(
            env,
            dispatcher,
            "implementedMethods",
            "()Ljava/lang/String;",
        )
        .map_err(|e| format!("implementedMethods: {e}"))?;
        let implemented_methods: std::collections::HashSet<String> =
            serde_json::from_str(&implemented_json).unwrap_or_default();

        let mut bridge = Self {
            inner,
            cached_name: String::new(),
            jvm,
            implemented_methods,
        };
{% if has_super_trait %}
        bridge.cached_name = bridge
            .__alef_dispatch("name", "{}")
            .ok()
            .and_then(|resp| serde_json::from_str::<serde_json::Value>(&resp).ok())
            .and_then(|v| v.get("ok").and_then(|o| o.as_str()).map(str::to_string))
            .unwrap_or_else(|| "unknown".to_string());
{% else %}
        bridge.cached_name = name;
{% endif %}
        Ok(bridge)
    }

    /// Route one trait method call to the dispatcher on an attached JVM thread.
    fn __alef_dispatch(&self, method: &str, args_json: &str) -> std::result::Result<String, String> {
        let result: std::result::Result<String, jni::errors::Error> = self
            .jvm
            .attach_current_thread(|env| jni_dispatch_json(env, self.inner.as_obj(), method, args_json));
        result.map_err(|e| e.to_string())
    }
}