Expand description

Uniffi: easily build cross-platform software components in Rust

This is a highly-experimental crate for building cross-language software components in Rust, based on things we’ve learned and patterns we’ve developed in the mozilla/application-services project.

The idea is to let you write your code once, in Rust, and then re-use it from many other programming languages via Rust’s C-compatible FFI layer and some automagically generated binding code. If you think of it as a kind of wasm-bindgen wannabe, with a clunkier developer experience but support for more target languages, you’ll be pretty close to the mark.

Currently supported target languages include Kotlin, Swift and Python.

Usage

To build a cross-language component using uniffi, follow these steps.

1) Specify your Component Interface

Start by thinking about the interface you want to expose for use from other languages. Use the Interface Definition Language to specify your interface in a .udl file, where it can be processed by the tools from this crate. For example you might define an interface like this:

namespace example {
  u32 foo(u32 bar);
}

dictionary MyData {
  u32 num_foos;
  bool has_a_bar;
}

2) Implement the Component Interface as a Rust crate

With the interface, defined, provide a corresponding implementation of that interface as a standard-looking Rust crate, using functions and structs and so-on. For example an implementation of the above Component Interface might look like this:

fn foo(bar: u32) -> u32 {
    // TODO: a better example!
    bar + 42
}

struct MyData {
  num_foos: u32,
  has_a_bar: bool
}

3) Generate and include component scaffolding from the UDL file

First you will need to install uniffi-bindgen on your system using cargo install uniffi_bindgen. Then add to your crate uniffi_build under [build-dependencies]. Finally, add a build.rs script to your crate and have it call uniffi_build::generate_scaffolding to process your .udl file. This will generate some Rust code to be included in the top-level source code of your crate. If your UDL file is named example.udl, then your build script would call:

uniffi_build::generate_scaffolding("./src/example.udl")

This would output a rust file named example.uniffi.rs, ready to be included into the code of your rust crate like this:

include!(concat!(env!("OUT_DIR"), "/example.uniffi.rs"));

4) Generate foreign language bindings for the library

The uniffi-bindgen utility provides a command-line tool that can produce code to consume the Rust library in any of several supported languages. It is done by calling (in kotlin for example):

uniffi-bindgen --language kotlin ./src/example.udl

This will produce a file example.kt in the same directory as the .udl file, containing kotlin bindings to load and use the compiled rust code via its C-compatible FFI.

Re-exports

pub use interface::ComponentInterface;

Modules

__unused 🔒

Generate foreign language bindings for a uniffi component.

Component Interface Definition.

Structs

Cli 🔒

Scaffolding and bindings generator for Rust

Config 🔒

Binding generator config with no members

Enums

Commands 🔒

Constants

Traits

A trait representing a UniFFI Binding Generator

A trait representing a Binding Generator Configuration

Functions

Generate bindings for an external binding generator Ideally, this should replace the generate_bindings function below

get_config 🔒

Guess the root directory of the crate from the path of its UDL file.

parse_udl 🔒