Skip to content

Commit

Permalink
Implement rondpoint types (#3)
Browse files Browse the repository at this point in the history
* Add byte/UInt8/Int8 types, add start of rondpoint

Also updates to current main of uniffi, removing `BindingsConfig` struct

* Add more numeric primitives, object

* Optionals and Sequences

* Map and Record

(and actually sequence and optional, forgot to add before)

Now generating but not compiling on the Java side yet

* Add object cleaners, fix broken Java

* Generate `record` files

* More compiling Maps, Sequences, Enums

Still missing Optional FfiConverters from the generation for some reason

* Compiling, following test failures

* Working minimal rondpoint test!

* All tested and passing except optional defaults.

Need to settle on how we want to handle default parameters.

* Commit to no defaults

* Add JNA to flake

* Add to testing doc

* Clear up a bunch of the TODOs that were decided

* Going with immutable records by default

* Add geometry example test

* Code review change

* Add CI

* Add JNA to CI

* Try to force CI onto Java 21

* Case matters

* Testing

* Newer Ubuntu version to get newer JNA version
  • Loading branch information
skeet70 authored May 28, 2024
1 parent 23c9627 commit f0450c5
Show file tree
Hide file tree
Showing 40 changed files with 1,395 additions and 244 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/rust-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Rust CI
'on':
push:
branches:
- main
pull_request: null
workflow_dispatch: null
schedule:
- cron: 0 14 * * 1
jobs:
rust-ci:
uses: IronCoreLabs/workflows/.github/workflows/rust-ci.yaml@rust-ci-v2
with:
# enable once initial implementation is done
run_clippy: false
minimum_coverage: "0"
additional_system_deps: "libjna-java"
cargo_command_env_vars: "PATH=$JAVA_HOME_21_X64/bin:$PATH CLASSPATH=/usr/share/java/jna.jar"
secrets: inherit
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
.direnv
*.class
59 changes: 32 additions & 27 deletions Cargo.lock

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

18 changes: 10 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@ path = "src/main.rs"

[dependencies]
anyhow = "1"
askama = { version = "0.12", default-features = false, features = ["config"]}
clap = { version = "4", default-features = false, features = ["derive", "std", "cargo"]}
askama = { version = "0.12", default-features = false, features = ["config"] }
camino = "1.1.6"
clap = { version = "4", default-features = false, features = ["derive", "std", "cargo"] }
heck = "0.5"
uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
paste = "1"
regex = "1.10.4"
serde = "1"
textwrap = "0.16.1"
toml = "0.5" # can't be on 8, `Value` is part of public interface
uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
uniffi_meta = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
textwrap = "0.16.1"
camino = "1.1.6"
regex = "1.10.4"

[dev-dependencies]
cargo_metadata = "0.18.1"
glob = "0.3"
uniffi_testing = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
uniffi-example-arithmetic = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
cargo_metadata = "0.18.1"
uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
uniffi-example-rondpoint = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }
uniffi_testing = { git = "https://github.com/mozilla/uniffi-rs.git", branch = "main" }


9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
## Requirements

* Java 20+: `javac`, and `jar`
* The [Java Native Access](https://github.com/java-native-access/jna#download) JAR downloaded and its path
added to your `$CLASSPATH` environment variable.
* The [Java Native Access](https://github.com/java-native-access/jna#download) JAR downloaded and its path added to your `$CLASSPATH` environment variable.

## Unsupported features

* Defaults aren't supported in Java so [uniffi struct, method, and function defaults](https://mozilla.github.io/uniffi-rs/proc_macro/index.html#default-values) don't exist in the Java code. *Note*: a reasonable case could be made for supporting defaults on structs by way of generated builder patterns. PRs welcome.

## Testing

We pull down the pinned examples directly from Uniffi and run Java tests using the generated bindings. Just run `cargo t` to run all of them.
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# nix develop
devShell = pkgs.mkShell {
buildInputs = with pkgs;
[ rusttoolchain pkg-config openjdk21 ]
[ rusttoolchain pkg-config openjdk21 jna ]
++ lib.optionals stdenv.isDarwin
[ darwin.apple_sdk.frameworks.SystemConfiguration ];
};
Expand Down
129 changes: 129 additions & 0 deletions src/gen_java/compounds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/* 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/. */

use super::{AsCodeType, CodeType};
use uniffi_bindgen::{
backend::{Literal, Type},
ComponentInterface,
};

#[derive(Debug)]
pub struct OptionalCodeType {
inner: Type,
}

impl OptionalCodeType {
pub fn new(inner: Type) -> Self {
Self { inner }
}
fn inner(&self) -> &Type {
&self.inner
}
}

impl CodeType for OptionalCodeType {
fn type_label(&self, ci: &ComponentInterface) -> String {
super::JavaCodeOracle
.find(self.inner())
.type_label(ci)
.to_string()
}

fn canonical_name(&self) -> String {
format!(
"Optional{}",
super::JavaCodeOracle.find(self.inner()).canonical_name()
)
}

fn literal(&self, literal: &Literal, ci: &ComponentInterface) -> String {
match literal {
Literal::None => "null".into(),
Literal::Some { inner } => super::JavaCodeOracle.find(&self.inner).literal(inner, ci),
_ => panic!("Invalid literal for Optional type: {literal:?}"),
}
}
}

#[derive(Debug)]
pub struct SequenceCodeType {
inner: Type,
}

impl SequenceCodeType {
pub fn new(inner: Type) -> Self {
Self { inner }
}
fn inner(&self) -> &Type {
&self.inner
}
}

impl CodeType for SequenceCodeType {
fn type_label(&self, ci: &ComponentInterface) -> String {
format!(
"List<{}>",
super::JavaCodeOracle.find(self.inner()).type_label(ci)
)
}

fn canonical_name(&self) -> String {
format!(
"Sequence{}",
super::JavaCodeOracle.find(self.inner()).canonical_name()
)
}

fn literal(&self, literal: &Literal, _ci: &ComponentInterface) -> String {
match literal {
Literal::EmptySequence => "List.of()".into(),
_ => panic!("Invalid literal for List type: {literal:?}"),
}
}
}

#[derive(Debug)]
pub struct MapCodeType {
key: Type,
value: Type,
}

impl MapCodeType {
pub fn new(key: Type, value: Type) -> Self {
Self { key, value }
}

fn key(&self) -> &Type {
&self.key
}

fn value(&self) -> &Type {
&self.value
}
}

impl CodeType for MapCodeType {
fn type_label(&self, ci: &ComponentInterface) -> String {
format!(
"Map<{}, {}>",
super::JavaCodeOracle.find(self.key()).type_label(ci),
super::JavaCodeOracle.find(self.value()).type_label(ci),
)
}

fn canonical_name(&self) -> String {
format!(
"Map{}{}",
self.key().as_codetype().canonical_name(),
self.value().as_codetype().canonical_name(),
)
}

fn literal(&self, literal: &Literal, _ci: &ComponentInterface) -> String {
match literal {
Literal::EmptyMap => "Map.of()".into(),
_ => panic!("Invalid literal for Map type: {literal:?}"),
}
}
}
Loading

0 comments on commit f0450c5

Please sign in to comment.