tetratto_core2/model/
id.rs1use std::fmt::Display;
2
3use base62::decode;
4use serde::{Deserialize, Deserializer, Serialize, de::Visitor};
5use tritools::id::Id as NewId;
6use uuid::Uuid;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum Id {
10 Next(NewId),
11 Legacy(usize),
12}
13
14impl Id {
15 pub fn new() -> Self {
17 Self::Next(NewId::new())
18 }
19
20 pub fn as_usize(&self) -> usize {
22 match self {
23 Self::Next(x) => x.0.as_u128() as usize,
24 Self::Legacy(x) => *x,
25 }
26 }
27
28 pub fn printable(&self) -> String {
30 match self {
31 Self::Next(x) => x.printable(),
32 Self::Legacy(x) => x.to_string(),
33 }
34 }
35
36 pub fn serialize(&self) -> String {
38 serde_json::to_string(&self)
39 .unwrap()
40 .trim_matches('"')
41 .to_string()
42 }
43
44 pub fn deserialize(input: &str) -> Self {
46 if input.is_empty() || input.len() < 12 {
47 return Id::default();
48 }
49
50 if is_numeric(input) {
51 Id::Legacy(input.parse().unwrap())
52 } else {
53 let uuid = Uuid::from_u128(match decode(input) {
54 Ok(x) => x,
55 Err(_) => return Id::default(),
56 });
57
58 Id::Next(tritools::id::Id(uuid))
59 }
60 }
61}
62
63impl Serialize for Id {
64 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
65 where
66 S: serde::Serializer,
67 {
68 match self {
69 Self::Next(x) => serializer.serialize_str(&x.printable()),
70 Self::Legacy(x) => serializer.serialize_str(&x.to_string()),
71 }
72 }
73}
74
75struct IdVisitor;
76
77fn is_numeric(haystack: &str) -> bool {
78 for c in haystack.chars() {
79 if !c.is_numeric() {
80 return false;
81 }
82 }
83
84 true
85}
86
87macro_rules! impl_number_visitor {
88 ($n:ident, $t:ty) => {
89 fn $n<E>(self, v: $t) -> Result<Self::Value, E>
90 where
91 E: serde::de::Error,
92 {
93 Ok(Id::Legacy(v as usize))
94 }
95 };
96}
97
98impl<'de> Visitor<'de> for IdVisitor {
99 type Value = Id;
100
101 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
102 formatter.write_str("a string")
103 }
104
105 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
106 where
107 E: serde::de::Error,
108 {
109 Ok(Id::deserialize(&v))
110 }
111
112 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
113 where
114 E: serde::de::Error,
115 {
116 Ok(Id::deserialize(v))
117 }
118
119 impl_number_visitor!(visit_f32, f32);
120 impl_number_visitor!(visit_i32, i32);
121 impl_number_visitor!(visit_u32, u32);
122 impl_number_visitor!(visit_i64, i64);
123 impl_number_visitor!(visit_u64, u64);
124 impl_number_visitor!(visit_i128, i128);
125 impl_number_visitor!(visit_u128, u128);
126}
127
128impl<'de> Deserialize<'de> for Id {
129 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
130 where
131 D: Deserializer<'de>,
132 {
133 deserializer.deserialize_any(IdVisitor)
134 }
135}
136
137impl Display for Id {
138 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139 f.write_str(&self.printable())
140 }
141}
142
143impl Default for Id {
144 fn default() -> Self {
145 Self::Legacy(0)
146 }
147}