use std::time::{Duration, SystemTime};
use tokio::time::Instant;
const MINIMUM_TIMESTAMP_SECONDS: i64 = -62_135_596_800;
const MAXIMUM_TIMESTAMP_SECONDS: i64 = 253_402_300_799;
pub(super) fn task_deadline(timestamp: &prost_types::Timestamp) -> Result<Instant, String> {
if !(0..1_000_000_000).contains(×tamp.nanos) {
return Err(format!(
"task deadline nanos {} out of range",
timestamp.nanos
));
}
if !(MINIMUM_TIMESTAMP_SECONDS..=MAXIMUM_TIMESTAMP_SECONDS).contains(×tamp.seconds) {
return Err(format!(
"task deadline seconds {} out of range",
timestamp.seconds
));
}
let current = Instant::now();
if timestamp.seconds < 0 {
return Ok(current);
}
let deadline = SystemTime::UNIX_EPOCH
.checked_add(Duration::from_secs(timestamp.seconds as u64))
.and_then(|time| time.checked_add(Duration::from_nanos(timestamp.nanos as u64)))
.ok_or_else(|| {
format!(
"task deadline seconds {} not representable",
timestamp.seconds
)
})?;
current
.checked_add(
deadline
.duration_since(SystemTime::now())
.unwrap_or_default(),
)
.ok_or_else(|| {
format!(
"task deadline seconds {} not representable",
timestamp.seconds
)
})
}