mirror of
https://gitea.ingwaz.work/Ingwaz/openbrain-mcp.git
synced 2026-03-31 14:49:06 +00:00
Add TTL expiry for transient facts
This commit is contained in:
49
src/ttl.rs
Normal file
49
src/ttl.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use anyhow::{Result, anyhow};
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
|
||||
pub fn parse_ttl_spec(ttl: &str) -> Result<Duration> {
|
||||
let ttl = ttl.trim();
|
||||
if ttl.is_empty() {
|
||||
return Err(anyhow!("ttl must not be empty"));
|
||||
}
|
||||
|
||||
let (value, multiplier_seconds) = match ttl.chars().last() {
|
||||
Some('s') | Some('S') => (&ttl[..ttl.len() - 1], 1i64),
|
||||
Some('m') | Some('M') => (&ttl[..ttl.len() - 1], 60i64),
|
||||
Some('h') | Some('H') => (&ttl[..ttl.len() - 1], 60i64 * 60),
|
||||
Some('d') | Some('D') => (&ttl[..ttl.len() - 1], 60i64 * 60 * 24),
|
||||
Some('w') | Some('W') => (&ttl[..ttl.len() - 1], 60i64 * 60 * 24 * 7),
|
||||
_ => {
|
||||
return Err(anyhow!(
|
||||
"invalid ttl '{ttl}'. Use a positive duration like 30s, 15m, 1h, 7d, or 2w"
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let value: i64 = value
|
||||
.trim()
|
||||
.parse()
|
||||
.map_err(|_| anyhow!("invalid ttl '{ttl}'. Duration value must be a positive integer"))?;
|
||||
if value <= 0 {
|
||||
return Err(anyhow!("invalid ttl '{ttl}'. Duration value must be greater than zero"));
|
||||
}
|
||||
|
||||
let total_seconds = value
|
||||
.checked_mul(multiplier_seconds)
|
||||
.ok_or_else(|| anyhow!("invalid ttl '{ttl}'. Duration is too large"))?;
|
||||
|
||||
Ok(Duration::seconds(total_seconds))
|
||||
}
|
||||
|
||||
pub fn expires_at_from_ttl(ttl: Option<&str>) -> Result<Option<DateTime<Utc>>> {
|
||||
match ttl {
|
||||
Some(ttl) => {
|
||||
let duration = parse_ttl_spec(ttl)?;
|
||||
Utc::now()
|
||||
.checked_add_signed(duration)
|
||||
.map(Some)
|
||||
.ok_or_else(|| anyhow!("ttl '{ttl}' overflows supported timestamp range"))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user