Files
logbuch/AGENTS.md
itsscb 755bdb063e refactor: extract actions module and keycode helpers
- Created actions/ module with save, load, delete business logic
- Created inputs/keycodes.rs with 30+ keybinding helper functions
- Separated business logic from UI/event handling
- Added 28 new unit tests and 8 integration tests
- Fixed bug: save now requires ctrl+s not just 's'
- Reduced ui/mod.rs from 618 to ~290 lines total
2026-01-07 02:38:15 +01:00

5.4 KiB

AGENTS.md

Commands

  • Build: cargo build
  • Run: cargo run
  • Test: cargo test (single test: cargo test <test_name>)
  • Lint: cargo clippy
  • Format: cargo fmt

Code Style

  • Imports: Avoid enum_glob_use, use explicit imports
  • Formatting: Run cargo fmt before committing
  • Clippy: All lints are set to deny (enum_glob_use, pedantic, nursery, unwrap_used, expect_used). You are not allowed to overwrite this!
  • Error handling: Never use unwrap() or expect(); use proper error handling instead
  • Naming: Use snake_case for functions/variables, PascalCase for types

Architecture

Module Structure

src/
├── lib.rs                 # Library root
├── main.rs                # CLI entry point
├── models.rs              # Domain models (Entry, SortOrder, SortField)
├── state.rs               # Application state (AppState, Mode, etc.)
├── db.rs                  # Database operations (Database struct)
├── error.rs               # Error types (Dialog, Toast, etc.)
├── cli.rs                 # CLI argument parsing
└── ui/
    ├── mod.rs             # Main UI module, event loop
    ├── overview.rs        # List/preview view rendering
    ├── detail.rs          # Detail/edit form rendering
    ├── dialogs.rs         # Dialog, help, toast overlays
    ├── theme.rs           # Color constants and theme
    ├── components.rs      # Shared UI components
    ├── text_utils.rs      # Text processing utilities
    ├── inputs/            # Input handling (trait-based)
    │   ├── mod.rs         # InputHandler trait
    │   ├── keycodes.rs    # Keybinding helper functions
    │   ├── list.rs        # List mode handler
    │   ├── search.rs      # Search mode handler
    │   ├── detail.rs      # Detail mode handler
    │   └── dialog.rs      # Dialog handler
    └── actions/           # Business logic actions
        ├── mod.rs         # Action module
        ├── save.rs        # Save entry action
        ├── load.rs        # Load entries action
        └── delete.rs      # Delete entry action

Input Handling Pattern

The UI uses a trait-based input handling pattern:

pub trait InputHandler {
    fn handle(&mut self, key: KeyEvent, state: &mut AppState, db: &Database) -> Result<()>;
}

Each mode has its own handler:

  • ListInputHandler - Navigation, create, edit, delete, search
  • SearchInputHandler - Search query input
  • DetailInputHandler - Text editing, field navigation
  • DialogInputHandler - Yes/no confirmations

Actions Module

Business logic is extracted to the actions/ module:

  • save::execute() - Save entry (create or update)
  • load::execute() - Load entries from database
  • delete::execute() - Delete entry by ID
  • execute_dialog_action() - Handle dialog confirmations

Shared Utilities

  • text_utils::extract_tags_and_mentions() - Parses #tags and @mentions from text
  • components::draw_timestamps() - Renders created/modified timestamps
  • components::draw_subject_field() - Renders subject textarea
  • components::draw_message_field() - Renders message textarea

State Management

AppState in state.rs contains:

  • Mode: List, Search, or Detail
  • Entries: Vector of all entries
  • Selection: selected_index, search_matches, search_match_index
  • Sorting: sort_field, sort_order
  • Search: search_query, search_active
  • Detail editing: detail_mode, detail_field, textareas, original_entry
  • UI state: dialog, toast, show_help, areas for mouse detection

Rendering

The UI is rendered using ratatui:

  • overview::draw() - List + preview split view
  • detail::draw() - Edit/create form
  • dialogs::draw_dialog() - Confirmation dialogs
  • dialogs::draw_help() - Help overlay
  • dialogs::draw_toast() - Notification toasts

Database

Database in db.rs provides:

  • insert() - Create new entry
  • update() - Modify existing entry
  • delete() - Remove entry by ID
  • get_all() - Query entries with sorting/filtering
  • export_json() / export_csv() - Export data
  • import_json() / import_csv() - Import data

Refactoring History

Phase 1: Shared Utilities (COMPLETED)

  • Created text_utils.rs with extract_tags_and_mentions()
  • Created components.rs with shared rendering functions
  • Eliminated ~180 lines of duplicated code

Phase 2: Input Handlers (COMPLETED)

  • Created inputs/ module with trait-based handlers
  • Extracted List, Search, Detail, Dialog handlers
  • Added 17 unit tests for input handling
  • Reduced ui/mod.rs from 618 to 364 lines (-41%)

Phase 3: Actions Module (COMPLETED)

  • Created actions/ module with save, load, delete actions
  • Separated business logic from UI/event handling
  • Added 8 integration tests for UI workflows
  • Reduced ui/mod.rs from 392 to ~290 lines (-26%)

Phase 4: Keybinding Constants (COMPLETED)

  • Created inputs/keycodes.rs with helper functions for key matching
  • Added 30+ keycode helper functions (esc, ctrl_c, enter, tab, etc.)
  • Updated all input handlers to use named functions instead of raw patterns
  • All 78 tests pass, clean clippy output

Future Improvements

  • Create NavigationState struct to separate navigation from UI state
  • Add mouse click tests
  • Create Theme struct for extensibility
  • Consider command pattern for undo/redo functionality