|
| 1 | +# Coding Standards |
| 2 | + |
| 3 | +This document outlines the coding standards and best practices for the Mostro CLI project. These guidelines ensure code quality, maintainability, and consistency across the codebase. |
| 4 | + |
| 5 | +## Core Principles |
| 6 | + |
| 7 | +### 1. Readability and Reuse |
| 8 | +**Priority**: Code should be written for humans first, machines second. |
| 9 | +- **Clear naming**: Use descriptive names for functions, variables, and modules (e.g., `parse_dm_events` vs `pde`). |
| 10 | +- **Function reuse**: Extract common logic into reusable functions. Place shared utilities in appropriate modules (`src/util/`, `src/parser/`, etc.). |
| 11 | +- **Module organization**: Group related functionality together (CLI commands in `src/cli/`, Protocol parsing in `src/parser/`, Utilities in `src/util/`). |
| 12 | + |
| 13 | +### 2. Avoid Code Duplication (DRY Principle) |
| 14 | +**Don't Repeat Yourself**: If the same logic appears in multiple places, extract it. |
| 15 | +- **Extract common patterns**: Create helper functions for repeated operations like DM sending. |
| 16 | +- **Centralize constants**: Import from `mostro-core::prelude` instead of hardcoding values. |
| 17 | + |
| 18 | +### 3. Simplicity |
| 19 | +**Keep It Simple**: Prefer straightforward solutions over clever ones. |
| 20 | +- **Avoid premature optimization**: Write clear code first, optimize only when needed. |
| 21 | +- **Prefer explicit over implicit**: Use `Option` and `Result` types explicitly rather than hiding errors with `unwrap()`. |
| 22 | + |
| 23 | +### 4. Function Length Limit |
| 24 | +**Maximum 300 lines per function**: If a function exceeds this limit, split it into smaller, single-responsibility functions. |
| 25 | + |
| 26 | +## Rust-Specific Guidelines |
| 27 | + |
| 28 | +### Error Handling |
| 29 | +- **Use `Result<T, E>`**: Functions that can fail should return `Result`. |
| 30 | +- **Use `anyhow::Result`**: For application-level errors, use `anyhow::Result<T>`. |
| 31 | +- **Propagate errors**: Use the `?` operator to propagate errors up the call stack. |
| 32 | +- **Add context**: Use `.context("...")` from `anyhow` to add meaningful error messages. |
| 33 | + |
| 34 | +### Type Safety |
| 35 | +- **Use strong types**: Prefer newtypes or enums (`Action`, `Status`) over primitive types. |
| 36 | +- **Leverage enums**: Use enums for state machines and role management. |
| 37 | + |
| 38 | +### Async/Await |
| 39 | +- **Prefer async/await**: Use `async fn` for I/O and network operations. |
| 40 | +- **Handle timeouts**: Use `tokio::time::timeout` for network operations. |
| 41 | + |
| 42 | +### Documentation |
| 43 | +- **Document public APIs**: Use `///` doc comments for public functions and types. |
| 44 | +- **Explain "why"**: Document the reasoning behind complex logic, not just "what". |
| 45 | + |
| 46 | +## Nostr and Mostro-Specific Guidelines |
| 47 | + |
| 48 | +### Event Kinds |
| 49 | +- **Use constants**: Always use constants from `mostro-core::prelude` (e.g., `NOSTR_ORDER_EVENT_KIND`). |
| 50 | +- **Never hardcode**: Avoid hardcoding event kind numbers like 38383. |
| 51 | + |
| 52 | +### Message Handling |
| 53 | +- **Parse DMs consistently**: Use `parse_dm_events` for all DM parsing. |
| 54 | +- **Support multiple message types**: Handle both GiftWrap (NIP-59) and PrivateDirectMessage (NIP-17). |
| 55 | + |
| 56 | +### Key Management |
| 57 | +- **Identity vs Trade Keys**: |
| 58 | + - **Identity keys** (index 0): User's main identity, used for signing. |
| 59 | + - **Trade keys** (index 1+): Ephemeral keys for each trade, ensuring privacy. |
| 60 | + |
| 61 | +## Code Organization Patterns |
| 62 | + |
| 63 | +### Module Structure |
| 64 | +```text |
| 65 | +src/ |
| 66 | +├── main.rs # Entry point |
| 67 | +├── cli.rs # CLI definitions and Context |
| 68 | +├── db.rs # Database models (User, Order) |
| 69 | +├── cli/ # CLI command implementations |
| 70 | +├── parser/ # Event parsing and display |
| 71 | +└── util/ # Core utilities (events, messaging, net) |
| 72 | +``` |
| 73 | + |
| 74 | +### Re-export Pattern |
| 75 | +Use `mod.rs` files to re-export commonly used items from submodules to keep imports clean. |
| 76 | + |
| 77 | +## Database Patterns |
| 78 | +- **User Model**: Use chainable setters and the `.save()` pattern. |
| 79 | +- **Order Management**: Use `Order::new()` to handle both insertion and updates. |
| 80 | + |
| 81 | +## CLI Command Pattern |
| 82 | +All CLI commands follow a standard flow: |
| 83 | +1. Validate inputs. |
| 84 | +2. Get required keys (Identity/Trade). |
| 85 | +3. Build the Mostro message. |
| 86 | +4. Send to Mostro (NIP-59). |
| 87 | +5. Wait for response (Subscription). |
| 88 | +6. Parse and display results. |
| 89 | + |
| 90 | +## Summary Checklist |
| 91 | +- [ ] Code is readable and well-named. |
| 92 | +- [ ] No code duplication (DRY). |
| 93 | +- [ ] Functions are under 300 lines. |
| 94 | +- [ ] Errors are handled properly (`Result`, `?`). |
| 95 | +- [ ] Event kinds use constants from `mostro-core`. |
| 96 | +- [ ] Both GiftWrap and PrivateDirectMessage are supported. |
| 97 | +- [ ] Public APIs are documented. |
| 98 | +- [ ] Code passes `cargo fmt` and `cargo clippy`. |
| 99 | +- [ ] Tests pass (`cargo test`). |
0 commit comments