# 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` 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 { 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` indicating success or the error encountered pub fn process_command(input: &str) -> Result { // 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` for function parameters - Use structs to group related parameters (> 3 related params) **Return Values:** - Use `Result` for operations that can fail - Use `Option` for values that may be absent - Avoid returning `Box` 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*