Style Guidelines
This document defines the conventions and standards for all software in this project. Consistency across code, documentation, branches, and issues makes the codebase easier to navigate and maintain.
Table of Contents
Rust Code Style
Follow the standard Rust style enforced by rustfmt. Run it before every commit:
cargo fmt
General Rules
- Use
snake_casefor variables, functions, and modules. - Use
PascalCasefor types, structs, enums, and traits. - Use
SCREAMING_SNAKE_CASEfor constants and statics. - Prefer explicit types in public APIs; let type inference handle local variables.
- Avoid
unwrap()andexpect()in production code paths. Use proper error propagation with?or match onResult/Option. - Keep functions short and single-purpose. If a function doesn’t fit on one screen, consider splitting it.
- Prefer
matchover longif-elsechains for exhaustive pattern matching.
Documentation Style
All documentation is written in Markdown and lives in the docs/ directory, processed by Jekyll with the Just the Docs theme.
File Frontmatter
Every .md file must include:
---
title: Page Title
layout: default
parent: Parent Section # omit if top-level
nav_order: N
---
Code Blocks
Always specify the language for syntax highlighting:
```rust
// embedded Rust example
```
```bash
# shell commands
```
```c
// C/C++ or linker examples
```
Headings
#— page title only (one per file).##— major sections.###— subsections.- Do not skip heading levels.
- Use sentence case: “Error handling”, not “Error Handling”.
Callouts (Just the Docs)
Use these consistently to flag important information:
{: .warning }
This operation resets all...
{: .note }
This only applies to...
{: .important }
Changing this register requires disabling...
Naming Conventions
Modules
Avoid module names like utils, helpers, or misc — these become dumping grounds.
Constants and Statics
const MAX_PACKET_SIZE: usize = 256;
static DEVICE_ID: u32 = 0xDEAD_BEEF;
Use _ separators in large numeric literals for readability: 0x0000_FFFF, 1_000_000.
Booleans
Prefix boolean variables and functions with is_, has_, or was_:
let is_ready: bool = ...;
fn has_pending_data(&self) -> bool { ... }
Acronyms in Names
Treat acronyms as words. Use Uart, Spi, Dma, not UART, SPI, DMA in type names. This keeps rustfmt and autocomplete happy:
struct UartDriver { ... } // ✓
struct UARTDriver { ... } // ✗
Branch Conventions
Format
<related-issue>-<short-description>
Use lowercase and hyphens. No spaces, no underscores, no uppercase.
Branch Examples
35-uart-dma-rx
12-stm32g4-bsp-init
56-update-embassy
Issue Conventions
Title Format
[Type] Short imperative description
Use the imperative mood as if completing the sentence “This issue will…”
Types
| Label | Description |
|---|---|
[bug] | Something is broken or behaves incorrectly |
[feat] | A new feature or capability |
[refactor] | Internal restructuring |
[docs] | Documentation gap or error |
[hw] | Hardware-related issue (pin conflicts, timing, etc.) |
[chore] | Maintenance, dependency bump, CI |
[question] | Needs discussion or decision before work begins |
Issue Examples
[bug] UART RX drops bytes at 921600 baud
[feat] Add watchdog timer support
[hw] SPI2 MISO conflicts with LED GPIO on rev B board
[docs] Document flash memory layout