-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Partial support for duplicated symbols (#143)
According to [The Big O of Code Reviews](https://www.egorand.dev/the-big-o-of-code-reviews/), this is a O(_n_) change. This PR partially fixes #68: - it re-exports each named crate as default export. - it documents working with megazords. - including the limitations of the Swift backend. The second part to fix #68 is a little more involved, but is not yet worth it: - for imported types and their converters, the bindings should use a more fully qualified name. e.g. Instead of: ```ts import { Crate1 } from "./crate1"; import crate1 from "./crate1"; const { FfiConverterTypeCrate1 } = crate1.converters; // In use type MyType = { scalar: Crate1, optional: Crate1 | undefined, list: Array<Crate1>, } // FfiConverterTypeCrate1 being used. const lift = FfiConverterTypeCrate1.lift.bind(FfiConverterTypeCrate1); ``` The next part needs to generate code: ```ts import * as crate1 from "./crate1"; // In use type MyType = { scalar: crate1.Crate1, optional: crate1.Crate1 | undefined, list: Array<crate1.Crate1>, } // FfiConverterTypeCrate1 being used. const lift = crate1.converters.FfiConverterTypeCrate1.lift.bind(crate1.converters.FfiConverterTypeCrate1); ``` I think I will file a new issue with this in, and close #68. --------- Co-authored-by: Johannes Marbach <[email protected]>
- Loading branch information
Showing
4 changed files
with
109 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# 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](https://robots.fandom.com/wiki/Mighty_Morphin%27_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: | ||
|
||
```ts | ||
import { Crate1Type, Crate2Type } from "react-native-my-megazord"; | ||
``` | ||
|
||
Alternatively, they can use the default export: | ||
|
||
```ts | ||
import megazord from "react-native-my-megazord"; | ||
|
||
const { Crate1Type } = megazord.crate1; | ||
const { Crate2Type } = megazord.crate2; | ||
``` | ||
|
||
```admonish warning title="Duplicated identifiers" | ||
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`. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* 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/ | ||
*/ | ||
|
||
import * as exported from "./playground/exported"; | ||
|
||
import { test } from "../testing/asserts"; | ||
|
||
test("Records imported as type", (t) => { | ||
const record: exported.MyRecord = { | ||
prop1: "string", | ||
prop2: 42, | ||
}; | ||
}); | ||
|
||
test("Enums imported as objects", (t) => { | ||
const enum_: exported.MyEnum = new exported.MyEnum.Variant1(); | ||
}); | ||
|
||
test("Objects interfaces imported as types", (t) => { | ||
// In our generated code, `MyObject` would not be imported into this | ||
// file because all creation happens via the `FfiConverterTypeMyObject`. | ||
const obj: exported.MyObjectInterface = new exported.MyObject(); | ||
}); | ||
|
||
test("Callback interfaces imported as types", (t) => { | ||
class Impl implements exported.MyCallbackInterface { | ||
myMethod(): void {} | ||
} | ||
|
||
const cb = new Impl(); | ||
}); | ||
|
||
test("Custom types imported as types", (t) => { | ||
const s: exported.MyCustomString = "string"; | ||
}); |