2 // Kotlin's `enum class` construct doesn't support variants with associated data,
3 // but is a little nicer for consumers than its `sealed class` enum pattern.
4 // So, we switch here, using `enum class` for enums with no associated data
5 // and `sealed class` for the general case.
10 enum class {{ type_name }} {
11 {% for variant in e.variants() -%}
12 {{ variant|variant_name }}{% if loop.last %};{% else %},{% endif %}
17 public object {{ e|ffi_converter_name }}: FfiConverterRustBuffer<{{ type_name }}> {
18 override fun read(buf: ByteBuffer) = try {
19 {{ type_name }}.values()[buf.getInt() - 1]
20 } catch (e: IndexOutOfBoundsException) {
21 throw RuntimeException("invalid enum value, something is very wrong!!", e)
24 override fun allocationSize(value: {{ type_name }}) = 4
26 override fun write(value: {{ type_name }}, buf: ByteBuffer) {
27 buf.putInt(value.ordinal + 1)
33 sealed class {{ type_name }}{% if contains_object_references %}: Disposable {% endif %} {
34 {% for variant in e.variants() -%}
35 {% if !variant.has_fields() -%}
36 object {{ variant|type_name(ci) }} : {{ type_name }}()
38 data class {{ variant|type_name(ci) }}(
39 {% for field in variant.fields() -%}
40 val {{ field.name()|var_name }}: {{ field|type_name(ci) }}{% if loop.last %}{% else %}, {% endif %}
42 ) : {{ type_name }}() {
48 {% if contains_object_references %}
49 @Suppress("UNNECESSARY_SAFE_CALL") // codegen is much simpler if we unconditionally emit safe calls here
50 override fun destroy() {
52 {%- for variant in e.variants() %}
53 is {{ type_name }}.{{ variant|type_name(ci) }} -> {
54 {%- if variant.has_fields() %}
55 {% call kt::destroy_fields(variant) %}
61 }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
67 public object {{ e|ffi_converter_name }} : FfiConverterRustBuffer<{{ type_name }}>{
68 override fun read(buf: ByteBuffer): {{ type_name }} {
69 return when(buf.getInt()) {
70 {%- for variant in e.variants() %}
71 {{ loop.index }} -> {{ type_name }}.{{ variant|type_name(ci) }}{% if variant.has_fields() %}(
72 {% for field in variant.fields() -%}
73 {{ field|read_fn }}(buf),
77 else -> throw RuntimeException("invalid enum value, something is very wrong!!")
81 override fun allocationSize(value: {{ type_name }}) = when(value) {
82 {%- for variant in e.variants() %}
83 is {{ type_name }}.{{ variant|type_name(ci) }} -> {
84 // Add the size for the Int that specifies the variant plus the size needed for all fields
87 {%- for field in variant.fields() %}
88 + {{ field|allocation_size_fn }}(value.{{ field.name()|var_name }})
95 override fun write(value: {{ type_name }}, buf: ByteBuffer) {
97 {%- for variant in e.variants() %}
98 is {{ type_name }}.{{ variant|type_name(ci) }} -> {
99 buf.putInt({{ loop.index }})
100 {%- for field in variant.fields() %}
101 {{ field|write_fn }}(value.{{ field.name()|var_name }}, buf)
106 }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }