diff --git a/crates/arc-workflows/src/cli/mod.rs b/crates/arc-workflows/src/cli/mod.rs index 95f0c0fd1..bdc71f7cd 100644 --- a/crates/arc-workflows/src/cli/mod.rs +++ b/crates/arc-workflows/src/cli/mod.rs @@ -3,6 +3,7 @@ pub mod cli_backend; pub mod run; #[cfg(feature = "server")] pub mod serve; +pub mod server_config; pub mod task_config; pub mod validate; diff --git a/crates/arc-workflows/src/cli/server_config.rs b/crates/arc-workflows/src/cli/server_config.rs new file mode 100644 index 000000000..47d79c320 --- /dev/null +++ b/crates/arc-workflows/src/cli/server_config.rs @@ -0,0 +1,85 @@ +use std::path::Path; + +use anyhow::{bail, Context}; +use serde::Deserialize; + +const SUPPORTED_VERSION: &str = "1"; + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ServerConfig { + pub version: String, + pub url: String, +} + +pub fn load_server_config(path: &Path) -> anyhow::Result { + let contents = + std::fs::read_to_string(path).with_context(|| format!("Failed to read {}", path.display()))?; + parse_server_config(&contents) +} + +fn parse_server_config(contents: &str) -> anyhow::Result { + let config: ServerConfig = + toml::from_str(contents).context("Failed to parse server config TOML")?; + + if config.version != SUPPORTED_VERSION { + bail!( + "Unsupported server config version {}. Only version {SUPPORTED_VERSION} is supported.", + config.version + ); + } + + Ok(config) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_valid_config() { + let toml = r#" +version = "1" +url = "http://localhost:3000" +"#; + let config = parse_server_config(toml).unwrap(); + assert_eq!(config.version, "1"); + assert_eq!(config.url, "http://localhost:3000"); + } + + #[test] + fn unsupported_version_rejected() { + let toml = r#" +version = "2" +url = "http://localhost:3000" +"#; + let err = parse_server_config(toml).unwrap_err(); + assert!( + err.to_string().contains("Unsupported server config version 2"), + "unexpected error: {err}" + ); + } + + #[test] + fn unknown_fields_rejected() { + let toml = r#" +version = "1" +url = "http://localhost:3000" +extra = "nope" +"#; + assert!(parse_server_config(toml).is_err()); + } + + #[test] + fn missing_fields_rejected() { + let no_url = r#" +version = "1" +"#; + assert!(parse_server_config(no_url).is_err()); + + let no_version = r#" +url = "http://localhost:3000" +"#; + assert!(parse_server_config(no_version).is_err()); + } +}