Source code
Revision control
Copy as Markdown
Other Tools
{#
// Template to call into rust. Used in several places.
// Variable names in `arg_list_decl` should match up with arg lists
// passed to rust via `arg_list_lowered`
#}
{%- macro to_ffi_call(func) -%}
{%- call is_try(func) -%}
{%- if let(Some(e)) = func.throws_type() -%}
rustCallWithError({{ e|ffi_error_converter_name }}_lift) {
{%- else -%}
rustCall() {
{%- endif %}
{{ func.ffi_func().name() }}(
{%- if func.takes_self() %}self.uniffiClonePointer(),{% endif %}
{%- call arg_list_lowered(func) -%} $0
)
}
{%- endmacro -%}
// eg, `public func foo_bar() { body }`
{%- macro func_decl(func_decl, callable, indent) %}
{%- call docstring(callable, indent) %}
{{ func_decl }} {{ callable.name()|fn_name }}(
{%- call arg_list_decl(callable) -%})
{%- call is_async(callable) %}
{%- call throws(callable) %}
{%- if let Some(return_type) = callable.return_type() %} -> {{ return_type|type_name }} {%- endif %} {
{%- call call_body(callable) %}
}
{%- endmacro %}
// primary ctor - no name, no return-type.
{%- macro ctor_decl(callable, indent) %}
{%- call docstring(callable, indent) %}
public convenience init(
{%- call arg_list_decl(callable) -%}) {%- call is_async(callable) %} {%- call throws(callable) %} {
{%- if callable.is_async() %}
let pointer =
{%- call call_async(callable) %}
{# The async mechanism returns an already constructed self.
We work around that by cloning the pointer from that object, then
assune the old object dies as there are no other references possible.
#}
.uniffiClonePointer()
{%- else %}
let pointer =
{% call to_ffi_call(callable) %}
{%- endif %}
self.init(unsafeFromRawPointer: pointer)
}
{%- endmacro %}
{%- macro call_body(callable) %}
{%- if callable.is_async() %}
return {%- call call_async(callable) %}
{%- else %}
{%- match callable.return_type() -%}
{%- when Some(return_type) %}
return {% call is_try(callable) %} {{ return_type|lift_fn }}({% call to_ffi_call(callable) %})
{%- when None %}
{%- call to_ffi_call(callable) %}
{%- endmatch %}
{%- endif %}
{%- endmacro %}
{%- macro call_async(callable) %}
{% call is_try(callable) %} await uniffiRustCallAsync(
rustFutureFunc: {
{{ callable.ffi_func().name() }}(
{%- if callable.takes_self() %}
self.uniffiClonePointer(){% if !callable.arguments().is_empty() %},{% endif %}
{% endif %}
{%- for arg in callable.arguments() -%}
{{ arg|lower_fn }}({{ arg.name()|var_name }}){% if !loop.last %},{% endif %}
{%- endfor %}
)
},
pollFunc: {{ callable.ffi_rust_future_poll(ci) }},
completeFunc: {{ callable.ffi_rust_future_complete(ci) }},
freeFunc: {{ callable.ffi_rust_future_free(ci) }},
{%- match callable.return_type() %}
{%- when Some(return_type) %}
liftFunc: {{ return_type|lift_fn }},
{%- when None %}
liftFunc: { $0 },
{%- endmatch %}
{%- match callable.throws_type() %}
{%- when Some with (e) %}
errorHandler: {{ e|ffi_error_converter_name }}_lift
{%- else %}
errorHandler: nil
{% endmatch %}
)
{%- endmacro %}
{%- macro arg_list_lowered(func) %}
{%- for arg in func.arguments() %}
{{ arg|lower_fn }}({{ arg.name()|var_name }}),
{%- endfor %}
{%- endmacro -%}
{#-
// Arglist as used in Swift declarations of methods, functions and constructors.
// Note the var_name and type_name filters.
-#}
{% macro arg_list_decl(func) %}
{%- for arg in func.arguments() -%}
{% if config.omit_argument_labels() %}_ {% endif %}{{ arg.name()|var_name }}: {{ arg|type_name -}}
{%- match arg.default_value() %}
{%- when Some with(literal) %} = {{ literal|literal_swift(arg) }}
{%- else %}
{%- endmatch %}
{%- if !loop.last %}, {% endif -%}
{%- endfor %}
{%- endmacro %}
{#-
// Field lists as used in Swift declarations of Records and Enums.
// Note the var_name and type_name filters.
-#}
{% macro field_list_decl(item, has_nameless_fields) %}
{%- for field in item.fields() -%}
{%- call docstring(field, 8) %}
{%- if has_nameless_fields %}
{{- field|type_name -}}
{%- if !loop.last -%}, {%- endif -%}
{%- else -%}
{{ field.name()|var_name }}: {{ field|type_name -}}
{%- match field.default_value() %}
{%- when Some with(literal) %} = {{ literal|literal_swift(field) }}
{%- else %}
{%- endmatch -%}
{% if !loop.last %}, {% endif %}
{%- endif -%}
{%- endfor %}
{%- endmacro %}
{% macro field_name(field, field_num) %}
{%- if field.name().is_empty() -%}
v{{- field_num -}}
{%- else -%}
{{ field.name()|var_name }}
{%- endif -%}
{%- endmacro %}
{% macro arg_list_protocol(func) %}
{%- for arg in func.arguments() -%}
{% if config.omit_argument_labels() %}_ {% endif %}{{ arg.name()|var_name }}: {{ arg|type_name -}}
{%- if !loop.last %}, {% endif -%}
{%- endfor %}
{%- endmacro %}
{%- macro is_async(func) %}
{%- if func.is_async() %}async {% endif %}
{%- endmacro -%}
{%- macro throws(func) %}
{%- if func.throws() %}throws {% endif %}
{%- endmacro -%}
{%- macro is_try(func) %}
{%- if func.throws() %}try {% else %}try! {% endif %}
{%- endmacro -%}
{%- macro docstring_value(maybe_docstring, indent_spaces) %}
{%- match maybe_docstring %}
{%- when Some(docstring) %}
{{ docstring|docstring(indent_spaces) }}
{%- else %}
{%- endmatch %}
{%- endmacro %}
{%- macro docstring(defn, indent_spaces) %}
{%- call docstring_value(defn.docstring(), indent_spaces) %}
{%- endmacro %}