From bd83dbe0852724936c5d8a11e91ceb65f5aa6804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 12 Jul 2024 18:54:27 +0200 Subject: [PATCH] Add `use_enum_entries` configuration option to enable the `EnumClass.entries` usage on `Kotlin >= 1.9.0` and keep backwards compatibility with previous versions --- docs/manual/src/kotlin/configuration.md | 17 +++++++++-------- .../src/bindings/kotlin/gen_kotlin/mod.rs | 6 ++++++ .../bindings/kotlin/templates/EnumTemplate.kt | 4 ++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/manual/src/kotlin/configuration.md b/docs/manual/src/kotlin/configuration.md index 19ae2a745b..029baba415 100644 --- a/docs/manual/src/kotlin/configuration.md +++ b/docs/manual/src/kotlin/configuration.md @@ -4,15 +4,16 @@ The generated Kotlin modules can be configured using a `uniffi.toml` configurati ## Available options -| Configuration name | Default | Description | -| ------------------ | ------- |------------ | -| `package_name` | `uniffi` | The Kotlin package name - ie, the value used in the `package` statement at the top of generated files. | -| `cdylib_name` | `uniffi_{namespace}`[^1] | The name of the compiled Rust library containing the FFI implementation (not needed when using `generate --library`). | +| Configuration name | Default | Description | +|------------------------------| ------- |------------ | +| `package_name` | `uniffi` | The Kotlin package name - ie, the value used in the `package` statement at the top of generated files. | +| `cdylib_name` | `uniffi_{namespace}`[^1] | The name of the compiled Rust library containing the FFI implementation (not needed when using `generate --library`). | | `generate_immutable_records` | `false` | Whether to generate records with immutable fields (`val` instead of `var`). | -| `custom_types` | | A map which controls how custom types are exposed to Kotlin. See the [custom types section of the manual](../udl/custom_types.md#custom-types-in-the-bindings-code)| -| `external_packages` | | A map of packages to be used for the specified external crates. The key is the Rust crate name, the value is the Kotlin package which will be used referring to types in that crate. See the [external types section of the manual](../udl/ext_types_external.md#kotlin) -| `android` | `false` | Used to toggle on Android specific optimizations -| `android_cleaner` | `android` | Use the [`android.system.SystemCleaner`](https://developer.android.com/reference/android/system/SystemCleaner) instead of [`java.lang.ref.Cleaner`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ref/Cleaner.html). Fallback in both instances is the one shipped with JNA. +| `custom_types` | | A map which controls how custom types are exposed to Kotlin. See the [custom types section of the manual](../udl/custom_types.md#custom-types-in-the-bindings-code)| +| `external_packages` | | A map of packages to be used for the specified external crates. The key is the Rust crate name, the value is the Kotlin package which will be used referring to types in that crate. See the [external types section of the manual](../udl/ext_types_external.md#kotlin) +| `android` | `false` | Used to toggle on Android specific optimizations +| `android_cleaner` | `android` | Use the [`android.system.SystemCleaner`](https://developer.android.com/reference/android/system/SystemCleaner) instead of [`java.lang.ref.Cleaner`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ref/Cleaner.html). Fallback in both instances is the one shipped with JNA. +| `use_enum_entries` | `false` | Uses `EnumClass.entries` instead of `EnumClass.values()` in the bindings, which is more efficient as it reuses the same list instance every time. Note this is only available since Kotlin 1.9.0 ## Example diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs index e6faf8ddfa..d979f9ece7 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs @@ -82,12 +82,18 @@ pub struct Config { android: bool, #[serde(default)] android_cleaner: Option, + #[serde(default)] + use_enum_entries: bool, } impl Config { pub(crate) fn android_cleaner(&self) -> bool { self.android_cleaner.unwrap_or(self.android) } + + pub(crate) fn use_enum_entries(&self) -> bool { + self.use_enum_entries + } } #[derive(Debug, Default, Clone, Serialize, Deserialize)] diff --git a/uniffi_bindgen/src/bindings/kotlin/templates/EnumTemplate.kt b/uniffi_bindgen/src/bindings/kotlin/templates/EnumTemplate.kt index 653c7d7dc8..1c17799633 100644 --- a/uniffi_bindgen/src/bindings/kotlin/templates/EnumTemplate.kt +++ b/uniffi_bindgen/src/bindings/kotlin/templates/EnumTemplate.kt @@ -29,7 +29,11 @@ enum class {{ type_name }}(val value: {{ variant_discr_type|type_name(ci) }}) { public object {{ e|ffi_converter_name }}: FfiConverterRustBuffer<{{ type_name }}> { override fun read(buf: ByteBuffer) = try { + {% if config.use_enum_entries() %} {{ type_name }}.entries[buf.getInt() - 1] + {% else -%} + {{ type_name }}.values()[buf.getInt() - 1] + {%- endif %} } catch (e: IndexOutOfBoundsException) { throw RuntimeException("invalid enum value, something is very wrong!!", e) }