use serde::{Deserialize, Serialize};
use crate::types::string_enum;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CacheControl {
#[serde(rename = "type")]
pub cache_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ttl: Option<CacheTtl>,
}
impl CacheControl {
pub fn ephemeral() -> Self {
Self {
cache_type: "ephemeral".to_string(),
ttl: None,
}
}
pub fn ephemeral_with_ttl(ttl: CacheTtl) -> Self {
Self {
cache_type: "ephemeral".to_string(),
ttl: Some(ttl),
}
}
}
impl Default for CacheControl {
fn default() -> Self {
Self::ephemeral()
}
}
string_enum! {
pub enum CacheTtl {
FiveMinutes = "5m",
OneHour = "1h",
}
}
#[cfg(test)]
mod tests {
use super::*;
fn rt<T>(json: serde_json::Value) -> serde_json::Value
where
T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug,
{
let parsed: T = serde_json::from_value(json).expect("deserialize");
let out = serde_json::to_value(&parsed).expect("serialize");
let reparsed: T = serde_json::from_value(out.clone()).expect("re-deserialize");
assert_eq!(parsed, reparsed, "struct round-trip mismatch");
out
}
#[test]
fn ephemeral_forms_round_trip() {
let plain = serde_json::json!({"type": "ephemeral"});
assert_eq!(rt::<CacheControl>(plain.clone()), plain);
let one_hour = serde_json::json!({"type": "ephemeral", "ttl": "1h"});
assert_eq!(rt::<CacheControl>(one_hour.clone()), one_hour);
let five_min = serde_json::json!({"type": "ephemeral", "ttl": "5m"});
assert_eq!(rt::<CacheControl>(five_min.clone()), five_min);
}
#[test]
fn unknown_ttl_is_preserved() {
let parsed: CacheTtl = serde_json::from_value(serde_json::json!("42m")).unwrap();
assert_eq!(parsed, CacheTtl::Unknown("42m".to_string()));
assert_eq!(
serde_json::to_value(&parsed).unwrap(),
serde_json::json!("42m")
);
}
}