use serde::{Deserialize, Serialize};
use crate::calendar::ScheduleWindow;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SlaCommitment {
pub metric: String,
pub target: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RateLimit {
pub resource: String,
pub limit: u64,
pub window: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperationalSection {
#[serde(skip_serializing_if = "Option::is_none")]
pub availability: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub sla: Vec<SlaCommitment>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rate_limits: Vec<RateLimit>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub supported_input_formats: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub supported_output_formats: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_payload_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_context_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub maintenance_windows: Vec<ScheduleWindow>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serde_round_trip() {
let ops = OperationalSection {
availability: Some("24/7".to_string()),
sla: vec![SlaCommitment {
metric: "uptime".to_string(),
target: "99.9%".to_string(),
}],
rate_limits: vec![RateLimit {
resource: "requests".to_string(),
limit: 1000,
window: "minute".to_string(),
}],
supported_input_formats: vec!["application/json".to_string()],
supported_output_formats: vec!["application/json".to_string()],
max_payload_bytes: Some(10_485_760),
max_context_tokens: Some(128_000),
maintenance_windows: vec![],
};
let json = serde_json::to_string_pretty(&ops).unwrap_or_default();
let parsed: OperationalSection =
serde_json::from_str(&json).unwrap_or_else(|_| ops.clone());
assert_eq!(ops, parsed);
}
#[test]
fn minimal_section_deserializes() {
let json = r#"{}"#;
let ops: Result<OperationalSection, _> = serde_json::from_str(json);
assert!(ops.is_ok());
}
}