1use std::{
5 cmp, fmt,
6 fmt::{Display, Formatter},
7 ops::Deref,
8 result::Result as StdResult,
9};
10
11use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Visitor};
12
13use super::{Value, r#type::Type};
14use crate::{Result, error::TypeError};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum DictionaryEntryId {
18 U1(u8),
19 U2(u16),
20 U4(u32),
21 U8(u64),
22 U16(u128),
23}
24
25impl DictionaryEntryId {
26 pub fn from_u128(value: u128, id_type: Type) -> Result<Self> {
27 match id_type {
28 Type::Uint1 => {
29 if value > u8::MAX as u128 {
30 return Err(TypeError::DictionaryCapacityExceeded {
31 id_type: Type::Uint1,
32 value,
33 max_value: u8::MAX as u128,
34 }
35 .into());
36 }
37 Ok(Self::U1(value as u8))
38 }
39 Type::Uint2 => {
40 if value > u16::MAX as u128 {
41 return Err(TypeError::DictionaryCapacityExceeded {
42 id_type: Type::Uint2,
43 value,
44 max_value: u16::MAX as u128,
45 }
46 .into());
47 }
48 Ok(Self::U2(value as u16))
49 }
50 Type::Uint4 => {
51 if value > u32::MAX as u128 {
52 return Err(TypeError::DictionaryCapacityExceeded {
53 id_type: Type::Uint4,
54 value,
55 max_value: u32::MAX as u128,
56 }
57 .into());
58 }
59 Ok(Self::U4(value as u32))
60 }
61 Type::Uint8 => {
62 if value > u64::MAX as u128 {
63 return Err(TypeError::DictionaryCapacityExceeded {
64 id_type: Type::Uint8,
65 value,
66 max_value: u64::MAX as u128,
67 }
68 .into());
69 }
70 Ok(Self::U8(value as u64))
71 }
72 Type::Uint16 => Ok(Self::U16(value)),
73 _ => unimplemented!(
75 "Invalid dictionary id_type: {:?}. Must be Uint1, Uint2, Uint4, Uint8, or Uint16",
76 id_type
77 ),
78 }
79 }
80
81 pub fn to_u128(&self) -> u128 {
82 match self {
83 Self::U1(v) => *v as u128,
84 Self::U2(v) => *v as u128,
85 Self::U4(v) => *v as u128,
86 Self::U8(v) => *v as u128,
87 Self::U16(v) => *v,
88 }
89 }
90
91 pub fn id_type(&self) -> Type {
92 match self {
93 Self::U1(_) => Type::Uint1,
94 Self::U2(_) => Type::Uint2,
95 Self::U4(_) => Type::Uint4,
96 Self::U8(_) => Type::Uint8,
97 Self::U16(_) => Type::Uint16,
98 }
99 }
100
101 pub fn to_value(self) -> Value {
102 Value::DictionaryId(self)
103 }
104
105 pub fn from_value(value: &Value) -> Option<Self> {
106 match value {
107 Value::DictionaryId(id) => Some(*id),
108 Value::Uint1(v) => Some(Self::U1(*v)),
109 Value::Uint2(v) => Some(Self::U2(*v)),
110 Value::Uint4(v) => Some(Self::U4(*v)),
111 Value::Uint8(v) => Some(Self::U8(*v)),
112 Value::Uint16(v) => Some(Self::U16(*v)),
113 _ => None,
114 }
115 }
116}
117
118impl PartialOrd for DictionaryEntryId {
119 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
120 Some(self.cmp(other))
121 }
122}
123
124impl Ord for DictionaryEntryId {
125 fn cmp(&self, other: &Self) -> cmp::Ordering {
126 self.to_u128().cmp(&other.to_u128())
127 }
128}
129
130impl Default for DictionaryEntryId {
131 fn default() -> Self {
132 Self::U1(0)
133 }
134}
135
136impl fmt::Display for DictionaryEntryId {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 match self {
139 Self::U1(v) => write!(f, "{}", v),
140 Self::U2(v) => write!(f, "{}", v),
141 Self::U4(v) => write!(f, "{}", v),
142 Self::U8(v) => write!(f, "{}", v),
143 Self::U16(v) => write!(f, "{}", v),
144 }
145 }
146}
147
148#[repr(transparent)]
149#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
150pub struct DictionaryId(pub u64);
151
152impl Display for DictionaryId {
153 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
154 Display::fmt(&self.0, f)
155 }
156}
157
158impl Deref for DictionaryId {
159 type Target = u64;
160
161 fn deref(&self) -> &Self::Target {
162 &self.0
163 }
164}
165
166impl PartialEq<u64> for DictionaryId {
167 fn eq(&self, other: &u64) -> bool {
168 self.0.eq(other)
169 }
170}
171
172impl From<DictionaryId> for u64 {
173 fn from(value: DictionaryId) -> Self {
174 value.0
175 }
176}
177
178impl DictionaryId {
179 #[inline]
180 pub fn to_u64(self) -> u64 {
181 self.0
182 }
183}
184
185impl From<i32> for DictionaryId {
186 fn from(value: i32) -> Self {
187 Self(value as u64)
188 }
189}
190
191impl From<u64> for DictionaryId {
192 fn from(value: u64) -> Self {
193 Self(value)
194 }
195}
196
197impl Serialize for DictionaryId {
198 fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
199 where
200 S: Serializer,
201 {
202 serializer.serialize_u64(self.0)
203 }
204}
205
206impl<'de> Deserialize<'de> for DictionaryId {
207 fn deserialize<D>(deserializer: D) -> StdResult<DictionaryId, D::Error>
208 where
209 D: Deserializer<'de>,
210 {
211 struct U64Visitor;
212
213 impl Visitor<'_> for U64Visitor {
214 type Value = DictionaryId;
215
216 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
217 formatter.write_str("an unsigned 64-bit number")
218 }
219
220 fn visit_u64<E>(self, value: u64) -> StdResult<Self::Value, E> {
221 Ok(DictionaryId(value))
222 }
223 }
224
225 deserializer.deserialize_u64(U64Visitor)
226 }
227}
228
229#[cfg(test)]
230pub mod tests {
231 use super::*;
232
233 #[test]
234 fn test_from_u128_u1() {
235 let id = DictionaryEntryId::from_u128(42, Type::Uint1).unwrap();
236 assert_eq!(id, DictionaryEntryId::U1(42));
237 assert_eq!(id.to_u128(), 42);
238 assert_eq!(id.id_type(), Type::Uint1);
239 }
240
241 #[test]
242 fn test_from_u128_u1_overflow() {
243 let err = DictionaryEntryId::from_u128(256, Type::Uint1).unwrap_err();
244 assert!(err.to_string().contains("DICT_001"));
245 }
246
247 #[test]
248 fn test_from_u128_u2() {
249 let id = DictionaryEntryId::from_u128(1000, Type::Uint2).unwrap();
250 assert_eq!(id, DictionaryEntryId::U2(1000));
251 assert_eq!(id.to_u128(), 1000);
252 }
253
254 #[test]
255 fn test_from_u128_u4() {
256 let id = DictionaryEntryId::from_u128(100_000, Type::Uint4).unwrap();
257 assert_eq!(id, DictionaryEntryId::U4(100_000));
258 assert_eq!(id.to_u128(), 100_000);
259 }
260
261 #[test]
262 fn test_from_u128_u8() {
263 let id = DictionaryEntryId::from_u128(10_000_000_000, Type::Uint8).unwrap();
264 assert_eq!(id, DictionaryEntryId::U8(10_000_000_000));
265 assert_eq!(id.to_u128(), 10_000_000_000);
266 }
267
268 #[test]
269 fn test_from_u128_u16() {
270 let large_value: u128 = u64::MAX as u128 + 1;
271 let id = DictionaryEntryId::from_u128(large_value, Type::Uint16).unwrap();
272 assert_eq!(id, DictionaryEntryId::U16(large_value));
273 assert_eq!(id.to_u128(), large_value);
274 }
275
276 #[test]
277 fn test_display() {
278 assert_eq!(format!("{}", DictionaryEntryId::U1(42)), "42");
279 assert_eq!(format!("{}", DictionaryEntryId::U8(12345)), "12345");
280 }
281}