> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boxlite.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust Style Guide

> Coding style and conventions for BoxLite Rust development

This guide extends the [Microsoft Rust Guidelines](https://microsoft.github.io/rust-guidelines) with BoxLite-specific patterns.

## External References

* **Microsoft Rust Guidelines**: [https://microsoft.github.io/rust-guidelines](https://microsoft.github.io/rust-guidelines)
* **Rust API Guidelines**: [https://rust-lang.github.io/api-guidelines/](https://rust-lang.github.io/api-guidelines/)

## Universal Guidelines (Must Follow)

These guidelines from the Microsoft Rust Guidelines are particularly important for BoxLite:

| Guideline                  | Summary                                                        |
| -------------------------- | -------------------------------------------------------------- |
| **M-PANIC-IS-STOP**        | Panics terminate the program - they are not exceptions         |
| **M-PANIC-ON-BUG**         | Panic only on programming errors, never for expected failures  |
| **M-CONCISE-NAMES**        | Avoid weasel words: "Service", "Manager", "Factory", "Handler" |
| **M-LOG-STRUCTURED**       | Use structured logging with meaningful fields                  |
| **M-DOCUMENTED-MAGIC**     | Document all magic numbers and constants                       |
| **M-PUBLIC-DEBUG**         | All public types must implement `Debug`                        |
| **M-PUBLIC-DISPLAY**       | User-facing types should implement `Display`                   |
| **M-LINT-OVERRIDE-EXPECT** | Use `#[expect]` over `#[allow]` for lint overrides             |
| **M-REGULAR-FN**           | Prefer regular functions over methods when `self` isn't needed |
| **M-SMALLER-CRATES**       | Keep crates focused on a single responsibility                 |

## Safety Guidelines

| Guideline               | Summary                                                              |
| ----------------------- | -------------------------------------------------------------------- |
| **M-UNSAFE**            | Minimize unsafe code; isolate it in small, well-documented functions |
| **M-UNSAFE-IMPLIES-UB** | Document all undefined behavior conditions in unsafe code            |
| **M-UNSOUND**           | Never expose unsound APIs; soundness must be guaranteed              |

## BoxLite-Specific Patterns

### Async-First Architecture

All I/O operations use async/await with Tokio runtime:

<CodeGroup>
  ```rust Correct theme={null}
  // async I/O
  async fn read_config(path: &Path) -> Result<Config> {
      let contents = tokio::fs::read_to_string(path).await?;
      Ok(toml::from_str(&contents)?)
  }
  ```

  ```rust Incorrect theme={null}
  // blocking I/O in async context
  async fn read_config(path: &Path) -> Result<Config> {
      let contents = std::fs::read_to_string(path)?;  // Blocks!
      Ok(toml::from_str(&contents)?)
  }
  ```
</CodeGroup>

<Warning>
  Never use blocking I/O (e.g. `std::fs`) inside an async context. Always use the Tokio async equivalents (`tokio::fs`) to avoid blocking the runtime.
</Warning>

### Centralized Error Handling

Use the `BoxliteError` enum for all errors (see `boxlite-shared/src/errors.rs`):

<CodeGroup>
  ```rust Correct theme={null}
  // use BoxliteError with context
  std::fs::create_dir_all(&socket_dir).map_err(|e| {
      BoxliteError::Storage(format!(
          "Failed to create socket directory {}: {}", socket_dir.display(), e
      ))
  })?;
  ```

  ```rust Incorrect theme={null}
  // generic error without context
  std::fs::create_dir_all(&dir)?;
  ```
</CodeGroup>

<Tip>
  Always wrap errors with `BoxliteError` and include descriptive context about what operation failed and why. This makes debugging significantly easier.
</Tip>

### Public Types Must Be `Send + Sync`

All public types exposed through the API must be thread-safe:

<CodeGroup>
  ```rust Correct theme={null}
  // Arc for shared ownership across threads
  pub struct LiteBox {
      inner: Arc<LiteBoxInner>,
  }
  ```

  ```rust Incorrect theme={null}
  // Rc is not Send
  pub struct LiteBox {
      inner: Rc<LiteBoxInner>,  // Not thread-safe!
  }
  ```
</CodeGroup>

## Formatting and Linting

* **Formatting**: `cargo fmt` (enforced in CI)
* **Linting**: `cargo clippy` (warnings are errors in CI)

Run before committing:

```bash theme={null}
cargo fmt
cargo clippy --all-targets --all-features
```

## Quick Reference

When writing Rust code for BoxLite, ask yourself:

<AccordionGroup>
  <Accordion title="Is this panic necessary? (M-PANIC-ON-BUG)">
    Only panic on programming errors (bugs). Use `Result` for all expected failures such as I/O errors, invalid input, or network issues.
  </Accordion>

  <Accordion title="Is this name clear? (M-CONCISE-NAMES)">
    Avoid vague weasel words like "Manager", "Service", and "Factory". Choose names that describe what the type actually does.
  </Accordion>

  <Accordion title="Is this unsafe minimized? (M-UNSAFE)">
    Isolate and document all unsafe code in small, focused functions. Every unsafe block must explain why it is sound.
  </Accordion>

  <Accordion title="Does this implement Debug? (M-PUBLIC-DEBUG)">
    All public types must implement `Debug`. User-facing types should also implement `Display`.
  </Accordion>

  <Accordion title="Is this async? (Async-First)">
    All I/O operations should be async using Tokio. Never use blocking I/O inside an async context.
  </Accordion>

  <Accordion title="Is the error contextual? (Centralized Errors)">
    Use `BoxliteError` with descriptive messages. Every error should explain what went wrong and where.
  </Accordion>
</AccordionGroup>
