Skip to main content
BoxLite follows the Microsoft Rust Guidelines and layers its own conventions on top. Examples target the boxlite crate (source under src/boxlite/src/) and the shared crate boxlite-shared (source under src/shared/src/).

External references

General guidelines (required)

The following guidelines from the Microsoft Rust Guidelines are especially important for BoxLite:

Unsafe guidelines

BoxLite-specific patterns

Async-first architecture

All I/O operations use async/await and run on the Tokio runtime:
BoxliteResult<T> and BoxliteError are both defined in boxlite-shared and re-exported at the top level of the boxlite crate (src/boxlite/src/lib.rs).

Centralized error handling

All errors flow through the BoxliteError enum (defined in src/shared/src/errors.rs). Always attach context when reporting an error:
Common BoxliteError variants (a selection from src/shared/src/errors.rs): Storage, Config, Image, Network, Execution, NotFound, AlreadyExists, InvalidState, InvalidArgument, Stopped, Internal, and others — all in the form BoxliteError::Variant(String). Choose the variant closest to the semantics; do not default everything to Internal.
Note: there is no BoxliteError::Run variant — use BoxliteError::Execution(...) for execution-related errors.

Public types must be Send + Sync

Every public type exposed through the API must be thread-safe. Use Arc to share ownership across threads; do not use Rc:
The real LiteBox (src/boxlite/src/litebox/mod.rs) holds Arc<dyn BoxBackend> / Arc<dyn SnapshotBackend> to provide a cloneable, thread-safe handle. Methods such as exec (the command-execution method; see src/boxlite/src/litebox/mod.rs) take &self so the handle can be shared.

Formatting and linting

  • Formatting: cargo fmt (enforced in CI; the repository root carries the rustfmt.toml configuration).
  • Linting: cargo clippy (warnings are treated as errors in CI).
Before submitting, run the following from the repository root:
cargo fmt --check does not modify files; it only reports whether formatting is needed, which makes it suitable as a gate in scripts.

Quick self-check

When writing Rust for BoxLite, ask yourself before submitting:
  1. Is this panic necessary? (M-PANIC-ON-BUG) — panic only on bugs; use Result for expected errors.
  2. Is this name clear enough? (M-CONCISE-NAMES) — avoid “Manager”, “Service”, “Factory”.
  3. Is the unsafe code minimized? (M-UNSAFE) — isolate and document unsafe code.
  4. Does it implement Debug? (M-PUBLIC-DEBUG) — required for all public types.
  5. Is it async? — all I/O should be Tokio-based and asynchronous.
  6. Does the error carry context? — use BoxliteError with a clear description.

Troubleshooting