docs: map existing codebase
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# Architecture
|
||||
|
||||
**Analysis Date:** 2026-02-28
|
||||
|
||||
## Pattern Overview
|
||||
|
||||
**Overall:** Single-Binary CLI/TUI Application (Rust)
|
||||
|
||||
**Key Characteristics:**
|
||||
- Monolithic Rust binary using Ratatui for terminal UI
|
||||
- Minimal dependency footprint (only Ratatui as external dependency)
|
||||
- Single entry point with main function
|
||||
- Early-stage project with foundational structure only
|
||||
|
||||
## Layers
|
||||
|
||||
**Presentation Layer:**
|
||||
- Purpose: Terminal user interface rendering and interaction
|
||||
- Location: `src/main.rs` (currently)
|
||||
- Contains: TUI initialization, event handling, widget rendering
|
||||
- Depends on: Ratatui framework
|
||||
- Used by: End users through terminal
|
||||
|
||||
**Business Logic Layer:**
|
||||
- Purpose: Core application functionality
|
||||
- Location: TBD - not yet implemented
|
||||
- Contains: Data processing, command handling, state management
|
||||
- Depends on: None currently defined
|
||||
- Used by: Presentation layer
|
||||
|
||||
**Data Layer:**
|
||||
- Purpose: Data persistence and retrieval
|
||||
- Location: TBD - not yet implemented
|
||||
- Contains: File I/O, caching, serialization
|
||||
- Depends on: Standard library (File, IO)
|
||||
- Used by: Business logic layer
|
||||
|
||||
## Data Flow
|
||||
|
||||
**Typical User Interaction Flow:**
|
||||
|
||||
1. Terminal input captured by Ratatui event handling
|
||||
2. User action (keyboard/mouse) parsed into application command
|
||||
3. Command dispatched to business logic handler
|
||||
4. Handler processes request, potentially reads/writes data
|
||||
5. State updated based on result
|
||||
6. UI re-rendered with new state in next frame
|
||||
|
||||
**State Management:**
|
||||
- Single application state entity (not yet defined)
|
||||
- Immutable state passed to rendering function
|
||||
- Ratatui handles incremental screen updates
|
||||
|
||||
## Key Abstractions
|
||||
|
||||
**Terminal User Interface (TUI):**
|
||||
- Purpose: Encapsulate all terminal rendering and input handling
|
||||
- Examples: `src/main.rs` (current single module)
|
||||
- Pattern: React-like paradigm via Ratatui (state -> render)
|
||||
|
||||
**Application Command/Action:**
|
||||
- Purpose: Abstract user intentions from input events
|
||||
- Examples: Not yet implemented
|
||||
- Pattern: Enum-based command pattern expected
|
||||
|
||||
## Entry Points
|
||||
|
||||
**Binary Entry:**
|
||||
- Location: `src/main.rs`
|
||||
- Triggers: `cargo run` or binary execution
|
||||
- Responsibilities:
|
||||
- Initialize Ratatui terminal
|
||||
- Set up event loop
|
||||
- Handle application lifecycle
|
||||
- Render UI each frame
|
||||
- Currently: Placeholder with "Hello, world!" output
|
||||
|
||||
## Error Handling
|
||||
|
||||
**Strategy:** Not yet defined
|
||||
|
||||
**Patterns:**
|
||||
- Ratatui provides Result types for I/O operations
|
||||
- Expected approach: Result-based error propagation using ? operator
|
||||
- Terminal restoration should be ensured on panic (Ratatui provides Drop impl)
|
||||
|
||||
## Cross-Cutting Concerns
|
||||
|
||||
**Logging:** Not yet implemented. Standard approach would use `log` crate or println! macros during development.
|
||||
|
||||
**Validation:** Not yet implemented. Expected in business logic layer once commands are defined.
|
||||
|
||||
**Terminal State:** Ratatui manages terminal state (raw mode, cursor visibility, etc.). Must ensure proper cleanup on application exit.
|
||||
|
||||
---
|
||||
|
||||
*Architecture analysis: 2026-02-28*
|
||||
@@ -0,0 +1,104 @@
|
||||
# Codebase Concerns
|
||||
|
||||
**Analysis Date:** 2026-02-28
|
||||
|
||||
## Critical Issues
|
||||
|
||||
**Empty Application Stub:**
|
||||
- Issue: The entire application is a bare "Hello, world!" stub with no functional implementation
|
||||
- Files: `src/main.rs`
|
||||
- Impact: No actual BBS markdown functionality exists; application is not usable
|
||||
- Fix approach: Implement core application logic for markdown bulletin board system functionality
|
||||
|
||||
**Invalid Edition Specification:**
|
||||
- Issue: `Cargo.toml` specifies `edition = "2024"` which is not a valid Rust edition
|
||||
- Files: `Cargo.toml`
|
||||
- Impact: Build will fail or behave unexpectedly if edition validation is enforced; incorrect edition can affect language feature availability
|
||||
- Fix approach: Change to a valid edition: `2021` (latest stable) or `2018` if legacy support needed
|
||||
|
||||
## Tech Debt
|
||||
|
||||
**Minimal Dependency Management:**
|
||||
- Issue: Heavy dependency on ratatui (0.30.0) and its entire ecosystem for a stub application
|
||||
- Files: `Cargo.toml`
|
||||
- Impact: Unnecessary compiled binary size and build time for functionality that doesn't yet exist; approximately 60+ transitive dependencies for "Hello, world!"
|
||||
- Fix approach: Keep ratatui when actual TUI is implemented; document why ratatui was chosen early
|
||||
|
||||
**No Error Handling:**
|
||||
- Issue: Application has no error handling, logging, or graceful failure modes
|
||||
- Files: `src/main.rs`
|
||||
- Impact: Crashes will be silent or unhelpful; no debugging information available
|
||||
- Fix approach: Implement structured error handling; consider using `anyhow` or `thiserror` crate (already available in dependencies)
|
||||
|
||||
**No Architecture Documentation:**
|
||||
- Issue: Zero guidance on how BBS-MD should be structured or what features should be implemented
|
||||
- Files: Project root (missing design docs)
|
||||
- Impact: Development direction unclear; future contributors won't understand intent
|
||||
- Fix approach: Create architecture documentation, feature specification, and roadmap
|
||||
|
||||
## Missing Critical Features
|
||||
|
||||
**No TUI Implementation:**
|
||||
- What's missing: Terminal UI is imported (ratatui) but never used
|
||||
- Blocks: Cannot create/view/edit bulletin board content
|
||||
- Priority: High
|
||||
|
||||
**No Data Persistence:**
|
||||
- What's missing: No markdown file handling, no storage mechanism
|
||||
- Blocks: Cannot persist BBS posts or configuration
|
||||
- Priority: High
|
||||
|
||||
**No Input Processing:**
|
||||
- What's missing: Application ignores user input entirely
|
||||
- Blocks: Cannot interact with application
|
||||
- Priority: High
|
||||
|
||||
## Test Coverage Gaps
|
||||
|
||||
**Zero Testing:**
|
||||
- What's not tested: All functionality (or complete lack thereof)
|
||||
- Files: No test directory exists; `src/main.rs` has no tests
|
||||
- Risk: No confidence in correctness; refactoring will be dangerous
|
||||
- Priority: High
|
||||
|
||||
## Scalability & Architecture Concerns
|
||||
|
||||
**Monolithic Structure:**
|
||||
- Problem: Single main.rs file will quickly become unmaintainable as features are added
|
||||
- Current capacity: ~45 lines before severe maintainability issues
|
||||
- Scaling path: Create modular structure with separate modules for TUI layer, data layer, business logic
|
||||
|
||||
**Dependency Organization:**
|
||||
- Problem: Entire ratatui ecosystem locked in at build time even when not used
|
||||
- Current capacity: 60+ transitive dependencies inflating binary
|
||||
- Scaling path: Feature-gate dependencies or defer dependency addition until features are implemented
|
||||
|
||||
## Security Considerations
|
||||
|
||||
**Unvalidated Input:**
|
||||
- Risk: Once input processing is added, no visible validation or sanitization strategy exists
|
||||
- Files: Will be implemented in future features
|
||||
- Current mitigation: None (application ignores input)
|
||||
- Recommendations: Plan input validation for markdown parsing; sanitize user-provided content if displayed; consider file path traversal protections if file loading is implemented
|
||||
|
||||
**File System Access:**
|
||||
- Risk: Future markdown file handling could expose security issues (directory traversal, privilege escalation)
|
||||
- Files: Not yet implemented
|
||||
- Current mitigation: None
|
||||
- Recommendations: When implementing file I/O, enforce strict path validation; restrict operations to designated directories only
|
||||
|
||||
## Dependencies at Risk
|
||||
|
||||
**Edition Mismatch:**
|
||||
- Risk: Invalid edition specification may cause build failures or unexpected behavior in future toolchain versions
|
||||
- Impact: Application may not compile with newer Rust tools
|
||||
- Migration plan: Immediately fix to `edition = "2021"` to match stable toolchain
|
||||
|
||||
**Tight Coupling to Ratatui:**
|
||||
- Risk: Early adoption of specific TUI framework before requirements are clear
|
||||
- Impact: Switching frameworks later will require significant refactoring
|
||||
- Migration plan: Encapsulate ratatui behind abstraction layer; consider generic TUI trait to allow future framework swaps
|
||||
|
||||
---
|
||||
|
||||
*Concerns audit: 2026-02-28*
|
||||
@@ -0,0 +1,200 @@
|
||||
# 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*
|
||||
@@ -0,0 +1,76 @@
|
||||
# External Integrations
|
||||
|
||||
**Analysis Date:** 2026-02-28
|
||||
|
||||
## APIs & External Services
|
||||
|
||||
**Not detected** - This is a standalone TUI application with no external API integrations.
|
||||
|
||||
## Data Storage
|
||||
|
||||
**Databases:**
|
||||
- Not detected - No database client/ORM dependencies present
|
||||
|
||||
**File Storage:**
|
||||
- Local filesystem only - Markdown files read/written to local disk
|
||||
|
||||
**Caching:**
|
||||
- Not detected - No external caching service
|
||||
|
||||
## Authentication & Identity
|
||||
|
||||
**Auth Provider:**
|
||||
- Custom or None - No authentication framework detected
|
||||
|
||||
**Implementation:**
|
||||
- Local-only TUI application with no user authentication layer
|
||||
|
||||
## Monitoring & Observability
|
||||
|
||||
**Error Tracking:**
|
||||
- Not detected - No error tracking service integration
|
||||
|
||||
**Logs:**
|
||||
- Standard output/stderr via log crate facade
|
||||
- Controlled via application logging configuration
|
||||
|
||||
## CI/CD & Deployment
|
||||
|
||||
**Hosting:**
|
||||
- Standalone binary deployment - Compiled as single executable
|
||||
|
||||
**CI Pipeline:**
|
||||
- Not detected - No CI/CD configuration files present
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
**Required env vars:**
|
||||
- None detected - Configuration appears to be hardcoded or via CLI arguments
|
||||
|
||||
**Secrets location:**
|
||||
- Not applicable - No external service credentials required
|
||||
|
||||
## Webhooks & Callbacks
|
||||
|
||||
**Incoming:**
|
||||
- Not applicable - Standalone CLI application
|
||||
|
||||
**Outgoing:**
|
||||
- Not applicable - No webhook support detected
|
||||
|
||||
## Terminal Environment
|
||||
|
||||
**Integration Points:**
|
||||
- Terminal protocol: VT100 escape sequences
|
||||
- Platform support via crossterm:
|
||||
- Unix/Linux systems: Raw mode via termios
|
||||
- Windows systems: Windows API for console mode
|
||||
- macOS: POSIX terminal support
|
||||
|
||||
**Signal Handling:**
|
||||
- Unix signals (SIGTERM, SIGINT) for graceful shutdown
|
||||
- Integrated via signal-hook and mio event loop
|
||||
|
||||
---
|
||||
|
||||
*Integration audit: 2026-02-28*
|
||||
@@ -0,0 +1,128 @@
|
||||
# Technology Stack
|
||||
|
||||
**Analysis Date:** 2026-02-28
|
||||
|
||||
## Languages
|
||||
|
||||
**Primary:**
|
||||
- Rust - CLI/TUI application for markdown bulletin board system
|
||||
|
||||
## Runtime
|
||||
|
||||
**Environment:**
|
||||
- Rust compiler and runtime
|
||||
|
||||
**Package Manager:**
|
||||
- Cargo
|
||||
- Lockfile: `Cargo.lock` present
|
||||
|
||||
## Frameworks
|
||||
|
||||
**Core:**
|
||||
- ratatui 0.30.0 - Terminal user interface (TUI) framework for building rich CLI applications
|
||||
|
||||
**Build:**
|
||||
- cargo - Rust package manager and build system
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
**Critical:**
|
||||
- ratatui 0.30.0 - Main TUI framework providing terminal rendering, event handling, and widgets
|
||||
- ratatui-core - Core functionality for ratatui
|
||||
- ratatui-crossterm - Crossterm backend integration for ratatui
|
||||
- ratatui-macros - Proc macros for ratatui
|
||||
- ratatui-termwiz - Termwiz backend support for ratatui
|
||||
- ratatui-widgets - Widget library for ratatui
|
||||
|
||||
**Terminal & Input:**
|
||||
- crossterm 0.29.0 - Cross-platform terminal manipulation library (Windows/Unix compatible)
|
||||
- signal-hook - Unix signal handling for clean shutdowns
|
||||
- signal-hook-mio - Integration between signal-hook and mio
|
||||
- termwiz - Terminal operations library with wide character support
|
||||
- terminfo - Terminal capability detection
|
||||
- vtparse - VT100 escape sequence parser
|
||||
- utf8parse - UTF-8 parsing utilities
|
||||
|
||||
**UI Rendering & Text:**
|
||||
- unicode-width - Calculate display width of unicode characters
|
||||
- unicode-truncate - Truncate unicode strings to display width
|
||||
- unicode-segmentation - Segment unicode text
|
||||
- wezterm-bidi - Bidirectional text support
|
||||
- fancy-regex - Advanced regex support with lookahead/lookbehind
|
||||
- regex 1.x - Regular expression library
|
||||
|
||||
**Graphics & Color:**
|
||||
- csscolorparser 0.6.2 - Parse CSS color strings
|
||||
- wezterm-color-types - Color type definitions
|
||||
- euclid - 2D and 3D geometry primitives
|
||||
- line-clipping - Line clipping algorithms
|
||||
|
||||
**Data Structures & Utilities:**
|
||||
- indexmap - Hash map preserving insertion order
|
||||
- hashbrown - Faster hashmap implementation
|
||||
- smallvec - Vector that stores small amounts inline
|
||||
- itertools - Iterator extensions
|
||||
- nom - Parser combinators library
|
||||
- pest - PEG parser generator
|
||||
- strum/strum_macros - Enum utilities and macros
|
||||
|
||||
**Serialization:**
|
||||
- serde/serde_json - Serialization framework
|
||||
- base64 - Base64 encoding/decoding
|
||||
|
||||
**Error Handling:**
|
||||
- anyhow 1.0.102 - Flexible error handling
|
||||
- thiserror - Structured error types
|
||||
|
||||
**Platform Support:**
|
||||
- libc - C library bindings (Unix)
|
||||
- rustix - Wrapper around system calls
|
||||
- nix - Unix-like API bindings
|
||||
- winapi - Windows API bindings
|
||||
- windows-sys - Windows system APIs
|
||||
- parking_lot - Synchronization primitives
|
||||
|
||||
**Hashing & Crypto:**
|
||||
- sha2 - SHA-2 digest algorithms
|
||||
- xxhash-rust - xxHash algorithm
|
||||
|
||||
**UUID & ID Generation:**
|
||||
- uuid - UUID generation and parsing
|
||||
- mac_address - MAC address utilities
|
||||
|
||||
**Logging:**
|
||||
- log - Logging facade
|
||||
|
||||
**Development & Macros:**
|
||||
- syn - Rust syntax tree parsing
|
||||
- quote - Quoting for proc macros
|
||||
- proc-macro2 - Proc macro utilities
|
||||
- darling - Attribute macro argument parsing
|
||||
|
||||
## Configuration
|
||||
|
||||
**Build Configuration:**
|
||||
- Edition: 2024 (Rust edition)
|
||||
- Target: Binary executable
|
||||
- Manifest: `Cargo.toml`
|
||||
|
||||
**Dependencies Management:**
|
||||
- Lock file: `Cargo.lock` ensures reproducible builds
|
||||
- All dependencies from crates.io registry
|
||||
- Transitive dependency management handled by Cargo
|
||||
|
||||
## Platform Requirements
|
||||
|
||||
**Development:**
|
||||
- Rust toolchain (cargo)
|
||||
- POSIX-compliant system (Linux, macOS) or Windows
|
||||
- Terminal support for modern escape sequences
|
||||
|
||||
**Production:**
|
||||
- Binary compiled for target platform (Linux, macOS, Windows)
|
||||
- Terminal with VT100 escape sequence support
|
||||
- UTF-8 capable terminal
|
||||
|
||||
---
|
||||
|
||||
*Stack analysis: 2026-02-28*
|
||||
@@ -0,0 +1,120 @@
|
||||
# Codebase Structure
|
||||
|
||||
**Analysis Date:** 2026-02-28
|
||||
|
||||
## Directory Layout
|
||||
|
||||
```
|
||||
bbs-md/
|
||||
├── src/ # Rust source code
|
||||
│ └── main.rs # Binary entry point and main application logic
|
||||
├── target/ # Build artifacts (generated)
|
||||
├── .git/ # Git repository metadata
|
||||
├── .planning/ # Planning and documentation
|
||||
│ └── codebase/ # Architecture and structure docs
|
||||
├── Cargo.toml # Rust package manifest
|
||||
├── Cargo.lock # Dependency lock file
|
||||
└── .gitignore # Git ignore rules
|
||||
```
|
||||
|
||||
## Directory Purposes
|
||||
|
||||
**src/**
|
||||
- Purpose: All Rust source code for the project
|
||||
- Contains: Rust modules and binary logic
|
||||
- Key files: `main.rs`
|
||||
|
||||
**.planning/codebase/**
|
||||
- Purpose: Architecture and codebase analysis documents
|
||||
- Contains: ARCHITECTURE.md, STRUCTURE.md, CONVENTIONS.md, TESTING.md (as written)
|
||||
- Generated by: Codebase mapping process
|
||||
|
||||
**target/**
|
||||
- Purpose: Build output directory (generated by Cargo)
|
||||
- Contains: Compiled binaries, dependencies, metadata
|
||||
- Generated: Yes
|
||||
- Committed: No (in .gitignore)
|
||||
|
||||
## Key File Locations
|
||||
|
||||
**Entry Points:**
|
||||
- `src/main.rs`: Main binary executable, contains fn main() and all current application logic
|
||||
|
||||
**Configuration:**
|
||||
- `Cargo.toml`: Package metadata, dependencies, build configuration
|
||||
|
||||
**Build Output:**
|
||||
- `Cargo.lock`: Locked dependency versions ensuring reproducible builds
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
**Files:**
|
||||
- `main.rs`: Entry point for binary crate
|
||||
- `lib.rs`: Would be used for library crate (not present)
|
||||
- Module files: `module_name.rs` (snake_case)
|
||||
- Cargo files: `Cargo.toml`, `Cargo.lock`
|
||||
|
||||
**Directories:**
|
||||
- `src/`: Source code directory (Rust convention)
|
||||
- `target/`: Build output (Cargo convention)
|
||||
- Module directories: `snake_case/` for organizing modules into subdirectories
|
||||
|
||||
**Modules:**
|
||||
- Snake_case for module names in Rust
|
||||
- Single-word module names preferred for clarity
|
||||
|
||||
## Where to Add New Code
|
||||
|
||||
**New Feature:**
|
||||
- Primary code: `src/main.rs` until structure grows
|
||||
- Once > 300 lines: Extract to `src/feature_name.rs`, then `mod feature_name;` in main.rs
|
||||
- Tests: In same file with `#[cfg(test)]` module, or separate `src/feature_name_test.rs`
|
||||
|
||||
**New Component/Module:**
|
||||
- Implementation: Create `src/module_name.rs`
|
||||
- Export in `src/main.rs` with `mod module_name;`
|
||||
- Public items: Use `pub` keyword and re-export in main if needed for internal use
|
||||
|
||||
**Utilities:**
|
||||
- Shared helpers: Create `src/utils.rs` or `src/common.rs` for cross-cutting utilities
|
||||
- General-purpose: Keep in dedicated module, expose via public functions
|
||||
|
||||
**UI Components:**
|
||||
- Ratatui-specific code: Keep in dedicated module like `src/ui.rs` or `src/widgets.rs`
|
||||
- Separate widget rendering logic from business logic
|
||||
- Re-export commonly used widgets from central location
|
||||
|
||||
## Special Directories
|
||||
|
||||
**target/:**
|
||||
- Purpose: Contains compiled binaries, intermediate build files, and dependencies
|
||||
- Generated: Yes
|
||||
- Committed: No
|
||||
|
||||
**.git/:**
|
||||
- Purpose: Git repository metadata
|
||||
- Generated: Yes
|
||||
- Committed: Not applicable (part of .git directory)
|
||||
|
||||
## Recommended Module Organization (As Project Grows)
|
||||
|
||||
Once the codebase expands beyond the current single-file structure:
|
||||
|
||||
```
|
||||
src/
|
||||
├── main.rs # Binary entry, module declarations, main loop
|
||||
├── app.rs # Application state and core logic
|
||||
├── ui/
|
||||
│ ├── mod.rs # UI module exports
|
||||
│ ├── widgets.rs # Custom widget definitions
|
||||
│ └── events.rs # Event handling logic
|
||||
├── commands.rs # Command/action definitions
|
||||
├── errors.rs # Error types
|
||||
└── utils.rs # Utility functions
|
||||
```
|
||||
|
||||
This structure keeps concerns separated while maintaining minimal interdependencies.
|
||||
|
||||
---
|
||||
|
||||
*Structure analysis: 2026-02-28*
|
||||
@@ -0,0 +1,324 @@
|
||||
# Testing Patterns
|
||||
|
||||
**Analysis Date:** 2026-02-28
|
||||
|
||||
## Test Framework
|
||||
|
||||
**Test Runner:**
|
||||
- Rust built-in test framework (via `cargo test`)
|
||||
- No external test framework currently integrated
|
||||
- Can add `tokio` for async testing if needed later
|
||||
|
||||
**Assertion Library:**
|
||||
- Standard `assert!()` and `assert_eq!()` macros from standard library
|
||||
- Can add `pretty_assertions` crate for better failure output if desired
|
||||
|
||||
**Run Commands:**
|
||||
```bash
|
||||
cargo test # Run all tests
|
||||
cargo test -- --nocapture # Run tests with output visible
|
||||
cargo test -- --test-threads=1 # Run tests sequentially
|
||||
cargo test --lib # Run only library tests
|
||||
cargo test --doc # Run doctests
|
||||
```
|
||||
|
||||
**Watch Mode:**
|
||||
```bash
|
||||
# Using cargo-watch (install with: cargo install cargo-watch)
|
||||
cargo watch -x test # Re-run tests on file changes
|
||||
```
|
||||
|
||||
**Coverage:**
|
||||
```bash
|
||||
# Using cargo-tarpaulin (install with: cargo install cargo-tarpaulin)
|
||||
cargo tarpaulin --out Html # Generate HTML coverage report
|
||||
```
|
||||
|
||||
## Test File Organization
|
||||
|
||||
**Location - Unit Tests:**
|
||||
- Co-located with implementation: Tests in same file as source code
|
||||
- Tests go in submodule at end of source file
|
||||
|
||||
**Location - Integration Tests:**
|
||||
- Separate `tests/` directory at workspace root
|
||||
- File: `tests/integration_test.rs` or similar
|
||||
- Each file is compiled as separate crate
|
||||
|
||||
**Naming:**
|
||||
- Unit test modules: `#[cfg(test)] mod tests`
|
||||
- Integration test files: `integration_test.rs`, `e2e_test.rs`
|
||||
- Test functions: `test_function_name_description()`
|
||||
- Unit tests: `tests::test_parses_valid_input()`
|
||||
|
||||
**Current Structure:**
|
||||
```
|
||||
src/
|
||||
├── main.rs # Contains #[cfg(test)] mod tests
|
||||
├── lib.rs # If created, contains library tests
|
||||
└── ...
|
||||
|
||||
tests/
|
||||
├── integration_test.rs
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Test Structure
|
||||
|
||||
**Suite Organization - Unit Test Pattern:**
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_function_does_something() {
|
||||
let input = setup_test_data();
|
||||
let result = function_under_test(input);
|
||||
assert_eq!(result, expected_value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Suite Organization - Integration Test Pattern:**
|
||||
```rust
|
||||
// tests/integration_test.rs
|
||||
#[test]
|
||||
fn test_system_integrates_correctly() {
|
||||
let app = App::new();
|
||||
let result = app.process_command("help");
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
```
|
||||
|
||||
**Patterns:**
|
||||
- **Setup:** Create test data or fixtures in test function body
|
||||
- **Teardown:** Not typically needed in Rust; cleanup happens automatically when test scope ends
|
||||
- **Assertion:** Use `assert!()`, `assert_eq!()`, `assert_ne!()` for conditions
|
||||
|
||||
## Mocking
|
||||
|
||||
**Framework:** No explicit mocking framework currently integrated
|
||||
|
||||
**If mocking becomes necessary:**
|
||||
- Use `mockito` crate for HTTP mocking
|
||||
- Use `mockall` crate for trait-based mocking
|
||||
- Use `proptest` crate for property-based testing
|
||||
|
||||
**Current Approach:**
|
||||
- Manual test doubles: Create simplified implementations of traits for testing
|
||||
- Dependency injection: Pass different implementations at test time
|
||||
- Stub data: Return hardcoded test data instead of external calls
|
||||
|
||||
**Example of Manual Test Double:**
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
struct MockDataStore {
|
||||
data: Vec<String>,
|
||||
}
|
||||
|
||||
impl DataStore for MockDataStore {
|
||||
fn fetch(&self, id: u32) -> Option<String> {
|
||||
self.data.get(id as usize).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_mock() {
|
||||
let mock = MockDataStore { data: vec!["test".to_string()] };
|
||||
let result = process_data(&mock);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**What to Mock:**
|
||||
- External service calls (network, file I/O)
|
||||
- Database operations
|
||||
- Time-dependent behavior
|
||||
- Hardware-dependent code
|
||||
|
||||
**What NOT to Mock:**
|
||||
- Core business logic
|
||||
- Standard library functions
|
||||
- Tested utility functions
|
||||
- Pure functions
|
||||
|
||||
## Fixtures and Factories
|
||||
|
||||
**Test Data:**
|
||||
- Currently: Manual test data created in test functions
|
||||
- Pattern: Helper functions to build test objects
|
||||
|
||||
**Example:**
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
fn create_test_user() -> User {
|
||||
User {
|
||||
id: 1,
|
||||
name: "Test User".to_string(),
|
||||
email: "test@example.com".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_creation() {
|
||||
let user = create_test_user();
|
||||
assert_eq!(user.name, "Test User");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Location:**
|
||||
- Helper functions in same module as tests: `#[cfg(test)] mod tests`
|
||||
- If many fixtures needed: Create `src/test_utils.rs` (not included in release build via `#[cfg(test)]`)
|
||||
|
||||
## Coverage
|
||||
|
||||
**Requirements:** Not currently enforced
|
||||
|
||||
**To Enable Coverage Tracking:**
|
||||
```bash
|
||||
# Using llvm-cov (install with: cargo install cargo-llvm-cov)
|
||||
cargo llvm-cov # Generate coverage report
|
||||
cargo llvm-cov --html # HTML report in target/llvm-cov/html
|
||||
```
|
||||
|
||||
**Target for new code:**
|
||||
- Aim for 80%+ coverage on public APIs
|
||||
- 100% coverage on critical paths
|
||||
- Document uncovered code with `#[cfg(test)]` or comments
|
||||
|
||||
## Test Types
|
||||
|
||||
**Unit Tests:**
|
||||
- Scope: Single function or small module in isolation
|
||||
- Approach: Test behavior with various inputs including edge cases
|
||||
- Location: Same file as implementation in `#[cfg(test)] mod tests`
|
||||
- Tools: Standard library assertions
|
||||
|
||||
**Integration Tests:**
|
||||
- Scope: Multiple components working together
|
||||
- Approach: Test workflows and interactions between modules
|
||||
- Location: `tests/` directory at workspace root
|
||||
- Tools: Standard library assertions
|
||||
|
||||
**Doc Tests:**
|
||||
- Scope: Examples in `///` doc comments
|
||||
- Approach: Verify example code actually works
|
||||
- Location: Documentation strings in source
|
||||
- Tools: Built-in `cargo test --doc`
|
||||
|
||||
**E2E Tests:**
|
||||
- Currently: Not applicable (TUI application, no external API)
|
||||
- When applicable: Test complete user workflows end-to-end
|
||||
|
||||
**Example Doc Test:**
|
||||
```rust
|
||||
/// Calculate the sum of two numbers.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(add(2, 2), 4);
|
||||
/// ```
|
||||
pub fn add(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
**Async Testing:**
|
||||
- Not currently used (no async in codebase)
|
||||
- When needed: Use `#[tokio::test]` attribute with `tokio` crate
|
||||
|
||||
**Example (future reference):**
|
||||
```rust
|
||||
#[tokio::test]
|
||||
async fn test_async_function() {
|
||||
let result = async_operation().await;
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
```
|
||||
|
||||
**Error Testing:**
|
||||
- Test both success and failure paths
|
||||
- Use `.is_err()` or `.is_ok()` to test Result types
|
||||
- Use `.is_some()` or `.is_none()` to test Option types
|
||||
|
||||
**Example:**
|
||||
```rust
|
||||
#[test]
|
||||
fn test_handles_invalid_input() {
|
||||
let result = parse_config("invalid");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_handles_valid_input() {
|
||||
let result = parse_config("valid");
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
```
|
||||
|
||||
**Property-Based Testing (future):**
|
||||
If using `proptest`:
|
||||
```rust
|
||||
#[test]
|
||||
fn test_reverse_is_involutive(input in ".*") {
|
||||
let reversed = reverse(&input);
|
||||
let double_reversed = reverse(&reversed);
|
||||
assert_eq!(input, double_reversed);
|
||||
}
|
||||
```
|
||||
|
||||
## Test Organization Best Practices
|
||||
|
||||
**File Structure:**
|
||||
```
|
||||
src/
|
||||
├── main.rs
|
||||
├── ui.rs # Contains #[cfg(test)] mod tests at bottom
|
||||
├── handler.rs # Contains #[cfg(test)] mod tests at bottom
|
||||
└── model.rs # Contains #[cfg(test)] mod tests at bottom
|
||||
|
||||
tests/
|
||||
├── integration_tests.rs # Full-system integration tests
|
||||
└── fixtures/ # Test data files if needed
|
||||
```
|
||||
|
||||
**Test Module Template:**
|
||||
```rust
|
||||
// At end of source file
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// Setup helpers
|
||||
fn create_test_fixture() -> TestData {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Tests organized by function
|
||||
mod function_name_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_success_case() {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_case() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Testing analysis: 2026-02-28*
|
||||
Reference in New Issue
Block a user