201 lines
5.6 KiB
Markdown
201 lines
5.6 KiB
Markdown
# Coding Conventions
|
|
|
|
**Analysis Date:** 2026-02-28
|
|
|
|
## Overview
|
|
|
|
This is an early-stage Rust project with minimal codebase (single `main.rs` file). Conventions are established based on:
|
|
- Rust language defaults and community standards
|
|
- Cargo default behavior
|
|
- Current code patterns in the project
|
|
|
|
## Naming Patterns
|
|
|
|
**Files:**
|
|
- Snake case: `main.rs`, `lib.rs` are standard entry points
|
|
- Module files use snake_case: `user_service.rs`, `data_handler.rs`
|
|
- Test modules within files or in separate `tests/` directory
|
|
|
|
**Functions:**
|
|
- Snake case throughout: `fn handle_connection()`, `fn parse_input()`
|
|
- Use descriptive verb-based names: `fn calculate_sum()`, `fn build_response()`
|
|
|
|
**Variables:**
|
|
- Snake case for bindings: `let user_id`, `let response_data`
|
|
- Constants use UPPER_CASE: `const MAX_BUFFER_SIZE: usize = 1024`
|
|
- Mutable bindings explicitly marked: `let mut count = 0`
|
|
|
|
**Types and Structs:**
|
|
- PascalCase for type names: `struct User`, `enum Status`, `trait Handler`
|
|
- Generic parameters use single letters or PascalCase: `T`, `S`, `Request`
|
|
- Lifetime parameters use lowercase: `'a`, `'static`
|
|
|
|
## Code Style
|
|
|
|
**Formatting:**
|
|
- Default Rust formatting applied by `rustfmt` (de facto standard)
|
|
- 4-space indentation (Rust default)
|
|
- No semicolons in final expressions that return values
|
|
- Closing braces on same line except for block statements
|
|
|
|
**Linting:**
|
|
- Clippy lints should be addressed as part of development
|
|
- No explicit `clippy.toml` or linting configuration currently present
|
|
- Default clippy warnings and errors should be resolved before commit
|
|
|
|
**Edition:**
|
|
- Rust 2024 edition (specified in `Cargo.toml`)
|
|
- Supports latest language features and idioms
|
|
|
|
## Import Organization
|
|
|
|
**Order:**
|
|
1. Standard library imports (`use std::`)
|
|
2. External crate imports (`use ratatui::`, other external deps)
|
|
3. Internal crate imports (`use crate::`)
|
|
4. Module declarations (`mod xyz;`)
|
|
|
|
**Example:**
|
|
```rust
|
|
use std::io;
|
|
use std::collections::HashMap;
|
|
|
|
use ratatui::backend::CrosstermBackend;
|
|
use ratatui::Terminal;
|
|
|
|
use crate::ui::draw;
|
|
use crate::handler::InputHandler;
|
|
```
|
|
|
|
**Path Aliases:**
|
|
- No path aliases configured currently
|
|
- Can be added via workspace root configuration if needed
|
|
|
|
## Error Handling
|
|
|
|
**Patterns:**
|
|
- Use `Result<T, E>` for fallible operations
|
|
- Propagate errors with `?` operator rather than unwrapping when possible
|
|
- Use `anyhow::Result` for application-level errors (dependency available)
|
|
- Only use `.unwrap()` or `.expect()` for code that should never panic in normal operation
|
|
|
|
**Example:**
|
|
```rust
|
|
fn read_config(path: &str) -> Result<Config> {
|
|
let content = std::fs::read_to_string(path)?;
|
|
let config = serde_json::from_str(&content)?;
|
|
Ok(config)
|
|
}
|
|
```
|
|
|
|
## Logging
|
|
|
|
**Framework:** Not yet selected/integrated
|
|
|
|
**When logging is added:**
|
|
- Use `log` crate for production logging
|
|
- Use `env_logger` or similar for log configuration
|
|
- Log levels: ERROR for failures, WARN for unusual conditions, INFO for significant events, DEBUG for detailed traces
|
|
- Avoid logging sensitive data (credentials, tokens, PII)
|
|
|
|
## Comments
|
|
|
|
**When to Comment:**
|
|
- Explain the "why" not the "what"
|
|
- Document non-obvious algorithmic decisions
|
|
- Explain trade-offs or workarounds
|
|
- Mark intentional violations of conventions with `// FIXME:` or `// TODO:`
|
|
|
|
**Doc Comments:**
|
|
- Use `///` for public item documentation
|
|
- Document public functions, structs, enums, traits
|
|
- Include examples for complex or non-obvious public APIs
|
|
|
|
**Example:**
|
|
```rust
|
|
/// Processes a user command from the input buffer.
|
|
///
|
|
/// This function parses the raw input and dispatches to appropriate handlers.
|
|
///
|
|
/// # Arguments
|
|
/// * `input` - Raw user input string
|
|
///
|
|
/// # Returns
|
|
/// `Result<CommandResult, Error>` indicating success or the error encountered
|
|
pub fn process_command(input: &str) -> Result<CommandResult> {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
## Function Design
|
|
|
|
**Size:**
|
|
- Keep functions small and focused (ideally < 50 lines)
|
|
- Extract helper functions for complex logic
|
|
- Separate parsing, validation, and execution logic
|
|
|
|
**Parameters:**
|
|
- Use owned values for simple types, references for larger types
|
|
- Prefer `&[T]` over `&Vec<T>` for function parameters
|
|
- Use structs to group related parameters (> 3 related params)
|
|
|
|
**Return Values:**
|
|
- Use `Result<T, E>` for operations that can fail
|
|
- Use `Option<T>` for values that may be absent
|
|
- Avoid returning `Box<dyn Trait>` unless necessary for dynamic dispatch
|
|
|
|
## Module Design
|
|
|
|
**Exports:**
|
|
- Explicitly declare public items with `pub`
|
|
- Use `pub use` to re-export important types at module boundaries
|
|
- Keep implementation details private (`non-pub` by default)
|
|
|
|
**Module Structure:**
|
|
```rust
|
|
// src/main.rs
|
|
mod ui;
|
|
mod handler;
|
|
mod model;
|
|
|
|
use ui::App;
|
|
use handler::InputHandler;
|
|
|
|
fn main() {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
**Barrel Files:**
|
|
- Use `mod.rs` files in subdirectories to organize module exports
|
|
- Example: `src/ui/mod.rs` exports types from `ui/draw.rs`, `ui/state.rs`
|
|
|
|
## Unsafe Code
|
|
|
|
**Usage:**
|
|
- Avoid unsafe blocks unless necessary for FFI or performance-critical code
|
|
- Document unsafe code with `// SAFETY:` comments explaining invariants
|
|
- Minimize unsafe scope
|
|
|
|
**Example:**
|
|
```rust
|
|
// SAFETY: ptr is guaranteed to point to valid, initialized memory
|
|
// returned from foreign_function, which owns its lifetime
|
|
unsafe {
|
|
let result = process_data(ptr);
|
|
}
|
|
```
|
|
|
|
## Workspace and Multi-Crate Structure
|
|
|
|
**Currently:** Single binary crate (`bbs-md`)
|
|
|
|
**If expanding:**
|
|
- Consider separating into `bbs-md` (binary) and `bbs-md-core` (library)
|
|
- Use workspace for shared dependencies and configuration
|
|
- Place library code in `src/lib.rs`, binary-specific code in `src/main.rs`
|
|
|
|
---
|
|
|
|
*Convention analysis: 2026-02-28*
|