Skip to main content

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}