#![forbid(unsafe_code)]
use serde::{Deserialize, Serialize};
use crate::scope::Scope;
#[inline]
pub fn retention_policy_key(scope: &Scope) -> Vec<u8> {
format!("{}retention", crate::keyspace::scope_prefix(scope)).into_bytes()
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct RetentionPolicy {
pub max_age_ms: u64,
#[serde(default)]
pub hard: bool,
}
impl RetentionPolicy {
pub fn max_age_ms(max_age_ms: u64) -> Self {
Self { max_age_ms, hard: false }
}
pub fn hard(mut self) -> Self {
self.hard = true;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_policy_key_is_scope_prefixed() {
let a = Scope::new("tenant-a").unwrap();
let b = Scope::new("tenant-b").unwrap();
assert_eq!(retention_policy_key(&a), b"lunaris:tenant-a:retention".to_vec());
assert_ne!(retention_policy_key(&a), retention_policy_key(&b));
}
#[test]
fn a_policy_round_trips_and_rejects_unknown_fields() {
let p = RetentionPolicy::max_age_ms(86_400_000).hard();
let bytes = serde_json::to_vec(&p).unwrap();
assert_eq!(serde_json::from_slice::<RetentionPolicy>(&bytes).unwrap(), p);
let older: RetentionPolicy = serde_json::from_str(r#"{"max_age_ms":1}"#).unwrap();
assert_eq!(older, RetentionPolicy { max_age_ms: 1, hard: false });
assert!(serde_json::from_str::<RetentionPolicy>(r#"{"maxAgeMs":1}"#).is_err());
}
}