135 lines
3.8 KiB
Rust
135 lines
3.8 KiB
Rust
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<String>,
|
|
pub icon_packs: Arc<HashMap<String, IconPack>>,
|
|
pub buttons: HashMap<ButtonPosition, ButtonConfig>, // EnumMap
|
|
pub initial: InitialConfig,
|
|
pub mqtt: Option<MqttConfig>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct WithFallbackId<T> {
|
|
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<String>,
|
|
pub key_pages_by_id: HashMap<String, model::key_page::Page>,
|
|
pub knob_pages_by_id: HashMap<String, model::knob_page::Page>,
|
|
pub icon_packs: Arc<HashMap<String, IconPack>>,
|
|
pub buttons: EnumMap<ButtonPosition, ButtonConfig>,
|
|
pub initial: InitialConfig,
|
|
pub mqtt: Option<MqttConfig>,
|
|
}
|
|
|
|
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<String>,
|
|
pub knob_page: Option<String>,
|
|
}
|
|
|
|
#[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<MqttConfigCredentials>,
|
|
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<ImageFilter>,
|
|
}
|
|
|
|
impl Config {
|
|
pub fn validate(self) -> Result<Self> {
|
|
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)
|
|
}
|
|
}
|