summaryrefslogtreecommitdiffstats
path: root/docs/writing-rust-code/basics.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/writing-rust-code/basics.md')
-rw-r--r--docs/writing-rust-code/basics.md84
1 files changed, 84 insertions, 0 deletions
diff --git a/docs/writing-rust-code/basics.md b/docs/writing-rust-code/basics.md
new file mode 100644
index 0000000000..d91288133b
--- /dev/null
+++ b/docs/writing-rust-code/basics.md
@@ -0,0 +1,84 @@
+# Basics
+
+## Formatting Rust code
+
+To format all the Rust code within a directory `$DIR`, run:
+```
+./mach lint -l rustfmt --fix $DIR
+```
+
+## Using Cargo
+
+Many Cargo commands can be run on individual crates. Change into the directory
+containing the crate's `Cargo.toml` file, and then run the command with
+`MOZ_TOPOBJDIR` set appropriately. For example, to generate and view rustdocs
+for the `xpcom` crate, run these commands:
+
+```
+cd xpcom/rust/xpcom
+MOZ_TOPOBJDIR=$OBJDIR cargo doc
+cd -
+firefox target/doc/xpcom/index.html
+```
+where `$OBJDIR` is the path to the object directory.
+
+## Using static prefs
+
+Static boolean/integer prefs can be easily accessed from Rust code. Add a
+`rust: true` field to the pref definition in
+[modules/libpref/init/StaticPrefList.yaml](https://searchfox.org/mozilla-central/source/modules/libpref/init/StaticPrefList.yaml),
+like this:
+```yaml
+- name: my.lucky.pref
+ type: RelaxedAtomicBool
+ value: true
+ mirror: always
+ rust: true
+```
+The pref can then be accessed via the `pref!` macro, like this:
+```
+let my_lucky_pref = static_prefs::pref!("my.lucky.pref");
+```
+
+## Helper crates
+
+The following in-tree helper crates provide idiomatic support for some common patterns.
+- [nserror](https://searchfox.org/mozilla-central/source/xpcom/rust/nserror/src/lib.rs)
+reflects `nsresult` codes into Rust.
+- [nsstring](https://searchfox.org/mozilla-central/source/xpcom/rust/nsstring/src/lib.rs)
+ exposes bindings for XPCOM string types. You can use the same `ns{A,C}String`
+ types as C++ for owned strings and pass them back and forth over the
+ boundary. There is also `ns{A,C}Str` for dependent or borrowed strings.
+- [xpcom](https://searchfox.org/mozilla-central/source/xpcom/rust/xpcom/src)
+ provides multiple building blocks for a component's implementation.
+ - The `RefPtr` type is for managing reference-counted pointers.
+ - XPCOM component getters are generated by
+ [xpcom/components/gen_static_components.py](https://searchfox.org/mozilla-central/source/xpcom/components/gen_static_components.py),
+ and can be called like this:
+ ```
+ use xpcom::{interfaces::nsIPrefService, RefPtr};
+ let pref_service: RefPtr<nsIPrefService> = xpcom::components::Preferences::service()?;
+ ```
+ - There is also a `get_service` function that works like `do_GetService` in
+ C++, as an alternative.
+ - A set of `derive` macros help with declaring interface implementations. The
+ [docs](https://searchfox.org/mozilla-central/source/xpcom/rust/xpcom/xpcom_macros/src/lib.rs)
+ have details and examples.
+- [moz_task](https://searchfox.org/mozilla-central/source/xpcom/rust/moz_task/src/lib.rs)
+ wraps XPCOM's threading functions in order to make it easy and safe to write
+ threaded code. It has helpers for getting and creating threads, dispatching
+ async runnables, and thread-safe handles.
+- [storage](https://searchfox.org/mozilla-central/source/storage/rust/src/lib.rs)
+ is an interface to mozStorage, our wrapper for SQLite. It can wrap an
+ existing storage connection, and prepare and execute statements. This crate
+ wraps the synchronous connection API, and lets you execute statements
+ asynchronously via `moz_task`.
+- [storage_variant](https://searchfox.org/mozilla-central/source/storage/variant/src/lib.rs)
+ is for working with variants. It also provides a `HashPropertyBag` type
+ that's useful for passing hash maps over XPCOM to JS.
+
+Unfortunately, rustdocs are [not yet generated and
+hosted](https://bugzilla.mozilla.org/show_bug.cgi?id=1428139) for crates within
+mozilla-central. Therefore, the crate links shown above link to files
+containing the relevant rustdocs source where possible. However, you can
+generate docs locally using the `cargo doc` command described above.