Coding Conventions
Rust
Item Order in Rust Modules
Items SHOULD appear in Rust modules in the following order, based on the one used by rust-analyzer:
- Inner doc comment
- Inner attributes
- Unconditional—i.e., not feature-gated—bodyless modules
- Conditional—i.e., feature-gated—bodyless modules
- Unconditional imports from the following:
std/alloc/core- External crates (including crates from the same workspace)
- Current crate, paths prefixed by
crate - Current module, paths prefixed by
self - Super module, paths prefixed by
super - Re-exports—i.e.,
pubimports not used in the module
- Conditional imports from the same
- Const items
- Static items
- Other items
TODO: type aliases before other items?
TODO: how to organize type definitions w.r.t. related logic?
Imports
Imports from the same crate with the same visibility MUST be merged into a single use statement.
Imports from Re-exports
When using whole-crate re-exports from ariel_os::reexports, two imports SHOULD be used: one to bring the re-exported crate into the scope, and the other one to import the required items from that crate, as it it were a direct dependency of the crate, as follows:
#![allow(unused)]
fn main() {
use ariel_os::reexports::embassy_usb;
use embassy_usb::class::hid::HidReaderWriter;
}
Comments
Doc Comments
All public items listed in the documentation—i.e., not marked with #[doc(hidden)]—SHOULD be documented.
Doc comments MUST use the line comment style, not the block style.
Doc comments MUST be written in third person present, not in the imperative mood, as recommended by RFC 1574. Each sentence in doc comments—including the first one, before an empty line—SHOULD end with a period. For instance, instead of:
#![allow(unused)]
fn main() {
/// Get the underlying value
}
write:
#![allow(unused)]
fn main() {
/// Returns the underlying value.
}
More generally, use the std docs as inspiration.
When possible—i.e., when items are in scope—items mentioned in the documentation MUST be linked to (see C-LINK). This is useful for readers, to quickly access the mentioned item, but it also helps prevent the docs from lagging behind, as broken links are tested for in CI, making it easy to spot renamed or removed items.
unsafe Code
Code containing unsafe is denied outside of modules where the unsafe-code lint is explicitly #[expect]ed
(or, in complex situations, #[allow]ed).
For all unsafe blocks, a SAFETY comment MUST be added, in the style of the undocumented-unsafe-blocks Clippy lint.
Any unsafe function MUST be documented with the preconditions for sound use in a # Safety section, in the style of the missing-safety-doc Clippy lint.
Naming Conventions
Names SHOULD adhere to the official API guidelines.
TODO: how to name error types/error enum variants (CannotDoSth vs DoingSth)?
Code formatting
The code is expected to be formatted following the Rust Style Guide.
You can quickly format the code in the ariel-os repository using this command:
laze build fmt
Dependencies
If the same dependency is used in multiples crates within the workspace, that dependency SHOULD be specified in the workspace’s Cargo.toml file and workspace crates should import them from there.
Adding a new workspace crate, exposed by ariel-os
To add a new workspace crate re-exported by ariel-os, follow these steps:
- Create the new crate’s directory in
src/. - Run
cargo init --libin that directory. - Add
#![deny(missing_docs)]to the crate; some lints are already inherited from the workspace and do not need to be added to the new crate. - In the workspace’s
Cargo.tomlworkspace.membersarray, ensure the new entry preserves the lexicographic order of that array. - In the workspace’s
Cargo.tomldependenciesarray, add a (properly sorted) entry. - Re-export the crate from the
ariel-oscrate, inline it in the docs as done for the other crates, and feature-gate it if necessary. - Add the crate to the list of crates checked by Clippy in
.github/workflows/main.yml, preserving lexicographic order. - If the crate is expected to have tests that can be run with
cargo test:- Add a feature named
_testthat enables all features that can be tested. - Add a
laze.ymlwith an application for the crate namedcrates/your-crate-namethat selects thehost-test-onlymodule (see e.g.,src/ariel-os/laze.yml) - Add the crate’s directory to its parent’s
laze.ymlsubdirs.
- Add a feature named
- If the new crate is feature-gated and if this is possible, add the feature that enables it to the ones used by cargo doc in
.github/workflows/main.ymland in.github/workflows/build-deploy-docs.yml, preserving lexicographic order.
laze
Modules
laze modules in examples and tests MUST use selects instead of depends.
Even though their behaviors are different in the general case, they are equivalent in our case.