zim-studio 0.8.1

A Terminal-Based Audio Project Scaffold and Metadata System
Documentation
# browser.rs Analysis and Refactoring Plan

## Overview
`player/browser.rs` implements a telescope-style file browser for audio discovery, totaling 490 lines. It searches markdown sidecar files for metadata while displaying the actual audio files.

## Public Interface

### Core Browser Methods
```rust
impl Browser {
    pub fn new() -> Self
    pub fn scan_directory(&mut self, path: &Path) -> Result<(), Box<dyn std::error::Error>>
    pub fn toggle(&mut self)
    pub fn push_char(&mut self, c: char)
    pub fn pop_char(&mut self)
    pub fn clear_search(&mut self)  // marked as dead_code
    pub fn select_next(&mut self)
    pub fn select_previous(&mut self)
    pub fn get_selected_path(&self) -> Option<&Path>
}

// UI Function
pub fn draw_browser(f: &mut Frame, area: Rect, browser: &Browser)
```

## Current Structure Analysis

### Strengths
- Clear separation between data model and UI rendering
- Efficient substring search implementation
- Good handling of recursive directory scanning
- Clean metadata parsing from sidecar files

### Areas for Improvement

1. **Error Handling**
   - Uses generic `Box<dyn std::error::Error>` throughout
   - Could benefit from specific error types

2. **Large Functions**
   - `draw_browser` (158 lines) - could be broken down
   - `filter_items` (71 lines) - complex scoring logic
   - `scan_directory_recursive` (68 lines) - file type handling

3. **Code Duplication**
   - Similar pattern matching for file extensions appears twice
   - Context extraction could be reused

## Refactoring Opportunities

### 1. Extract UI Components
Break down `draw_browser` into smaller functions:
- `draw_search_input`
- `draw_results_list`
- `draw_help_bar`
- `draw_preview_pane`

### 2. Simplify filter_items
Extract scoring logic:
```rust
fn score_item(item: &AudioFile, query: &str) -> Option<(i64, Option<String>)>
fn find_content_match(content: &str, query: &str) -> Option<(i64, String)>
fn find_filename_match(filename: &str, query: &str) -> Option<i64>
```

### 3. File Type Handling
Create a more extensible approach:
```rust
const SUPPORTED_AUDIO_EXTENSIONS: &[&str] = &["wav", "flac"];

fn is_supported_audio_file(path: &Path) -> bool
```

## Test Requirements

### Unit Tests Needed

1. **Initialization Tests**
   - `test_new_browser()`
   - `test_browser_initial_state()`

2. **Directory Scanning Tests**
   - `test_scan_empty_directory()`
   - `test_scan_directory_with_audio_files()`
   - `test_scan_directory_recursive()`
   - `test_scan_directory_skip_hidden()`
   - `test_scan_directory_with_sidecars()`

3. **Search Tests**
   - `test_search_empty_query()`
   - `test_search_by_content()`
   - `test_search_by_filename()`
   - `test_search_by_tags()`
   - `test_search_case_insensitive()`
   - `test_search_scoring()`

4. **Navigation Tests**
   - `test_select_next_previous()`
   - `test_select_wraparound()`
   - `test_get_selected_path()`

5. **Metadata Parsing Tests**
   - `test_parse_sidecar_with_title()`
   - `test_parse_sidecar_with_tags()`
   - `test_parse_sidecar_empty()`

6. **UI State Tests**
   - `test_toggle_browser()`
   - `test_push_pop_char()`
   - `test_clear_search()`

### Helper Functions Needed
- Mock file system setup for tests
- Test data generators for audio files and sidecars

## Implementation Priority

1. **High Priority**
   - Add comprehensive unit tests
   - Refactor `draw_browser` into smaller functions
   - Extract file type constants

2. **Medium Priority**
   - Simplify `filter_items` logic
   - Improve error types
   - Add more metadata field support

3. **Low Priority**
   - Performance optimizations for large directories
   - Additional search algorithms
   - Caching for repeated searches

## Metrics

### Current State
- Lines of code: 490
- Public methods: 9
- Test coverage: 0%
- Largest function: 158 lines (draw_browser)

### Target State
- Reduce largest function to <50 lines
- Achieve 80%+ test coverage
- Extract at least 5 helper functions
- Zero clippy warnings