1use anyhow::{Result, anyhow};
3
4pub fn now_ms() -> u64 {
5 std::time::SystemTime::now()
6 .duration_since(std::time::UNIX_EPOCH)
7 .unwrap_or_default()
8 .as_millis() as u64
9}
10
11pub fn since_days(days: u64) -> u64 {
12 now_ms().saturating_sub(days.saturating_mul(86_400_000))
13}
14
15pub fn parse_window(raw: Option<&str>, default_days: u64) -> Result<u64> {
16 raw.map(parse_since)
17 .transpose()?
18 .map(|d| now_ms().saturating_sub(d))
19 .or_else(|| Some(since_days(default_days)))
20 .ok_or_else(|| anyhow!("invalid window"))
21}
22
23fn parse_since(raw: &str) -> Result<u64> {
24 let s = raw.trim();
25 let (n, unit) = s.split_at(s.len().saturating_sub(1));
26 let n = n.parse::<u64>()?;
27 match unit {
28 "d" => Ok(n.saturating_mul(86_400_000)),
29 "w" => Ok(n.saturating_mul(7 * 86_400_000)),
30 _ => Err(anyhow!("since must end in d or w")),
31 }
32}