//! User-configurable settings for the record daemon. use serde::{Deserialize, Serialize}; use std::path::PathBuf; use super::presets::{AudioSettings, EncoderPreset, QualityLevel}; use crate::config::get_default_output_dir; /// Main settings structure. #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct Settings { /// Video recording settings. #[serde(default)] pub video: VideoSettings, /// Output settings. #[serde(default)] pub output: OutputSettings, /// Audio capture settings. #[serde(default)] pub audio: AudioSettings, /// Daemon behavior settings. #[serde(default)] pub daemon: DaemonSettings, } /// Video recording settings. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct VideoSettings { /// Encoder preset (codec and quality settings). #[serde(default)] pub encoder_preset: EncoderPreset, /// Quality level preset. #[serde(default)] pub quality: QualityLevel, /// Target frame rate. #[serde(default = "default_frame_rate")] pub frame_rate: u32, /// Enable hardware acceleration. #[serde(default = "default_true")] pub hardware_acceleration: bool, } impl Default for VideoSettings { fn default() -> Self { Self { encoder_preset: EncoderPreset::default(), quality: QualityLevel::default(), frame_rate: default_frame_rate(), hardware_acceleration: true, } } } fn default_frame_rate() -> u32 { 60 } fn default_true() -> bool { true } /// Output settings for recordings. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OutputSettings { /// Directory where recordings will be saved. #[serde(default = "default_output_path")] pub path: PathBuf, /// File naming pattern. /// Supports: {date}, {time}, {game_id}, {champion}, {queue_type} #[serde(default = "default_naming_pattern")] pub naming_pattern: String, /// Container format (mp4, mkv, etc.). #[serde(default = "default_container")] pub container: String, /// Split recordings by size (MB). 0 = no splitting. #[serde(default)] pub split_size_mb: u32, /// Split recordings by time (minutes). 0 = no splitting. #[serde(default)] pub split_time_minutes: u32, } impl OutputSettings { /// Get the output format enum for this container. pub fn output_format(&self) -> crate::recording::OutputFormat { crate::recording::OutputFormat::from(self.container.as_str()) } } impl Default for OutputSettings { fn default() -> Self { Self { path: default_output_path(), naming_pattern: default_naming_pattern(), container: default_container(), split_size_mb: 0, split_time_minutes: 0, } } } fn default_output_path() -> PathBuf { get_default_output_dir().unwrap_or_else(|| PathBuf::from("./recordings")) } fn default_naming_pattern() -> String { "{date}_{time}_{champion}".to_string() } fn default_container() -> String { "mp4".to_string() } /// Daemon behavior settings. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DaemonSettings { /// Automatically start recording when a match begins. #[serde(default = "default_true")] pub auto_record: bool, /// Monitor for League Client startup. #[serde(default = "default_true")] pub monitor_client: bool, /// Polling interval for client detection (milliseconds). #[serde(default = "default_poll_interval")] pub poll_interval_ms: u64, /// IPC socket path. If None, uses default path. #[serde(default)] pub socket_path: Option, /// Log level (trace, debug, info, warn, error). #[serde(default = "default_log_level")] pub log_level: String, /// Keep event timeline after recording ends. #[serde(default = "default_true")] pub save_timeline: bool, } impl Default for DaemonSettings { fn default() -> Self { Self { auto_record: true, monitor_client: true, poll_interval_ms: default_poll_interval(), socket_path: None, log_level: default_log_level(), save_timeline: true, } } } fn default_poll_interval() -> u64 { 1000 } fn default_log_level() -> String { "info".to_string() } #[cfg(test)] mod tests { use super::*; #[test] fn test_default_settings_serialization() { let settings = Settings::default(); let toml_str = toml::to_string_pretty(&settings).unwrap(); let parsed: Settings = toml::from_str(&toml_str).unwrap(); assert_eq!(settings.video.frame_rate, parsed.video.frame_rate); assert_eq!(settings.daemon.auto_record, parsed.daemon.auto_record); } }