rush_sync_server/setup/
setup_toml.rs

1// src/setup/setup_toml.rs - Cleaned and optimized
2use crate::core::prelude::*;
3use std::path::PathBuf;
4use tokio::fs;
5
6// Consolidated DEFAULT_CONFIG - All sections in one place
7const DEFAULT_CONFIG: &str = r#"[general]
8max_messages = 1000
9typewriter_delay = 5
10input_max_length = 100
11max_history = 30
12poll_rate = 16
13log_level = "info"
14current_theme = "dark"
15
16[language]
17current = "en"
18
19# =====================================================
20# SERVER CONFIGURATION
21# =====================================================
22[server]
23# Port Management
24port_range_start = 8080      # Starting port for auto-allocation
25port_range_end = 8180        # Maximum port for auto-allocation
26max_concurrent = 10          # Maximum simultaneous servers
27shutdown_timeout = 5         # Graceful shutdown timeout (seconds)
28startup_delay_ms = 500       # Delay after server creation (milliseconds)
29workers = 1                  # Actix workers per server
30auto_open_browser = true     # Automatically open browser
31
32# HTTPS/TLS Configuration
33enable_https = true          # Enable HTTPS support
34https_port_offset = 1000     # HTTPS port = HTTP port + offset
35cert_dir = ".rss/certs"      # Certificate storage directory
36auto_cert = true             # Generate certificates automatically
37cert_validity_days = 365     # Certificate validity (days)
38
39# Production Settings
40use_lets_encrypt = false     # Use Let's Encrypt (requires public domain)
41production_domain = "localhost"  # Production domain name
42
43# =====================================================
44# REVERSE PROXY CONFIGURATION
45# =====================================================
46[proxy]
47enabled = true               # Enable integrated reverse proxy
48port = 8000                  # Proxy listening port
49bind_address = "127.0.0.1"   # Proxy bind address
50health_check_interval = 30   # Health check interval (seconds)
51timeout_ms = 5000           # Request timeout (milliseconds)
52
53# For production use:
54# port = 80                  # Standard HTTP Port
55# bind_address = "0.0.0.0"   # All interfaces (for external access)
56
57# =====================================================
58# LOGGING CONFIGURATION
59# =====================================================
60[logging]
61max_file_size_mb = 100       # Log rotation size (100MB per file)
62max_archive_files = 9        # Archive generations (9 backups)
63compress_archives = true     # GZIP compression for archives
64log_requests = true          # Enable request logging
65log_security_alerts = true  # Enable security monitoring
66log_performance = true       # Enable performance metrics
67
68# =====================================================
69# THEME DEFINITIONS
70# =====================================================
71[theme.dark]
72output_bg = "Black"
73output_text = "White"
74output_cursor = "PIPE"
75output_cursor_color = "White"
76input_bg = "White"
77input_text = "Black"
78input_cursor_prefix = "/// "
79input_cursor = "PIPE"
80input_cursor_color = "Black"
81
82[theme.light]
83output_bg = "White"
84output_text = "Black"
85output_cursor = "PIPE"
86output_cursor_color = "Black"
87input_bg = "Black"
88input_text = "White"
89input_cursor_prefix = "/// "
90input_cursor = "PIPE"
91input_cursor_color = "White"
92
93[theme.green]
94output_bg = "Black"
95output_text = "Green"
96output_cursor = "BLOCK"
97output_cursor_color = "Green"
98input_bg = "LightGreen"
99input_text = "Black"
100input_cursor_prefix = "$ "
101input_cursor = "BLOCK"
102input_cursor_color = "Black"
103
104[theme.blue]
105output_bg = "White"
106output_text = "LightBlue"
107output_cursor = "UNDERSCORE"
108output_cursor_color = "Blue"
109input_bg = "Blue"
110input_text = "White"
111input_cursor_prefix = "> "
112input_cursor = "UNDERSCORE"
113input_cursor_color = "White"
114"#;
115
116pub async fn ensure_config_exists() -> Result<PathBuf> {
117    let config_path = get_primary_config_path()?;
118
119    // Create directory if needed
120    if let Some(parent) = config_path.parent() {
121        fs::create_dir_all(parent).await.map_err(AppError::Io)?;
122    }
123
124    // Create config file if it doesn't exist
125    if !config_path.exists() {
126        fs::write(&config_path, DEFAULT_CONFIG)
127            .await
128            .map_err(AppError::Io)?;
129
130        log::info!(
131            "{}",
132            get_translation(
133                "system.config.file_created",
134                &[&config_path.display().to_string()]
135            )
136        );
137    }
138
139    Ok(config_path)
140}
141
142pub fn get_config_paths() -> Vec<PathBuf> {
143    let mut paths = Vec::new();
144
145    if let Ok(exe_path) = std::env::current_exe() {
146        if let Some(base_dir) = exe_path.parent() {
147            // Primary locations (in order of preference)
148            paths.push(base_dir.join(".rss/rush.toml"));
149            paths.push(base_dir.join("rush.toml"));
150            paths.push(base_dir.join("config/rush.toml"));
151        }
152    }
153
154    // Development fallbacks
155    #[cfg(debug_assertions)]
156    {
157        paths.push(PathBuf::from("rush.toml"));
158        paths.push(PathBuf::from("src/rush.toml"));
159    }
160
161    paths
162}
163
164fn get_primary_config_path() -> Result<PathBuf> {
165    let exe_path = std::env::current_exe().map_err(AppError::Io)?;
166    let base_dir = exe_path
167        .parent()
168        .ok_or_else(|| AppError::Validation(get_translation("system.config.dir_error", &[])))?;
169
170    Ok(base_dir.join(".rss/rush.toml"))
171}