use std::time::Duration;
use chrono::{DateTime, TimeDelta, Utc};
pub(super) fn due_after(answered: DateTime<Utc>, gap: Duration) -> Option<DateTime<Utc>> {
TimeDelta::from_std(gap)
.ok()
.and_then(|gap| answered.checked_add_signed(gap))
}
#[cfg(test)]
mod tests {
use super::*;
fn at(seconds: i64) -> DateTime<Utc> {
DateTime::from_timestamp(seconds, 0).expect("an instant inside the epoch")
}
#[test]
fn a_gap_an_instant_can_reach_falls_due_that_long_after_the_answer() {
assert_eq!(due_after(at(100), Duration::from_secs(30)), Some(at(130)));
}
#[test]
fn the_gap_to_the_end_of_time_falls_due_and_a_nanosecond_more_does_not() {
let answered = at(100);
let to_the_end = (DateTime::<Utc>::MAX_UTC - answered)
.to_std()
.expect("the end of time is after the epoch");
assert_eq!(
due_after(answered, to_the_end),
Some(DateTime::<Utc>::MAX_UTC)
);
assert_eq!(
due_after(answered, to_the_end + Duration::from_nanos(1)),
None
);
}
#[test]
fn a_gap_too_long_to_be_an_interval_at_all_falls_due_never() {
assert_eq!(due_after(at(100), Duration::MAX), None);
}
}