use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::config_manager::ConfigModule;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub ffplay_path: Option<PathBuf>, pub default_volume: f64,
pub default_speed: f64,
pub fullscreen_by_default: bool,
pub keybindings: KeyBindings,
pub ui: UiConfig,
}
impl ConfigModule for Config {
fn module_name() -> &'static str {
"player"
}
fn default() -> Self {
Self {
ffplay_path: None,
default_volume: 100.0,
default_speed: 1.0,
fullscreen_by_default: false,
keybindings: KeyBindings::default(),
ui: UiConfig::default(),
}
}
fn validate(&self) -> anyhow::Result<()> {
if !(0.0..=100.0).contains(&self.default_volume) {
return Err(anyhow::anyhow!("Default volume must be between 0 and 100"));
}
if self.default_speed <= 0.0 || self.default_speed > 10.0 {
return Err(anyhow::anyhow!("Default speed must be between 0.1 and 10.0"));
}
Ok(())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyBindings {
pub play_pause: String,
pub stop: String,
pub volume_up: String,
pub volume_down: String,
pub mute: String,
pub seek_forward: String,
pub seek_backward: String,
pub speed_up: String,
pub speed_down: String,
pub reset_speed: String,
pub toggle_fullscreen: String,
pub quit: String,
pub help: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UiConfig {
pub update_interval_ms: u64,
pub volume_step: f64,
pub seek_step: f64,
pub speed_step: f64,
pub show_milliseconds: bool,
}
impl Default for Config {
fn default() -> Self {
<Self as ConfigModule>::default()
}
}
impl Default for KeyBindings {
fn default() -> Self {
Self {
play_pause: "Space".to_string(),
stop: "s".to_string(),
volume_up: "Up".to_string(),
volume_down: "Down".to_string(),
mute: "m".to_string(),
seek_forward: "Right".to_string(),
seek_backward: "Left".to_string(),
speed_up: "=".to_string(),
speed_down: "-".to_string(),
reset_speed: "r".to_string(),
toggle_fullscreen: "f".to_string(),
quit: "q".to_string(),
help: "h".to_string(),
}
}
}
impl Default for UiConfig {
fn default() -> Self {
Self {
update_interval_ms: 100,
volume_step: 5.0,
seek_step: 10.0,
speed_step: 0.1,
show_milliseconds: false,
}
}
}
impl Config {
pub fn load() -> anyhow::Result<Self> {
use crate::config_manager::ConfigManager;
let manager = ConfigManager::new()?;
Ok(manager.get::<Self>())
}
pub fn save(&self) -> anyhow::Result<()> {
use crate::config_manager::ConfigManager;
let manager = ConfigManager::new()?;
manager.set(self.clone())
}
}