[ANN] In-tree helper crates for Rust XPCOM components

212 views
Skip to first unread message

Lina Cambridge

unread,
Mar 26, 2019, 10:28:32 AM3/26/19
to dev-pl...@lists.mozilla.org, firef...@mozilla.org
Hi all,

Last year, Nika Layzell landed support for implementing XPCOM components in
Rust [1]. Since then, folks on different teams have been adding components,
and working out some common patterns. There are now several in-tree helper
crates that provide more idiomatic wrappers for these patterns, and I
thought I'd take the time to summarize them here.

TL;DR: If you're building a new XPCOM component, please give Rust a try!
[2] The ergonomics get better with every release, and there are building
blocks to help you.

* The `xpcom` crate (`xpcom/rust/xpcom` in the tree) is the bread and
butter for a component implementation. It provides functions for creating
instances and services, and the familiar `RefPtr` for managing
reference-counted pointers.

`xpcom` also includes a set of `derive` macros for declaring your interface
implementations. Check out its docs [3] for more details and examples.

* `nserror` (`xpcom/rust/nserror`) reflects `nsresult` codes into Rust.
You'll almost always want to import this. 😊

* `nsstring` (`xpcom/rust/nsstring`) exposes bindings for XPCOM string
types. You can use the same `ns{A,C}String` types as C++ for owned
strings—there's also `ns{A, C}Str` for dependent or borrowed strings—and
pass them back and forth over the boundary.

* `moz_task` (`xpcom/rust/moz_task`) wraps XPCOM's threading functions.
There are helpers for getting and creating threads, dispatching async
runnables, and thread-safe handles. The goal of this crate is to make it
easy and safe™ to write threaded code.

* `storage` (`storage/rust`) is an interface to mozStorage, our wrapper for
SQLite. It can wrap an existing storage connection, and prepare and execute
statements. `storage` wraps the synchronous connection API, and lets you
execute statements asynchronously via `moz_task`.

* `storage_variant` (`storage/variant`) is a crate for working with
variants, and also provides a `HashPropertyBag` type that's useful for
passing hash maps over XPCOM to JS.

If you're looking for examples of how to build components, check out:

* `kvstore` (`toolkit/components/kvstore`), which exposes the LMDB
key-value store (via the Rkv library [4]). The API is asynchronous, using
`moz_task` to schedule all I/O on a background thread, and supports
getting, setting, and iterating over keys.

* `cert_storage` (`security/manager/ssl/cert_storage`), which stores lists
of revoked intermediate certificates [5].

* `bookmark_sync` (`toolkit/components/places/bookmark_sync`), which merges
[6] bookmarks from Firefox Sync with bookmarks in the Places database.

Please feel free to file bugs, extend these crates, or add your own helpers
to make it even easier to build Rust components! 🦀

Cheers,
~ lina

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1293362
[2]: https://firefox-source-docs.mozilla.org/build/buildsystem/rust.html
[3]:
https://searchfox.org/mozilla-central/rev/2c912888e3b7ae4baf161d98d7a01434f31830aa/xpcom/rust/xpcom/xpcom_macros/src/lib.rs
[4]: https://docs.rs/rkv
[5]:
https://blog.mozilla.org/security/2015/03/03/revoking-intermediate-certificates-introducing-onecrl/
[6]: https://mozilla.github.io/dogear

Joshua Cranmer 🐧

unread,
Mar 27, 2019, 8:36:06 AM3/27/19
to
On 3/26/2019 10:27 AM, Lina Cambridge wrote:
> Hi all,
>
> Last year, Nika Layzell landed support for implementing XPCOM components in
> Rust [1]. Since then, folks on different teams have been adding components,
> and working out some common patterns. There are now several in-tree helper
> crates that provide more idiomatic wrappers for these patterns, and I
> thought I'd take the time to summarize them here.
Are there any plans to add better support for Rust<->JS integration, or
mapping Rust futures back into the XPCOM world?-

Joshua Cranmer
Thunderbird and DXR developer
Source code archæologist

Reply all
Reply to author
Forward
0 new messages