use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; use color_eyre::{eyre::eyre, Result}; use enum_map::EnumMap; use rgb::RGB8; use serde::{Deserialize, Serialize}; use deckster_shared::image_filter::ImageFilter; use deckster_shared::rgb::RGB8Wrapper; use crate::model; use crate::model::position::ButtonPosition; #[derive(Debug, Deserialize)] pub struct File { #[serde(default = "active_button_color_default")] pub active_button_color: RGB8Wrapper, #[serde(default = "inactive_button_color_default")] pub inactive_button_color: RGB8Wrapper, pub label_font_family: Option, pub icon_packs: Arc>, pub buttons: HashMap, // EnumMap pub initial: InitialConfig, pub mqtt: Option, } #[derive(Debug)] pub struct WithFallbackId { pub fallback_id: String, pub inner: T, } #[derive(Debug)] pub struct Config { pub active_button_color: RGB8Wrapper, pub inactive_button_color: RGB8Wrapper, pub label_font_family: Option, pub key_pages_by_id: HashMap, pub knob_pages_by_id: HashMap, pub icon_packs: Arc>, pub buttons: EnumMap, pub initial: InitialConfig, pub mqtt: Option, } fn inactive_button_color_default() -> RGB8Wrapper { RGB8::new(128, 128, 128).into() } fn active_button_color_default() -> RGB8Wrapper { RGB8::new(0, 255, 0).into() } #[derive(Debug, Deserialize, Default)] pub struct ButtonConfig { pub key_page: Option, pub knob_page: Option, } #[derive(Debug, Deserialize)] pub struct InitialConfig { pub key_page: String, pub knob_page: String, } #[derive(Debug, Deserialize)] pub struct MqttConfig { pub client_id: String, pub host: String, pub port: u16, pub credentials: Option, pub topic_prefix: String, } #[derive(Debug, Deserialize)] pub struct MqttConfigCredentials { pub username: String, pub password: String, } #[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum IconFormat { Png, Svg, } #[derive(Debug, Deserialize)] pub struct IconPack { pub path: PathBuf, pub format: IconFormat, pub global_filter: Option, } impl Config { pub fn validate(self) -> Result { if !self.key_pages_by_id.contains_key(&self.initial.key_page) { return Err(eyre!(format!( "There is no key page with the ID specified at initial.key_page: {}", &self.initial.key_page ))); } if !self.knob_pages_by_id.contains_key(&self.initial.knob_page) { return Err(eyre!(format!( "There is no knob page with the ID specified at initial.knob_page: {}", &self.initial.knob_page ))); } for (position, button) in &self.buttons { if let Some(key_page) = &button.key_page { if !self.key_pages_by_id.contains_key(key_page) { return Err(eyre!(format!( "There is no key page with the ID specified at buttons.{}.key_page: {}", position, &self.initial.key_page ))); } } if let Some(knob_page) = &button.knob_page { if !self.knob_pages_by_id.contains_key(knob_page) { return Err(eyre!(format!( "There is no knob page with the ID specified at buttons.{}.knob_page: {}", position, &self.initial.knob_page ))); } } } Ok(self) } }