use std::{collections::HashMap, sync::Arc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Route {
pub path_prefix: String,
#[serde(default)]
pub host: Option<String>,
#[serde(default)]
pub headers: Option<HashMap<String, String>>,
pub cluster: Arc<str>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_route_without_host() {
let yaml = r#"
path_prefix: "/api"
cluster: "backend"
"#;
let route: Route = serde_yaml::from_str(yaml).unwrap();
assert_eq!(route.path_prefix, "/api", "path_prefix mismatch");
assert_eq!(&*route.cluster, "backend", "cluster mismatch");
assert!(route.host.is_none(), "host should be None when omitted");
}
#[test]
fn parse_route_with_headers() {
let yaml = r#"
path_prefix: "/"
cluster: "backend"
headers:
x-model: "claude-sonnet-4-5"
x-version: "v1"
"#;
let route: Route = serde_yaml::from_str(yaml).unwrap();
let headers = route.headers.unwrap();
assert_eq!(headers.len(), 2, "should have 2 header constraints");
assert_eq!(
headers.get("x-model").unwrap(),
"claude-sonnet-4-5",
"x-model header mismatch"
);
assert_eq!(headers.get("x-version").unwrap(), "v1", "x-version header mismatch");
}
#[test]
fn parse_route_with_host() {
let yaml = r#"
path_prefix: "/"
host: "api.example.com"
cluster: "api"
"#;
let route: Route = serde_yaml::from_str(yaml).unwrap();
assert_eq!(route.host.as_deref(), Some("api.example.com"), "host should be parsed");
}
}