paramodel_elements/
ids.rs1use serde::{Deserialize, Serialize};
18use ulid::Ulid;
19
20#[derive(
26 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
27)]
28#[serde(transparent)]
29pub struct TrialId(Ulid);
30
31impl TrialId {
32 #[must_use]
34 pub const fn from_ulid(u: Ulid) -> Self {
35 Self(u)
36 }
37
38 #[must_use]
40 pub const fn as_ulid(&self) -> &Ulid {
41 &self.0
42 }
43
44 #[must_use]
46 pub const fn into_ulid(self) -> Ulid {
47 self.0
48 }
49}
50
51impl std::fmt::Display for TrialId {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 self.0.fmt(f)
54 }
55}
56
57impl From<Ulid> for TrialId {
58 fn from(u: Ulid) -> Self {
59 Self(u)
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn trial_id_roundtrips_ulid() {
69 let u = Ulid::from_parts(1_700_000_000_000, 42);
70 let t = TrialId::from_ulid(u);
71 assert_eq!(t.as_ulid(), &u);
72 assert_eq!(t.into_ulid(), u);
73 }
74
75 #[test]
76 fn trial_id_display_matches_ulid_display() {
77 let u = Ulid::from_parts(1_700_000_000_000, 42);
78 let t = TrialId::from_ulid(u);
79 assert_eq!(format!("{t}"), format!("{u}"));
80 }
81
82 #[test]
83 fn trial_id_is_lexicographically_ordered_by_time() {
84 let earlier = TrialId::from_ulid(Ulid::from_parts(1_000, 0));
85 let later = TrialId::from_ulid(Ulid::from_parts(2_000, 0));
86 assert!(earlier < later);
87 }
88
89 #[test]
90 fn trial_id_serde_roundtrip() {
91 let t = TrialId::from_ulid(Ulid::from_parts(1_700_000_000_000, 42));
92 let json = serde_json::to_string(&t).unwrap();
93 let back: TrialId = serde_json::from_str(&json).unwrap();
94 assert_eq!(t, back);
95 }
96}