···11use core::fmt;22+use std::sync::Mutex;2334static LOOKUP: [u8; 32] = [45 b'2', b'3', b'4', b'5', b'6', b'7', b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j',···1312/// Timestamp Identifier1413///1514/// See: <https://atproto.com/specs/tid>1616-#[derive(Default, Hash, PartialEq, Eq, PartialOrd, Ord)]1515+#[derive(Clone, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]1716pub struct Tid(u64);18171918impl Tid {···300299 }301300302301 Ok(Tid(value))302302+}303303+304304+pub struct TidClock {305305+ ts: Mutex<u64>,306306+ id: u16,307307+}308308+309309+impl TidClock {310310+ /// Create a new TID clock with the specified ID.311311+ pub const fn with_id(clock_id: u16) -> Self {312312+ if clock_id > Tid::MAX_CLOCK_ID {313313+ panic!("TID clock ID must be in the range 0..=1023");314314+ }315315+316316+ Self {317317+ id: clock_id,318318+ ts: Mutex::new(0),319319+ }320320+ }321321+322322+ /// Generate a new TID from [`SystemTime::now()`].323323+ ///324324+ /// # Panics325325+ ///326326+ /// Panics if the current date is later than 2255-06-05 23:47:34.740991 +00:00:00.327327+ ///328328+ pub fn next(&self) -> Tid {329329+ use std::time::SystemTime;330330+331331+ // This will panic after 2554-07-21 23:34:33.709551615 +00:00:00, but332332+ // Tid::new() will start panicking around 200 years before.333333+ let mut new_ts: u64 = SystemTime::now()334334+ .duration_since(SystemTime::UNIX_EPOCH)335335+ .expect("SystemTime before UNIX epoch")336336+ .as_micros()337337+ .try_into()338338+ .unwrap();339339+340340+ let mut last = self.ts.lock().unwrap();341341+ if *last >= new_ts {342342+ new_ts = *last + 1;343343+ }344344+345345+ *last = new_ts;346346+ Tid::new(new_ts, self.id)347347+ }303348}304349305350#[cfg(test)]