grain_id/std.rs
1use std::time::{SystemTime, UNIX_EPOCH};
2
3use super::GrainId;
4
5impl GrainId {
6 /// Creates a `GrainId` from a [`Duration`](std::time::Duration) from [`UNIX_EPOCH`] to `timestamp` based on decisecond precision.
7 ///
8 /// See [`GrainId::from_duration`] and [`GrainId::from_timestamp_since`] for more details.
9 ///
10 /// # Examples
11 ///
12 /// ```
13 /// use chrono::Utc;
14 /// # use grain_id::*;
15 ///
16 /// let timestamp = Utc::now();
17 /// let id = GrainId::from_timestamp_unix(timestamp);
18 /// assert_eq!(id.to_u64(), ((timestamp.timestamp_millis() / 100) as u64));
19 /// ```
20 pub fn from_timestamp_unix<T>(timestamp: T) -> Self
21 where
22 T: Into<SystemTime>,
23 {
24 Self::from_timestamp_since(timestamp, UNIX_EPOCH)
25 }
26 /// Creates a `GrainId` from a [`Duration`](std::time::Duration) from `base_time` to `timestamp` based on decisecond precision.
27 ///
28 /// See [`GrainId::from_duration`] for more details.
29 ///
30 /// # Behavior when `timestamp` is earlier than `base_time`
31 ///
32 /// If `timestamp` is earlier than `base_time`, Returns the value obtained by wrapping substracting the absolute value of the duration from [`NIL`](GrainId::NIL)
33 ///
34 /// # Examples
35 ///
36 /// ```
37 /// use chrono::NaiveDate;
38 /// # use grain_id::*;
39 ///
40 /// let base_time = NaiveDate::from_ymd_opt(2025, 1, 1)
41 /// .unwrap()
42 /// .and_hms_opt(0, 0, 0)
43 /// .unwrap()
44 /// .and_utc();
45 /// let timestamp = NaiveDate::from_ymd_opt(2025, 11, 28)
46 /// .unwrap()
47 /// .and_hms_micro_opt(12, 34, 56, 789)
48 /// .unwrap()
49 /// .and_utc();
50 /// let id = GrainId::from_timestamp_since(timestamp, base_time);
51 /// assert_eq!(
52 /// id.to_u64(),
53 /// (((timestamp - base_time).num_milliseconds() / 100) as u64)
54 /// );
55 /// ```
56 pub fn from_timestamp_since<T, U>(timestamp: T, base_time: U) -> Self
57 where
58 T: Into<SystemTime>,
59 U: Into<SystemTime>,
60 {
61 match timestamp.into().duration_since(base_time.into()) {
62 Ok(x) => Self::from_duration(x),
63 Err(x) => Self::NIL.wrapping_sub(Self::from_duration(x.duration())),
64 }
65 }
66
67 /// Creates a `GrainId` from a [`Duration`](std::time::Duration) from [`UNIX_EPOCH`] to [`SystemTime::now()`] based on decisecond precision.
68 ///
69 /// See [`GrainId::from_duration`] and [`GrainId::from_timestamp_since`] for more details.
70 pub fn now_unix() -> Self {
71 Self::from_timestamp_unix(SystemTime::now())
72 }
73
74 /// Creates a `GrainId` from a [`Duration`](std::time::Duration) from `base_time` to [`SystemTime::now()`] based on decisecond precision.
75 ///
76 /// See [`GrainId::from_duration`] and [`GrainId::from_timestamp_since`] for more details.
77 pub fn now_since<T>(base_time: T) -> Self
78 where
79 T: Into<SystemTime>,
80 {
81 Self::from_timestamp_since(SystemTime::now(), base_time)
82 }
83}