1use crate::{ID_STATE16, SemanticKey};
2use std::{
3 fmt::{Debug, Display, Formatter, LowerHex},
4 hash::{Hash, Hasher},
5 marker::PhantomData,
6 num::ParseIntError,
7 str::FromStr,
8};
9
10#[cfg(feature = "sea-orm")]
11mod for_orm;
12#[cfg(feature = "poem-openapi")]
13mod for_poem;
14#[cfg(feature = "serde")]
15mod for_serde;
16
17#[cfg(feature = "uuid")]
18mod for_uuid;
19
20#[cfg(feature = "sqlx")]
21mod for_sqlx_pgsql;
22
23pub struct Semantic32<K> {
31 id: u32,
32 kind: PhantomData<K>,
33}
34
35impl<K> Copy for Semantic32<K> {}
36
37impl<K> Clone for Semantic32<K> {
38 fn clone(&self) -> Self {
39 Self { id: self.id, kind: self.kind }
40 }
41}
42
43impl<K> Hash for Semantic32<K> {
44 fn hash<H: Hasher>(&self, state: &mut H) {
45 self.id.hash(state);
46 }
47}
48
49impl<K> PartialEq for Semantic32<K> {
50 fn eq(&self, other: &Self) -> bool {
51 self.id.eq(&other.id)
52 }
53}
54
55impl<K> Eq for Semantic32<K> {}
56
57impl<K: SemanticKey> Debug for Semantic32<K> {
58 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59 match K::KEY {
60 "" => write!(f, "{}", self.id),
61 s => write!(f, "{}-{}", s, self.id),
62 }
63 }
64}
65
66impl<K: SemanticKey> Display for Semantic32<K> {
67 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68 match K::KEY {
69 "" => write!(f, "{}", self.id),
70 s => write!(f, "{}-{:x}", s, self.id),
71 }
72 }
73}
74
75impl<K> LowerHex for Semantic32<K> {
76 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
77 LowerHex::fmt(&self.id, f)
78 }
79}
80
81impl<K> Default for Semantic32<K> {
82 fn default() -> Self {
83 Self { id: 0, kind: Default::default() }
84 }
85}
86
87impl<K> FromStr for Semantic32<K> {
88 type Err = ParseIntError;
89
90 fn from_str(s: &str) -> Result<Self, Self::Err> {
91 let mut parts = s.rsplit('-');
92 match parts.next() {
93 Some(s) => {
94 let id = u32::from_str_radix(&s, 36)?;
95 Ok(Self { id, kind: Default::default() })
96 }
97 None => Ok(Self::default()),
98 }
99 }
100}
101
102impl<K> From<i32> for Semantic32<K> {
103 fn from(value: i32) -> Self {
104 unsafe { std::mem::transmute(value) }
105 }
106}
107
108impl<K> From<u32> for Semantic32<K> {
109 fn from(value: u32) -> Self {
110 Self { id: value, kind: Default::default() }
111 }
112}
113
114impl<K> Semantic32<K> {
115 pub fn new(unix_ms: u64) -> Semantic32<K> {
116 Self { id: ID_STATE16.lock().unwrap().generate64_by(unix_ms) as u32, kind: Default::default() }
117 }
118 pub fn now() -> Self {
119 Self { id: ID_STATE16.lock().unwrap().generate64_now() as u32, kind: Default::default() }
120 }
121 pub fn as_u32(&self) -> u32 {
122 self.id
123 }
124 pub fn as_i32(&self) -> i32 {
125 unsafe { std::mem::transmute(self.id) }
126 }
127}