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