///|
/// Rust Duration-compatible timestamp: unsigned seconds and subsecond nanoseconds.
pub struct Duration {
priv seconds : UInt64
priv nanos : UInt32
} derive(Eq, Compare, Debug, Hash)
///|
/// Normalize nanoseconds; overflow beyond the largest duration is rejected.
pub fn Duration::Duration(
seconds : UInt64,
nanoseconds~ : UInt32 = 0,
) -> Duration {
let carry = (nanoseconds / 1000000000U).to_uint64()
guard checked_add_uint64(seconds, carry) is Some(seconds) else {
abort("duration overflow")
}
{ seconds, nanos: nanoseconds % 1000000000U, }
}
///|
pub fn Duration::seconds(self : Duration) -> UInt64 {
self.seconds
}
///|
pub fn Duration::nanoseconds(self : Duration) -> UInt32 {
self.nanos
}
///|
pub fn Duration::checked_add(self : Duration, other : Duration) -> Duration? {
guard checked_add_uint64(self.seconds, other.seconds) is Some(seconds) else {
return None
}
let nanos = self.nanos + other.nanos
guard checked_add_uint64(seconds, (nanos / 1000000000U).to_uint64())
is Some(seconds) else {
return None
}
Some({ seconds, nanos: nanos % 1000000000U, })
}
///|
pub impl Lattice for Duration with fn less_equal(self, other) {
self <= other
}
///|
pub impl Lattice for Duration with fn join(self, other) {
if self > other {
self
} else {
other
}
}
///|
pub impl Lattice for Duration with fn meet(self, other) {
if self < other {
self
} else {
other
}
}
///|
pub impl TotalOrder for Duration
///|
pub extend Duration with Eq::{equal, not_equal}
///|
pub extend Duration with Compare::{compare, op_lt, op_le, op_gt, op_ge}
///|
pub extend Duration with Debug::{to_repr}
///|
pub extend Duration with Hash::{hash, hash_combine}
///|
pub extend Duration with Lattice::{less_equal, join, meet}
///|
pub fn SummaryDomain::duration() -> SummaryDomain[Duration, Duration] {
SummaryDomain(
Duration(0),
apply=fn(a, b) { a.checked_add(b) },
compose=fn(a, b) { a.checked_add(b) },
less_equal=fn(a, b) { a <= b },
)
}