rush_sync_server/server/
config.rs

1// =====================================================
2// FILE: src/server/config.rs - SERVER CONFIGURATION
3// =====================================================
4
5use crate::core::prelude::*;
6use serde::{Deserialize, Serialize};
7use std::path::PathBuf;
8
9/// Server-Modus: Dev mit Hot-Reloading, Prod optimiert
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
11pub enum ServerMode {
12    Dev,  // Hot-Reloading, Debug-Logs, CORS offen
13    Prod, // Optimiert, TLS, minimale Logs
14}
15
16impl Default for ServerMode {
17    fn default() -> Self {
18        Self::Dev
19    }
20}
21
22impl std::fmt::Display for ServerMode {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        match self {
25            Self::Dev => write!(f, "development"),
26            Self::Prod => write!(f, "production"),
27        }
28    }
29}
30
31/// Server-spezifische Konfiguration
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct ServerConfig {
34    pub mode: ServerMode,
35    pub port: u16,
36    pub host: String,
37    pub static_dir: PathBuf,
38    pub hot_reload: bool,
39    pub cors_enabled: bool,
40    pub debug_logs: bool,
41
42    // Dev-spezifische Einstellungen
43    pub dev: DevConfig,
44
45    // Prod-spezifische Einstellungen
46    pub prod: ProdConfig,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct DevConfig {
51    pub auto_compile_scss: bool,
52    pub watch_files: Vec<String>,
53    pub reload_delay_ms: u64,
54    pub show_debug_routes: bool,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct ProdConfig {
59    pub enable_tls: bool,
60    pub cert_path: Option<PathBuf>,
61    pub key_path: Option<PathBuf>,
62    pub compression: bool,
63    pub cache_static_files: bool,
64}
65
66impl Default for ServerConfig {
67    fn default() -> Self {
68        Self {
69            mode: ServerMode::Dev,
70            port: 8080,
71            host: "127.0.0.1".to_string(),
72            static_dir: PathBuf::from("static"),
73            hot_reload: true,
74            cors_enabled: true,
75            debug_logs: true,
76
77            dev: DevConfig {
78                auto_compile_scss: true,
79                watch_files: vec![
80                    "static/**/*.html".to_string(),
81                    "static/**/*.css".to_string(),
82                    "static/**/*.scss".to_string(),
83                    "static/**/*.js".to_string(),
84                ],
85                reload_delay_ms: 100,
86                show_debug_routes: true,
87            },
88
89            prod: ProdConfig {
90                enable_tls: false,
91                cert_path: None,
92                key_path: None,
93                compression: true,
94                cache_static_files: true,
95            },
96        }
97    }
98}
99
100impl ServerConfig {
101    /// Erstellt Konfiguration für spezifischen Modus
102    pub fn for_mode(mode: ServerMode, port: u16) -> Self {
103        let (hot_reload, cors_enabled, debug_logs) = match mode {
104            ServerMode::Dev => (true, true, true),
105            ServerMode::Prod => (false, false, false),
106        };
107
108        Self {
109            mode,
110            port,
111            hot_reload,
112            cors_enabled,
113            debug_logs,
114            ..Default::default()
115        }
116    }
117
118    /// Bind-Adresse für Actix-Web
119    pub fn bind_address(&self) -> String {
120        format!("{}:{}", self.host, self.port)
121    }
122
123    /// Prüft ob Konfiguration gültig ist
124    pub fn validate(&self) -> Result<()> {
125        if self.port < 1024 && self.host != "127.0.0.1" {
126            return Err(AppError::Validation(
127                "Ports < 1024 require root privileges".to_string(),
128            ));
129        }
130
131        if self.mode == ServerMode::Prod
132            && self.prod.enable_tls
133            && (self.prod.cert_path.is_none() || self.prod.key_path.is_none())
134        {
135            return Err(AppError::Validation(
136                "TLS enabled but cert/key paths missing".to_string(),
137            ));
138        }
139
140        Ok(())
141    }
142
143    /// User-friendly Beschreibung
144    pub fn description(&self) -> String {
145        format!(
146            "📊 Server Config\n   Mode: {}\n   Address: {}\n   Hot-Reload: {}\n   CORS: {}\n   Debug: {}",
147            self.mode,
148            self.bind_address(),
149            self.hot_reload,
150            self.cors_enabled,
151            self.debug_logs
152        )
153    }
154}