wasmer_cli/utils/
timestamp.rs1use time::{
2    Date, OffsetDateTime, PrimitiveDateTime, Time,
3    format_description::well_known::{Rfc2822, Rfc3339},
4};
5
6pub fn parse_timestamp_or_relative_time(
16    s: &str,
17    assume_negative_offset: bool,
18) -> Result<OffsetDateTime, anyhow::Error> {
19    parse_timestamp_or_relative_time_based(s, OffsetDateTime::now_utc(), assume_negative_offset)
20}
21
22pub fn parse_timestamp_or_relative_time_negative_offset(
26    s: &str,
27) -> Result<OffsetDateTime, anyhow::Error> {
28    parse_timestamp_or_relative_time(s, true)
29}
30
31pub fn parse_timestamp_or_relative_time_based(
33    s: &str,
34    base: OffsetDateTime,
35    assume_negative_offset: bool,
36) -> Result<OffsetDateTime, anyhow::Error> {
37    if let Ok(t) = OffsetDateTime::parse(s, &Rfc3339) {
38        return Ok(t);
39    }
40    if let Ok(t) = OffsetDateTime::parse(s, &Rfc2822) {
41        return Ok(t);
42    }
43    if let Ok(t) = Date::parse(s, time::macros::format_description!("[year]-[month]-[day]")) {
44        return Ok(PrimitiveDateTime::new(t, Time::MIDNIGHT).assume_utc());
45    }
46    if let Ok(t) = OffsetDateTime::parse(s, time::macros::format_description!("[unix_timestamp]")) {
47        return Ok(t);
48    }
49
50    let (is_negative, v) = match s.strip_prefix('-') {
52        Some(rest) => (true, rest),
53        None => (assume_negative_offset, s.trim_start_matches('+')),
55    };
56
57    if let Ok(duration) = humantime::parse_duration(v) {
58        let time = if is_negative {
59            base - duration
60        } else {
61            base + duration
62        };
63
64        return Ok(time);
65    }
66
67    anyhow::bail!("Unable to parse the timestamp - no known format matched")
68}