Revision control
Copy as Markdown
Other Tools
{%- let type_name = type_|type_name(ci) %}
{%- let ffi_converter_name = type_|ffi_converter_name %}
{%- let canonical_type_name = type_|canonical_name %}
{% if e.is_flat() %}
{%- call kt::docstring(e, 0) %}
sealed class {{ type_name }}(message: String): kotlin.Exception(message){% if contains_object_references %}, Disposable {% endif %} {
{% for variant in e.variants() -%}
{%- call kt::docstring(variant, 4) %}
class {{ variant|error_variant_name }}(message: String) : {{ type_name }}(message)
{% endfor %}
companion object ErrorHandler : UniffiRustCallStatusErrorHandler<{{ type_name }}> {
override fun lift(error_buf: RustBuffer.ByValue): {{ type_name }} = {{ ffi_converter_name }}.lift(error_buf)
}
}
{%- else %}
{%- call kt::docstring(e, 0) %}
sealed class {{ type_name }}: kotlin.Exception(){% if contains_object_references %}, Disposable {% endif %} {
{% for variant in e.variants() -%}
{%- call kt::docstring(variant, 4) %}
{%- let variant_name = variant|error_variant_name %}
class {{ variant_name }}(
{% for field in variant.fields() -%}
{%- call kt::docstring(field, 8) %}
val {% call kt::field_name(field, loop.index) %}: {{ field|type_name(ci) }}{% if loop.last %}{% else %}, {% endif %}
{% endfor -%}
) : {{ type_name }}() {
override val message
get() = "{%- for field in variant.fields() %}{% call kt::field_name_unquoted(field, loop.index) %}=${ {% call kt::field_name(field, loop.index) %} }{% if !loop.last %}, {% endif %}{% endfor %}"
}
{% endfor %}
companion object ErrorHandler : UniffiRustCallStatusErrorHandler<{{ type_name }}> {
override fun lift(error_buf: RustBuffer.ByValue): {{ type_name }} = {{ ffi_converter_name }}.lift(error_buf)
}
{% if contains_object_references %}
@Suppress("UNNECESSARY_SAFE_CALL") // codegen is much simpler if we unconditionally emit safe calls here
override fun destroy() {
when(this) {
{%- for variant in e.variants() %}
is {{ type_name }}.{{ variant|error_variant_name }} -> {
{%- if variant.has_fields() %}
{% call kt::destroy_fields(variant) %}
{% else -%}
// Nothing to destroy
{%- endif %}
}
{%- endfor %}
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
}
{% endif %}
}
{%- endif %}
/**
* @suppress
*/
public object {{ e|ffi_converter_name }} : FfiConverterRustBuffer<{{ type_name }}> {
override fun read(buf: ByteBuffer): {{ type_name }} {
{% if e.is_flat() %}
return when(buf.getInt()) {
{%- for variant in e.variants() %}
{{ loop.index }} -> {{ type_name }}.{{ variant|error_variant_name }}({{ Type::String.borrow()|read_fn }}(buf))
{%- endfor %}
else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
}
{% else %}
return when(buf.getInt()) {
{%- for variant in e.variants() %}
{{ loop.index }} -> {{ type_name }}.{{ variant|error_variant_name }}({% if variant.has_fields() %}
{% for field in variant.fields() -%}
{{ field|read_fn }}(buf),
{% endfor -%}
{%- endif -%})
{%- endfor %}
else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
}
{%- endif %}
}
override fun allocationSize(value: {{ type_name }}): ULong {
{%- if e.is_flat() %}
return 4UL
{%- else %}
return when(value) {
{%- for variant in e.variants() %}
is {{ type_name }}.{{ variant|error_variant_name }} -> (
// Add the size for the Int that specifies the variant plus the size needed for all fields
4UL
{%- for field in variant.fields() %}
+ {{ field|allocation_size_fn }}(value.{% call kt::field_name(field, loop.index) %})
{%- endfor %}
)
{%- endfor %}
}
{%- endif %}
}
override fun write(value: {{ type_name }}, buf: ByteBuffer) {
when(value) {
{%- for variant in e.variants() %}
is {{ type_name }}.{{ variant|error_variant_name }} -> {
buf.putInt({{ loop.index }})
{%- for field in variant.fields() %}
{{ field|write_fn }}(value.{% call kt::field_name(field, loop.index) %}, buf)
{%- endfor %}
Unit
}
{%- endfor %}
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
}
}