use antigen::{antigen, presents};
use std::time::{Duration, SystemTime};
#[antigen(
name = "system-time-unwrap-panic",
category = AntigenCategory::FunctionalCorrectness,
fingerprint = r#"all_of([body_calls("duration_since"), any_of([body_calls("unwrap"), body_calls("expect")])])"#,
family = "time-and-ordering-hazards",
summary = "A SystemTime::duration_since clock read whose Result is unwrap/expect-ed — panics in prod on backwards-clock, never in tests. (elapsed excluded: it fires on the Instant::elapsed clean sibling = the recommended fix.)",
references = ["https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.duration_since"],
)]
pub struct SystemTimeUnwrapPanic;
#[presents(SystemTimeUnwrapPanic)]
fn age_since_panicking(earlier: SystemTime) -> Duration {
SystemTime::now().duration_since(earlier).unwrap()
}
#[presents(SystemTimeUnwrapPanic)]
fn age_since_safe(earlier: SystemTime) -> Duration {
SystemTime::now()
.duration_since(earlier)
.unwrap_or(Duration::ZERO)
}
fn main() {
println!("antigen time-ordering example: see source for the affinity-pair.");
println!(
"Both siblings are #[presents]-marked, so audit lists both; the handled path is spared by the FINGERPRINT (it doesn't bind). To read the bind/spare side by side, see antigen/tests/stdlib_family_fingerprints.rs."
);
let earlier = SystemTime::now();
let _ = age_since_safe(earlier);
let _ = age_since_panicking(earlier);
}