alef 0.32.11

Opinionated polyglot binding generator for Rust libraries
Documentation
{% if not has_error %}
// This method's Rust signature is infallible, so a host failure cannot
// propagate. eprintln! is invisible in browsers, so log to the JS console
// before substituting the default — a silent default is indistinguishable
// from a real result to the caller.
fn __log_host_failure(msg: &str) {
    let global = js_sys::global();
    if let Ok(console) = js_sys::Reflect::get(&global, &wasm_bindgen::JsValue::from_str("console")) {
        if let Ok(error_fn) = js_sys::Reflect::get(&console, &wasm_bindgen::JsValue::from_str("error")) {
            if let Ok(error_fn) = error_fn.dyn_into::<js_sys::Function>() {
                let _ = error_fn.call1(&console, &wasm_bindgen::JsValue::from_str(msg));
            }
        }
    }
}
{% endif %}
let key = wasm_bindgen::JsValue::from_str("{{ js_name }}");
let has_method = js_sys::Reflect::has(&self.inner, &key).unwrap_or(false);
if !has_method {
{% if has_error %}
    return Err({{ error_expr }});
{% else %}
    __log_host_failure("[{{ wrapper }}] host method '{{ js_name }}' is missing; returning default");
    return Default::default();
{% endif %}
}

{% if has_error %}
let func_val = js_sys::Reflect::get(&self.inner, &key)
    .map_err(|_| {{ error_get_method }})?;
{% else %}
let func_val = match js_sys::Reflect::get(&self.inner, &key) {
    Ok(f) => f,
    Err(e) => {
        __log_host_failure(&format!("[{{ wrapper }}] failed to get host method '{{ js_name }}'; returning default: {e:?}"));
        return Default::default();
    }
};
{% endif %}

{% if has_error %}
let func: js_sys::Function = func_val.dyn_into()
    .map_err(|_| {{ error_dyn_into }})?;
{% else %}
let func: js_sys::Function = match func_val.dyn_into() {
    Ok(f) => f,
    Err(_) => {
        __log_host_failure("[{{ wrapper }}] host '{{ js_name }}' is not a function; returning default");
        return Default::default();
    }
};
{% endif %}

// Build args array
let args = js_sys::Array::new();
{% for param in params %}
args.push(&{{ param }});
{% endfor %}

// Call the function
{% if has_error %}
let result = func.apply(&self.inner, &args)
    .map_err(|_| {{ error_apply }})?;
{% else %}
let result = match func.apply(&self.inner, &args) {
    Ok(r) => r,
    Err(e) => {
        __log_host_failure(&format!("[{{ wrapper }}] host '{{ js_name }}' threw; returning default: {e:?}"));
        return Default::default();
    }
};
{% endif %}

// Convert result
{% if return_unit %}
{% if has_error %}
Ok(())
{% else %}
()
{% endif %}
{% elif return_string %}
{% if has_error %}
result.as_string()
    .ok_or_else(|| {{ error_string_conv }})
{% else %}
match result.as_string() {
    Some(s) => s,
    None => {
        __log_host_failure("[{{ wrapper }}] host '{{ js_name }}' returned a non-string value; returning default");
        Default::default()
    }
}
{% endif %}
{% elif return_bool %}
// Convert JS boolean to Rust bool
{% if has_error %}
result.as_bool()
    .ok_or_else(|| {{ error_result_conv }})
{% else %}
match result.as_bool() {
    Some(b) => b,
    None => {
        __log_host_failure("[{{ wrapper }}] host '{{ js_name }}' returned a non-boolean value; returning default");
        Default::default()
    }
}
{% endif %}
{% elif return_enum %}
// Convert bare enum string (non-JSON) to {{ ret_ty }}
{% if has_error %}
result.as_string()
    .ok_or_else(|| {{ error_result_conv }})
    .and_then(|s| serde_json::from_str::<{{ ret_ty }}>(&format!("\"{}\"", s)).map_err(|e| {{ error_deser }}))
{% else %}
match result.as_string() {
    Some(s) => match serde_json::from_str::<{{ ret_ty }}>(&format!("\"{}\"", s)) {
        Ok(v) => v,
        Err(e) => {
            __log_host_failure(&format!("[{{ wrapper }}] host '{{ js_name }}' returned an unparseable value; returning default: {e}"));
            Default::default()
        }
    },
    None => {
        __log_host_failure("[{{ wrapper }}] host '{{ js_name }}' returned a non-string value; returning default");
        Default::default()
    }
}
{% endif %}
{% else %}
// Convert JS result to {{ ret_ty }}
{% if has_error %}
result.as_string()
    .ok_or_else(|| {{ error_result_conv }})
    .and_then(|s| serde_json::from_str::<{{ ret_ty }}>(&s).map_err(|e| {{ error_deser }}))
{% else %}
match result.as_string() {
    Some(s) => match serde_json::from_str::<{{ ret_ty }}>(&s) {
        Ok(v) => v,
        Err(e) => {
            __log_host_failure(&format!("[{{ wrapper }}] host '{{ js_name }}' returned an unparseable value; returning default: {e}"));
            Default::default()
        }
    },
    None => {
        __log_host_failure("[{{ wrapper }}] host '{{ js_name }}' returned a non-string value; returning default");
        Default::default()
    }
}
{% endif %}
{% endif %}