Команда синхронизации Mozilla использовала общие Rust-компоненты для нескольких платформ, но ручные обвязки для JavaScript, Kotlin и Swift требовали большого сопровождения. В инженерном разборе объясняется, как генератор UniFFI помог сократить эту работу.
Два уровня интерфейса
Нижний слой UniFFI предоставляет функции через C ABI. Поверх него создаётся удобный интерфейс для конкретного языка. В Firefox генерация C++ и WebIDL обслуживала именно нижний слой, а пользовательский API был реализован на JavaScript: ограничения WebIDL при этом не определяли возможности всего интерфейса.
Почему вызовы возвращают Promise
В описанной интеграции блокирующие обращения к Rust нельзя было выполнять в главном потоке интерфейса. Поэтому JavaScript-вызовы возвращают Promise, а работа выполняется в пуле потоков. Это архитектурное решение конкретной интеграции, а не общее требование делать любую быструю функцию асинхронной.
Поддержка UniFFI была внедрена в движке синхронизации, который стал примером общего компонента для Desktop, Android и iOS с обвязками на трёх языках.