Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- `--lib-file` and `--library` CLI generator options removed, they're both now automatically detected by uniffi
- Java callback interface implementations must now use primitive types (e.g., `int`, `long`, `boolean`) instead of boxed types (`Integer`, `Long`, `Boolean`) for non-optional primitive parameters and return types
- use Java primitive types (`int`, `long`, `boolean`, etc.) instead of boxed types (`Integer`, `Long`, `Boolean`) for non-optional primitive parameters, return types, and record fields. Optional primitives and primitives in generic contexts (e.g., `List<Integer>`, `CompletableFuture<Integer>`) still use boxed types as required by Java.
- use primitive arrays where possible (similar to how `Vec<u8> -> bytes[]`). This should reduce GC pressure and speed up copies across the boundary via `AsBuffer` instead of iteration. There's a potentially small ergonomic hit to those doing a lot of data transformation, not just passing values to and from the Rust side. If you're someone this negatively impacts, reach out and we can talk about adding a `use_primitive_arrays` config option.

## 0.2.1

Expand Down
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ uniffi-example-rondpoint = { git = "https://github.com/mozilla/uniffi-rs.git", t
uniffi-fixture-coverall = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
uniffi-fixture-ext-types = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
uniffi-fixture-futures = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
uniffi-fixture-primitive-arrays = { path = "fixtures/primitive-arrays" }
uniffi-fixture-proc-macro = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
uniffi-fixture-rename = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
uniffi-fixture-time = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
Expand Down
11 changes: 11 additions & 0 deletions fixtures/primitive-arrays/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "uniffi-fixture-primitive-arrays"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib", "lib"]
name = "uniffi_fixture_primitive_arrays"

[dependencies]
uniffi = { git = "https://github.com/mozilla/uniffi-rs.git", tag = "v0.31.0" }
87 changes: 87 additions & 0 deletions fixtures/primitive-arrays/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

uniffi::setup_scaffolding!("primitive_arrays");

// Float32 (float[]) operations
#[uniffi::export]
fn roundtrip_float32(data: Vec<f32>) -> Vec<f32> {
data
}

#[uniffi::export]
fn sum_float32(data: Vec<f32>) -> f32 {
data.iter().sum()
}

// Float64 (double[]) operations
#[uniffi::export]
fn roundtrip_float64(data: Vec<f64>) -> Vec<f64> {
data
}

#[uniffi::export]
fn sum_float64(data: Vec<f64>) -> f64 {
data.iter().sum()
}

// Int16 (short[]) operations
#[uniffi::export]
fn roundtrip_int16(data: Vec<i16>) -> Vec<i16> {
data
}

#[uniffi::export]
fn sum_int16(data: Vec<i16>) -> i16 {
data.iter().sum()
}

// Int32 (int[]) operations
#[uniffi::export]
fn roundtrip_int32(data: Vec<i32>) -> Vec<i32> {
data
}

#[uniffi::export]
fn sum_int32(data: Vec<i32>) -> i32 {
data.iter().sum()
}

// Int64 (long[]) operations
#[uniffi::export]
fn roundtrip_int64(data: Vec<i64>) -> Vec<i64> {
data
}

#[uniffi::export]
fn sum_int64(data: Vec<i64>) -> i64 {
data.iter().sum()
}

// Boolean (boolean[]) operations
#[uniffi::export]
fn roundtrip_bool(data: Vec<bool>) -> Vec<bool> {
data
}

#[uniffi::export]
fn count_true(data: Vec<bool>) -> i32 {
data.iter().filter(|&&b| b).count() as i32
}

// UInt variants to test unsigned handling
#[uniffi::export]
fn roundtrip_uint16(data: Vec<u16>) -> Vec<u16> {
data
}

#[uniffi::export]
fn roundtrip_uint32(data: Vec<u32>) -> Vec<u32> {
data
}

#[uniffi::export]
fn roundtrip_uint64(data: Vec<u64>) -> Vec<u64> {
data
}
27 changes: 27 additions & 0 deletions src/gen_java/compounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,30 @@ impl CodeType for MapCodeType {
)
}
}

// Primitive array types for sequences of primitives.
// These generate Java primitive arrays (e.g., float[], int[]) instead of List<Boxed>.

macro_rules! impl_primitive_array_code_type {
($name:ident, $type_label:literal, $canonical_name:literal) => {
#[derive(Debug)]
pub struct $name;

impl CodeType for $name {
fn type_label(&self, _ci: &ComponentInterface, _config: &Config) -> String {
$type_label.into()
}

fn canonical_name(&self) -> String {
$canonical_name.into()
}
}
};
}

impl_primitive_array_code_type!(Int16ArrayCodeType, "short[]", "Int16Array");
impl_primitive_array_code_type!(Int32ArrayCodeType, "int[]", "Int32Array");
impl_primitive_array_code_type!(Int64ArrayCodeType, "long[]", "Int64Array");
impl_primitive_array_code_type!(Float32ArrayCodeType, "float[]", "Float32Array");
impl_primitive_array_code_type!(Float64ArrayCodeType, "double[]", "Float64Array");
impl_primitive_array_code_type!(BooleanArrayCodeType, "boolean[]", "BooleanArray");
Loading
Loading