use std::path::PathBuf;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
const DEFAULT_IDLE_TIMEOUT_SECS: u64 = 1800;
const DEFAULT_MAX_MESSAGES_PER_ROOM: u32 = 1000;
const DEFAULT_RETENTION_SECS: u64 = 604_800;
const DEFAULT_MAX_ROOMS: u32 = 256;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct CommsConfig {
#[serde(default = "CommsConfig::default_enabled")]
pub enabled: bool,
#[serde(default)]
pub agent_id: Option<String>,
#[serde(default = "CommsConfig::default_idle_timeout_secs")]
#[schemars(range(min = 1))]
pub idle_timeout_secs: u64,
#[serde(default = "CommsConfig::default_max_messages_per_room")]
#[schemars(range(min = 1))]
pub max_messages_per_room: u32,
#[serde(default = "CommsConfig::default_retention_secs")]
#[schemars(range(min = 1))]
pub retention_secs: u64,
#[serde(default = "CommsConfig::default_max_rooms")]
#[schemars(range(min = 1))]
pub max_rooms: u32,
#[serde(default)]
pub workspace_root: Option<PathBuf>,
}
impl CommsConfig {
fn default_enabled() -> bool {
true
}
fn default_idle_timeout_secs() -> u64 {
DEFAULT_IDLE_TIMEOUT_SECS
}
fn default_max_messages_per_room() -> u32 {
DEFAULT_MAX_MESSAGES_PER_ROOM
}
fn default_retention_secs() -> u64 {
DEFAULT_RETENTION_SECS
}
fn default_max_rooms() -> u32 {
DEFAULT_MAX_ROOMS
}
}
impl Default for CommsConfig {
fn default() -> Self {
Self {
enabled: Self::default_enabled(),
agent_id: None,
idle_timeout_secs: Self::default_idle_timeout_secs(),
max_messages_per_room: Self::default_max_messages_per_room(),
retention_secs: Self::default_retention_secs(),
max_rooms: Self::default_max_rooms(),
workspace_root: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults_are_the_documented_values() {
let c = CommsConfig::default();
assert!(c.enabled);
assert_eq!(c.agent_id, None);
assert_eq!(c.idle_timeout_secs, 1800);
assert_eq!(c.max_messages_per_room, 1000);
assert_eq!(c.retention_secs, 604_800);
assert_eq!(c.max_rooms, 256);
assert_eq!(c.workspace_root, None);
}
#[test]
fn round_trips_through_toml_with_partial_keys() {
let toml = r#"
enabled = false
agent_id = "claude-code"
max_rooms = 8
"#;
let c: CommsConfig = toml::from_str(toml).expect("parse");
assert!(!c.enabled);
assert_eq!(c.agent_id.as_deref(), Some("claude-code"));
assert_eq!(c.max_rooms, 8);
assert_eq!(c.retention_secs, 604_800);
}
#[test]
fn rejects_unknown_fields() {
let toml = "bogus_key = 1\n";
assert!(toml::from_str::<CommsConfig>(toml).is_err());
}
}