This directory contains some small example components implemented using uniffi. It's currently being used more as a living test environment than user-facing docs, but hopefully it gives you a bit of an idea of what we're up to with this crate.
Newcomers are recommended to explore them in the following order:
./arithmetic/
is the most minimal example - just some plain functions that operate on integers, and some minimal error handling../arithmetic-procmacro/
is a copy of the above example implemented using procmacros - it has no UDL file norbuild.rs
script../geometry/
shows how to use records and nullable types for working with more complex data../sprites/
shows how to work with stateful objects that have methods, in classical object-oriented style../todolist
is a simplistic todo-list that can only add items and show the last item, meant to show how interacting with strings works../rondpoint
exercises complex data types by round-tripping them from the foreign-language code, through rust and back again../fxa-client
doesn't work yet, but it contains aspirational example of what the UDL might look like for an actual real-world component../async-api-client
shows how to handle async calls across the FFI. The foreign code supplies the HTTP client, the Rust code uses that client to expose a GitHub API client, then the foreign code consumes the client. All code on both sides of the FFI is async.
Each example has the following structure:
src/<namespace>.udl
, the component interface definition which defines the main object and its methods. This is processed by functions inbuild.rs
to generate Rust scaffolding for the component.src/lib.rs
, the core implementation of the component in Rust. This basically pulls in the generated Rust scaffolding viauniffi::include_scaffolding!()
and fills in function implementations.Cargo.toml
configures the crate to build acdylib
with an appropriate name.- Some small test scripts that double as API examples in each target foreign language:
- Kotlin
tests/bindings/test_<namespace>.kts
- Swift
tests/bindings/test_<namespace>.swift
- Python
tests/bindings/test_<namespace>.py
- Kotlin
If you want to try them out, you will need:
- The Kotlin command-line tools, particularly
kotlinc
. - The Java Native Access JAR downloaded and its path
added to your
$CLASSPATH
environment variable. - Python 3
- The Swift command-line tools, particularly
swift
,swiftc
and theFoundation
package. - The Ruby FFI
gem install ffi test-unit rubocop
We publish a docker image that has all of this dependencies pre-installed, if you want to get up and running quickly.
With that in place, try the following:
- Run
cargo build
. That compiles the component implementation into a native library nameduniffi_<namespace>
in../target/debug/
. - Run
cargo test
. This will run each of the foreign-language testcases against the compiled Rust code, confirming whether everything is working as intended. - Explore the build process in more detail:
- Change to the root directory of this repo, so the
uniffi-bindgen
package referenced below can be found. - Run
cargo run --bin uniffi-bindgen -- scaffolding examples/<example>/src/<namespace>.udl
. This will generate the Rust scaffolding code which exposes a C FFI for the component. You can view the generatd code in./src/<namespace>.uniffi.rs
. - Run
cargo run --bin uniffi-bindgen -- generate --language kotlin examples/<example>/src/<namespace>.udl
. This will generate the foreign-language bindings for Kotlin, which load the compiled Rust code and use the C FFI generated above to interact with it. You can view the generated code in./src/uniffi/<namespace>/<namespace>.kt
. - Try using
--language swift
or--language python
to explore the foreign-language bindings generated for other languages.
- Change to the root directory of this repo, so the