<div dir="ltr">Hi all,<br><div dir="ltr"><br>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.<br><br>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.<br><br>* 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.<br><br>`xpcom` also includes a set of `derive` macros for declaring your interface implementations. Check out its docs [3] for more details and examples.<br><br>* `nserror` (`xpcom/rust/nserror`) reflects `nsresult` codes into Rust. You'll almost always want to import this. šŸ˜Š<br><br>* `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.<br><br>* `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.<br><br>* `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`.<br><br>* `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.<br><br>If you're looking for examples of how to build components, check out:<br><br>* `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.<br><br>* `cert_storage` (`security/manager/ssl/cert_storage`), which stores lists of revoked intermediate certificates [5].<br><br>* `bookmark_sync` (`toolkit/components/places/bookmark_sync`), which merges [6] bookmarks from Firefox Sync with bookmarks in the Places database.<br><br>Please feel free to file bugs, extend these crates, or add your own helpers to make it even easier to build Rust components! šŸ¦€<br><br>Cheers,<br>~ lina<br><br>[1]: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1293362">https://bugzilla.mozilla.org/show_bug.cgi?id=1293362</a><br>[2]: <a href="https://firefox-source-docs.mozilla.org/build/buildsystem/rust.html">https://firefox-source-docs.mozilla.org/build/buildsystem/rust.html</a><br>[3]: <a href="https://searchfox.org/mozilla-central/rev/2c912888e3b7ae4baf161d98d7a01434f31830aa/xpcom/rust/xpcom/xpcom_macros/src/lib.rs">https://searchfox.org/mozilla-central/rev/2c912888e3b7ae4baf161d98d7a01434f31830aa/xpcom/rust/xpcom/xpcom_macros/src/lib.rs</a><br>[4]: <a href="https://docs.rs/rkv">https://docs.rs/rkv</a><br>[5]: <a href="https://blog.mozilla.org/security/2015/03/03/revoking-intermediate-certificates-introducing-onecrl/">https://blog.mozilla.org/security/2015/03/03/revoking-intermediate-certificates-introducing-onecrl/</a><br>[6]: <a href="https://mozilla.github.io/dogear">https://mozilla.github.io/dogear</a><br></div></div>