refactor: Split App struct into focused components (SRP violation) #209

Closed
opened 2026-01-09 04:42:46 +00:00 by navicore · 1 comment
navicore commented 2026-01-09 04:42:46 +00:00 (Migrated from github.com)

Problem

crates/repl/src/app.rs contains a 2,046-line App struct with 54 methods handling at least 8 different responsibilities:

  1. REPL state management (input buffer, cursor, history)
  2. IR visualization (stack art, AST, LLVM IR display)
  3. LSP client communication
  4. File I/O (session management, history persistence)
  5. Command execution and expression compilation
  6. UI rendering
  7. Vim-mode editing integration
  8. Completion management

This violates the Single Responsibility Principle and makes the code difficult to test, modify, and understand.

Current Structure

pub struct App {
    // REPL state
    input: String,
    cursor_position: usize,
    history: Vec<String>,
    history_index: Option<usize>,
    
    // IR visualization
    ir_content: Option<String>,
    stack_art: Option<String>,
    
    // LSP
    lsp_client: Option<LspClient>,
    
    // Session
    session_file: PathBuf,
    
    // Vim mode
    vim_state: VimState,
    
    // Completions
    completions: Vec<String>,
    completion_index: usize,
    
    // ... 20+ more fields
}

Proposed Solution

Split into focused components:

// crates/repl/src/state.rs
pub struct ReplState {
    input: InputBuffer,
    history: History,
    cursor: Cursor,
}

// crates/repl/src/visualizer.rs  
pub struct IrVisualizer {
    content: Option<IrContent>,
    stack_art: Option<StackArt>,
    display_mode: DisplayMode,
}

// crates/repl/src/executor.rs
pub struct CommandExecutor {
    compiler: CompilerClient,
    runtime: RuntimeHandle,
}

// crates/repl/src/session.rs
pub struct SessionManager {
    session_file: PathBuf,
    history_file: PathBuf,
}

// crates/repl/src/completion.rs
pub struct CompletionManager {
    lsp_client: Option<LspClient>,
    builtin_completions: Vec<String>,
}

// crates/repl/src/app.rs - Now just orchestration
pub struct App {
    state: ReplState,
    visualizer: IrVisualizer,
    executor: CommandExecutor,
    session: SessionManager,
    completions: CompletionManager,
    vim: VimState,
}

Files Affected

  • crates/repl/src/app.rs (primary)
  • New files: state.rs, visualizer.rs, executor.rs, session.rs, completion.rs

Acceptance Criteria

  • Each component has single responsibility
  • No component exceeds 500 lines
  • Components are independently testable
  • App struct is pure orchestration (< 300 lines)
  • All REPL functionality preserved

Labels

refactor, technical-debt, high-priority

## Problem `crates/repl/src/app.rs` contains a 2,046-line `App` struct with 54 methods handling at least 8 different responsibilities: 1. REPL state management (input buffer, cursor, history) 2. IR visualization (stack art, AST, LLVM IR display) 3. LSP client communication 4. File I/O (session management, history persistence) 5. Command execution and expression compilation 6. UI rendering 7. Vim-mode editing integration 8. Completion management This violates the Single Responsibility Principle and makes the code difficult to test, modify, and understand. ## Current Structure ```rust pub struct App { // REPL state input: String, cursor_position: usize, history: Vec<String>, history_index: Option<usize>, // IR visualization ir_content: Option<String>, stack_art: Option<String>, // LSP lsp_client: Option<LspClient>, // Session session_file: PathBuf, // Vim mode vim_state: VimState, // Completions completions: Vec<String>, completion_index: usize, // ... 20+ more fields } ``` ## Proposed Solution Split into focused components: ```rust // crates/repl/src/state.rs pub struct ReplState { input: InputBuffer, history: History, cursor: Cursor, } // crates/repl/src/visualizer.rs pub struct IrVisualizer { content: Option<IrContent>, stack_art: Option<StackArt>, display_mode: DisplayMode, } // crates/repl/src/executor.rs pub struct CommandExecutor { compiler: CompilerClient, runtime: RuntimeHandle, } // crates/repl/src/session.rs pub struct SessionManager { session_file: PathBuf, history_file: PathBuf, } // crates/repl/src/completion.rs pub struct CompletionManager { lsp_client: Option<LspClient>, builtin_completions: Vec<String>, } // crates/repl/src/app.rs - Now just orchestration pub struct App { state: ReplState, visualizer: IrVisualizer, executor: CommandExecutor, session: SessionManager, completions: CompletionManager, vim: VimState, } ``` ## Files Affected - `crates/repl/src/app.rs` (primary) - New files: `state.rs`, `visualizer.rs`, `executor.rs`, `session.rs`, `completion.rs` ## Acceptance Criteria - [ ] Each component has single responsibility - [ ] No component exceeds 500 lines - [ ] Components are independently testable - [ ] App struct is pure orchestration (< 300 lines) - [ ] All REPL functionality preserved ## Labels refactor, technical-debt, high-priority
navicore commented 2026-01-10 05:19:21 +00:00 (Migrated from github.com)
https://github.com/navicore/patch-seq/pull/222
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
navicore/patch-seq#209
No description provided.