Working with multiple crates in one library
Some teams arrange their Rust library in to multiple crates, or multiple teams from one organization combine their efforts into one library.
This might be for better code organization, or to reduce shipping multiple copies of the same dependencies.
The combined library from multiple crates, in Mozilla vernacular, is known as a Megazord.
uniffi-rs
and uniffi-bindgen-react-native
both work well with Megazords.
uniffi-bindgen-react-native
produces a cluster of files per crate. For example, generating files from the library libmymegazord.a
might contain two crates, crate1
and crate2
. The library directory would look like this:
cpp
├── generated
│ ├── crate1.cpp
│ ├── crate1.hpp
│ ├── crate2.cpp
│ └── crate2.hpp
├── react-native-my-megazord.cpp
└── react-native-my-megazord.h
src
├── NativeMyMegazord.ts
├── generated
│ ├── crate1.ts
│ ├── crate1-ffi.ts
│ ├── crate2.ts
│ └── crate2-ffi.ts
└── index.tsx
In index.tsx
, the types are re-exported from crate1.ts
and crate2.ts
.
In this extended example, crate1.ts
might declare a Crate1Type
and crate2.ts
a Crate2Type
.
In this case, your library’s client code would import Crate1Type
and Crate2Type
like this:
import { Crate1Type, Crate2Type } from "react-native-my-megazord";
Alternatively, they can use the default export:
import megazord from "react-native-my-megazord";
const { Crate1Type } = megazord.crate1;
const { Crate2Type } = megazord.crate2;
Due to Swift’s large granular module sytem, crates in the same megazord cannot have types of the same name.
This may be solved in Swift at some point— e.g. by adding prefixes— but until then, duplicate identifiers will cause a Typescript compilation error as the types are smooshed together in index.tsx
.