Skip to content

Commit d6cdc22

Browse files
committed
fix: correct time delta
1 parent be096fe commit d6cdc22

File tree

1 file changed

+26
-22
lines changed
  • rust/signed_doc/src/validator/rules/id

1 file changed

+26
-22
lines changed

rust/signed_doc/src/validator/rules/id/mod.rs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#[cfg(test)]
44
mod tests;
55

6-
use chrono::{Duration, TimeZone, Utc};
6+
use anyhow::Context;
7+
use chrono::{DateTime, Utc};
78

89
use crate::{providers::CatalystSignedDocumentProvider, CatalystSignedDocument};
910

@@ -43,46 +44,49 @@ impl IdRule {
4344
.ok_or(anyhow::anyhow!("Document `id` field must be a UUIDv7"))?
4445
.to_unix();
4546

46-
let id_time = Utc
47-
.timestamp_opt(i64::try_from(id_time_secs).unwrap_or(0), id_time_nanos)
48-
.single()
49-
.ok_or_else(|| anyhow::anyhow!("Invalid timestamp in document `id` field"))?;
47+
let Some(id_time) = i64::try_from(id_time_secs)
48+
.ok()
49+
.and_then(|id_time_secs| DateTime::from_timestamp(id_time_secs, id_time_nanos))
50+
else {
51+
doc.report().invalid_value(
52+
"id",
53+
&id.to_string(),
54+
"Must a valid UTC date time since `UNIX_EPOCH`",
55+
"Cannot instantiate a valid `DateTime<Utc>` value from the provided `id` field timestamp.",
56+
);
57+
return Ok(false);
58+
};
5059

5160
let now = Utc::now();
61+
let time_delta = id_time.signed_duration_since(now);
5262

53-
let diff = id_time.signed_duration_since(now);
54-
55-
if diff.num_nanoseconds().unwrap_or(0) > 0 {
56-
// id_time is in the future
63+
if let Ok(id_age) = time_delta.to_std() {
64+
// `now` is earlier than `id_time`
5765
if let Some(future_threshold) = provider.future_threshold() {
58-
let threshold = Duration::from_std(future_threshold)?;
59-
if diff > threshold {
66+
if id_age > future_threshold {
6067
doc.report().invalid_value(
6168
"id",
6269
&id.to_string(),
6370
"id < now + future_threshold",
64-
&format!(
65-
"Document Version timestamp {id} cannot be too far in future (threshold: {threshold:?}) from now: {now:?}"
66-
),
71+
&format!("Document ID timestamp {id} cannot be too far in future (threshold: {future_threshold:?}) from now: {now}"),
6772
);
6873
is_valid = false;
6974
}
7075
}
7176
} else {
72-
// id_time is in the past
73-
// make positive duration
74-
let id_age = diff.abs();
77+
// `id_time` is earlier than `now`
78+
let id_age = time_delta
79+
.abs()
80+
.to_std()
81+
.context("BUG! `id_time` must be earlier than `now` at this place")?;
7582

7683
if let Some(past_threshold) = provider.past_threshold() {
77-
let threshold = Duration::from_std(past_threshold)?;
78-
if id_age > threshold {
84+
if id_age > past_threshold {
7985
doc.report().invalid_value(
8086
"id",
8187
&id.to_string(),
8288
"id > now - past_threshold",
83-
&format!(
84-
"Document Version timestamp {id} cannot be too far behind (threshold: {threshold:?}) from now: {now:?}"
85-
),
89+
&format!("Document ID timestamp {id} cannot be too far behind (threshold: {past_threshold:?}) from now: {now:?}",),
8690
);
8791
is_valid = false;
8892
}

0 commit comments

Comments
 (0)