    fn {{ method_name }}({{ signature }}) -> {{ return_type }} {
        use extendr_api::prelude::*;

        let maybe_fn = self.r_obj.dollar("{{ method_name }}");
        let fn_robj = match maybe_fn {
            Ok(v) if !v.is_null() && !v.is_na() => v,
            _ => return {{ default_result_expr }},
        };

{% if empty_args %}
        let result = fn_robj.call(extendr_api::Pairlist::new());
{% else %}
        let args = extendr_api::Pairlist::from_pairs(&[{{ args_pairs }}]);
        let result = fn_robj.call(args);
{% endif %}

        match result {
            Err(_) => {{ default_result_expr }},
            Ok(val) => {
                if let Some(s) = val.as_str() {
                    match s {
{%- for variant in unit_result_variants %}
                        "{{ variant.wire_name }}" => {{ return_type }}::{{ variant.name }},
{%- endfor %}
                        _ => {{ unknown_string_result_expr }},
                    }
                } else if val.is_null() || val.is_na() {
                    {{ default_result_expr }}
                } else {
{%- for variant in payload_result_variants %}
                    if let Ok(custom_val) = val.dollar("{{ variant.wire_name }}") {
                        if let Some(s) = custom_val.as_str() {
                            return {{ return_type }}::{{ variant.name }}(s.to_string());
                        }
                    }
{%- endfor %}
                    {{ default_result_expr }}
                }
            }
        }
    }
