1use std::fmt::{Display, Formatter, Result};
2
3use const_fnv1a_hash::fnv1a_hash_str_64;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct ConstId {
8 id: u64,
9}
10
11impl Display for ConstId {
12 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
13 write!(f, "{}", self.id)
14 }
15}
16
17impl ConstId {
18 #[doc(hidden)]
23 pub const fn from_raw(value: u64) -> Self {
24 Self { id: value }
25 }
26
27 pub const fn generate(unique_str: &str) -> Self {
29 Self {
30 id: fnv1a_hash_str_64(unique_str),
31 }
32 }
33
34 pub const fn raw_value(&self) -> u64 {
38 self.id
39 }
40}
41
42pub unsafe trait ConstIdentify {
52 const CONST_ID: ConstId;
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use const_identify_derive::ConstIdentify;
59
60 #[derive(ConstIdentify)]
61 struct TestStruct;
62
63 #[test]
64 fn uniqueness() {
65 const ID1: ConstId = ConstId::generate("unique1");
66 const ID2: ConstId = ConstId::generate("unique2");
67 const ID3: ConstId = ConstId::generate("unique3");
68 assert_ne!(ID1, ID2);
69 assert_ne!(ID2, ID3);
70 assert_ne!(ID3, ID1);
71 }
72
73 #[test]
74 fn derive_uniqueness() {
75 #[derive(ConstIdentify)]
76 struct TestStruct;
77
78 #[derive(ConstIdentify)]
79 struct TestStruct2;
80
81 let local_id = TestStruct::CONST_ID;
82 let local_id2 = TestStruct2::CONST_ID;
83 assert_ne!(local_id, local_id2);
84
85 let global_id = tests::TestStruct::CONST_ID;
86 assert_ne!(local_id, global_id);
87 }
88
89 #[rustfmt::skip]
91 mod unformatted {
92 use super::*;
93
94 #[derive(ConstIdentify)]struct TestStruct;#[test]fn derive_uniqueness() {#[derive(ConstIdentify)]struct TestStruct;
95 let local_id = TestStruct::CONST_ID;
96 let global_id = tests::TestStruct::CONST_ID;
97 assert_ne!(local_id, global_id);
98 }
99 }
100}