ricecoder_tui/
config.rs

1//! Configuration for the TUI
2//!
3//! This module provides configuration management for the RiceCoder TUI. Configuration can be
4//! loaded from files or environment variables, and includes settings for:
5//! - Theme selection
6//! - Animation preferences
7//! - Mouse support
8//! - Terminal dimensions
9//! - Accessibility options
10//!
11//! # Configuration Hierarchy
12//!
13//! Configuration is loaded in the following priority order (highest to lowest):
14//! 1. Runtime overrides (CLI flags, environment variables)
15//! 2. Project-level config (`.ricecoder/config.yaml`)
16//! 3. User-level config (`~/.ricecoder/config.yaml`)
17//! 4. Built-in defaults
18//!
19//! # Examples
20//!
21//! Loading default configuration:
22//!
23//! ```ignore
24//! use ricecoder_tui::TuiConfig;
25//!
26//! let config = TuiConfig::load()?;
27//! println!("Theme: {}", config.theme);
28//! println!("Animations: {}", config.animations);
29//! ```
30//!
31//! Creating custom configuration:
32//!
33//! ```ignore
34//! use ricecoder_tui::TuiConfig;
35//!
36//! let config = TuiConfig {
37//!     theme: "dracula".to_string(),
38//!     animations: false,
39//!     mouse: true,
40//!     ..Default::default()
41//! };
42//! config.save()?;
43//! ```
44//!
45//! # Configuration File Format
46//!
47//! Configuration files use YAML format:
48//!
49//! ```yaml
50//! theme: dracula
51//! animations: true
52//! mouse: true
53//! accessibility:
54//!   screen_reader_enabled: false
55//!   high_contrast_mode: false
56//!   disable_animations: false
57//! ```
58
59use crate::accessibility::AccessibilityConfig;
60use anyhow::Result;
61use serde::{Deserialize, Serialize};
62use std::path::PathBuf;
63
64/// TUI configuration
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct TuiConfig {
67    /// Theme name
68    pub theme: String,
69    /// Enable animations
70    pub animations: bool,
71    /// Enable mouse support
72    pub mouse: bool,
73    /// Terminal width
74    pub width: Option<u16>,
75    /// Terminal height
76    pub height: Option<u16>,
77    /// Accessibility configuration
78    #[serde(default)]
79    pub accessibility: AccessibilityConfig,
80    /// AI provider to use
81    #[serde(default)]
82    pub provider: Option<String>,
83    /// Model to use
84    #[serde(default)]
85    pub model: Option<String>,
86    /// Enable vim keybindings
87    #[serde(default)]
88    pub vim_mode: bool,
89}
90
91impl Default for TuiConfig {
92    fn default() -> Self {
93        Self {
94            theme: "dark".to_string(),
95            animations: true,
96            mouse: true,
97            width: None,
98            height: None,
99            accessibility: AccessibilityConfig::default(),
100            provider: None,
101            model: None,
102            vim_mode: false,
103        }
104    }
105}
106
107impl TuiConfig {
108    /// Load configuration from file
109    pub fn load() -> Result<Self> {
110        // TODO: Load from config file if it exists
111        Ok(Self::default())
112    }
113
114    /// Save configuration to file
115    pub fn save(&self) -> Result<()> {
116        // TODO: Save to config file
117        Ok(())
118    }
119
120    /// Get the config file path
121    pub fn config_path() -> Result<PathBuf> {
122        let config_dir = dirs::config_dir()
123            .ok_or_else(|| anyhow::anyhow!("Could not determine config directory"))?;
124        Ok(config_dir.join("ricecoder").join("tui.yaml"))
125    }
126}