Files
xy/crates/xy-protocol/src/config.rs
T
logaritmisk 7e59d7d050 feat(protocol): KDL parser for ServerConfig
Adds kdl_parse module with parse_server_config() that deserialises a
KDL document into ServerConfig, with full validation of name, types,
durations, and restart/stop blocks. Also derives Default on
RestartPolicy to satisfy clippy.
2026-05-25 11:29:05 +02:00

104 lines
2.5 KiB
Rust

use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum RestartPolicy {
Always,
#[default]
OnFailure,
Never,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RestartConfig {
#[serde(default)]
pub policy: RestartPolicy,
#[serde(default = "default_backoff_initial", with = "humantime_serde")]
pub backoff_initial: Duration,
#[serde(default = "default_backoff_max", with = "humantime_serde")]
pub backoff_max: Duration,
#[serde(default = "default_max_retries_per_minute")]
pub max_retries_per_minute: u32,
}
fn default_backoff_initial() -> Duration {
Duration::from_secs(1)
}
fn default_backoff_max() -> Duration {
Duration::from_secs(30)
}
fn default_max_retries_per_minute() -> u32 {
5
}
impl Default for RestartConfig {
fn default() -> Self {
Self {
policy: RestartPolicy::default(),
backoff_initial: default_backoff_initial(),
backoff_max: default_backoff_max(),
max_retries_per_minute: default_max_retries_per_minute(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StopConfig {
#[serde(default = "default_grace", with = "humantime_serde")]
pub grace: Duration,
}
fn default_grace() -> Duration {
Duration::from_secs(10)
}
impl Default for StopConfig {
fn default() -> Self {
Self {
grace: default_grace(),
}
}
}
use std::collections::BTreeMap;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ServerConfig {
pub name: String,
pub command: PathBuf,
#[serde(default)]
pub args: Vec<String>,
pub port: u16,
#[serde(default)]
pub env: BTreeMap<String, String>,
#[serde(default)]
pub working_dir: Option<PathBuf>,
#[serde(default)]
pub restart: RestartConfig,
#[serde(default)]
pub stop: StopConfig,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn restart_config_defaults() {
let c = RestartConfig::default();
assert_eq!(c.policy, RestartPolicy::OnFailure);
assert_eq!(c.backoff_initial, Duration::from_secs(1));
assert_eq!(c.backoff_max, Duration::from_secs(30));
assert_eq!(c.max_retries_per_minute, 5);
}
#[test]
fn stop_config_defaults() {
assert_eq!(StopConfig::default().grace, Duration::from_secs(10));
}
}