Files
fds-os/rust/dasungd/src/config.rs
T
2026-09-21 22:29:23 +08:00

104 lines
3.1 KiB
Rust

use crate::protocol::Parameter;
use anyhow::{Context, Result, ensure};
use serde::{Deserialize, Serialize};
use std::{
collections::BTreeMap,
fs,
path::{Path, PathBuf},
};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct Config {
pub monitor_serial: String,
pub socket: PathBuf,
pub state_file: PathBuf,
pub transport: String,
pub serial_device: Option<PathBuf>,
pub usb_path: Option<String>,
pub require_companion: bool,
pub require_display: bool,
pub keepalive_ms: u64,
pub reconnect_ms: u64,
pub watchdog_ms: u64,
pub display: Display,
pub startup: BTreeMap<Parameter, u8>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct Display {
pub enabled: bool,
pub edid: PathBuf,
// AMD's virtual hotplug API was verified on the actual machine. Other GPUs
// should use the portable firmware EDID mechanism or their KMS client.
pub hotplug: String,
}
impl Default for Display {
fn default() -> Self {
Self {
enabled: false,
edid: "/usr/lib/firmware/edid/dasung-paperlike13k-37hz.bin".into(),
hotplug: "none".into(),
}
}
}
impl Default for Config {
fn default() -> Self {
Self {
monitor_serial: "L56051794302".into(),
socket: "/run/dasungd/control.sock".into(),
state_file: "/run/dasungd/settings.json".into(),
transport: "usb".into(),
serial_device: None,
usb_path: None,
require_companion: true,
require_display: true,
keepalive_ms: 2000,
reconnect_ms: 2000,
watchdog_ms: 30000,
display: Display::default(),
startup: BTreeMap::new(),
}
}
}
impl Config {
pub fn load(path: &Path) -> Result<Self> {
let config: Self = toml::from_str(
&fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?,
)?;
ensure!(
!config.monitor_serial.is_empty(),
"monitor_serial must identify the intended monitor"
);
ensure!(
(500..=5000).contains(&config.keepalive_ms),
"keepalive_ms must be 500..5000"
);
ensure!(
(500..=30000).contains(&config.reconnect_ms),
"reconnect_ms must be 500..30000"
);
ensure!(
config.watchdog_ms >= 20000,
"watchdog_ms must be at least 20000"
);
ensure!(
matches!(config.transport.as_str(), "usb" | "serial"),
"transport must be usb or serial"
);
ensure!(
config.transport != "serial" || config.serial_device.is_some(),
"serial transport needs serial_device"
);
ensure!(
matches!(config.display.hotplug.as_str(), "none" | "amdgpu"),
"display.hotplug must be none or amdgpu"
);
for (&parameter, &value) in &config.startup {
parameter.validate(value)?;
}
Ok(config)
}
}