pak_db/
value.rs

1//==============================================================================================
2//        Pak Values
3//==============================================================================================
4
5use std::fmt::Debug;
6use serde::{Deserialize, Serialize};
7
8#[derive(Deserialize, Serialize, Clone, Hash, Default)]
9pub enum PakValue {
10    String(String),
11    Float(u64),
12    Int(i64),
13    Uint(u64),
14    Boolean(bool),
15    Array(Vec<PakValue>),
16    #[default]
17    Void
18}
19
20impl PartialEq for PakValue {
21    fn eq(&self, other: &Self) -> bool {
22        match (self, other) {
23            (PakValue::String(a), PakValue::String(b)) => a == b,
24            (PakValue::Float(a), PakValue::Float(b)) => a == b,
25            (PakValue::Float(a), PakValue::Int(b)) => f64::from_bits(*a) == *b as f64,
26            (PakValue::Float(a), PakValue::Uint(b)) => f64::from_bits(*a) == *b as f64,
27            (PakValue::Int(a), PakValue::Float(b)) => *a as f64 == f64::from_bits(*b),
28            (PakValue::Int(a), PakValue::Int(b)) => a == b,
29            (PakValue::Int(a), PakValue::Uint(b)) => *a == *b as i64,
30            (PakValue::Uint(a), PakValue::Float(b)) => *a as f64 == f64::from_bits(*b),
31            (PakValue::Uint(a), PakValue::Int(b)) => *a as i64 == *b,
32            (PakValue::Uint(a), PakValue::Uint(b)) => a == b,
33            (PakValue::Boolean(a), PakValue::Boolean(b)) => a == b,
34            (PakValue::Array(a), PakValue::Array(b)) => a == b,
35            (PakValue::Array(a), _) => {
36                let Some(first) = a.first() else { return false };
37                first == other
38            },
39            (_, PakValue::Array(b)) => {
40                let Some(first) = b.first() else { return false };
41                self == first
42            },
43            (PakValue::Void, PakValue::Void) => true,
44            _ => false,
45        }
46    }
47}
48
49impl Debug for PakValue {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        match self {
52            PakValue::String(string) => string.fmt(f),
53            PakValue::Float(float) => float.fmt(f),
54            PakValue::Int(int) => int.fmt(f),
55            PakValue::Uint(uint) => uint.fmt(f),
56            PakValue::Boolean(boolean) => boolean.fmt(f),
57            PakValue::Array(string_array) => string_array.fmt(f),
58            PakValue::Void => f.write_str("Void"),
59        }
60    }
61}
62
63impl PartialOrd for PakValue {
64    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
65        match (self, other) {
66            (PakValue::String(a), PakValue::String(b)) => a.partial_cmp(b),
67            (PakValue::Float(a), PakValue::Float(b)) => a.partial_cmp(b),
68            (PakValue::Float(a), PakValue::Int(b)) => f64::from_bits(*a).partial_cmp(&(*b as f64)),
69            (PakValue::Float(a), PakValue::Uint(b)) => f64::from_bits(*a).partial_cmp(&(*b as f64)),
70            (PakValue::Int(a), PakValue::Float(b)) => (*a as f64).partial_cmp(&f64::from_bits(*b)),
71            (PakValue::Int(a), PakValue::Int(b)) => a.partial_cmp(b),
72            (PakValue::Int(a), PakValue::Uint(b)) => (*a as i64).partial_cmp(&(*b as i64)),
73            (PakValue::Uint(a), PakValue::Float(b)) => (*a as f64).partial_cmp(&f64::from_bits(*b)),
74            (PakValue::Uint(a), PakValue::Int(b)) => (*a as i64).partial_cmp(&(*b as i64)),
75            (PakValue::Uint(a), PakValue::Uint(b)) => a.partial_cmp(b),
76            (PakValue::Boolean(a), PakValue::Boolean(b)) => a.partial_cmp(b),
77            (PakValue::Array(a), PakValue::Array(b)) => a.partial_cmp(b),
78            (PakValue::Array(a), _) => {
79                let Some(first) = a.first() else { return None };
80                first.partial_cmp(other)
81            },
82            (_, PakValue::Array(b)) => {
83                let Some(first) = b.first() else { return None };
84                self.partial_cmp(first)
85            }
86            (PakValue::Void, PakValue::Void) => Some(std::cmp::Ordering::Equal),
87            _ => None,
88        }
89    }
90}
91
92impl Eq for PakValue {}
93
94impl Ord for PakValue {
95    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
96        self.partial_cmp(other).unwrap_or(std::cmp::Ordering::Equal)
97    }
98}
99
100
101impl PakValue {
102    pub fn is_array(&self) -> bool {
103        matches!(self, PakValue::Array(_))
104    }
105    
106    pub fn is_integer(&self) -> bool {
107        matches!(self, PakValue::Int(_))
108    }
109    
110    pub fn is_unsigned_integer(&self) -> bool {
111        matches!(self, PakValue::Uint(_))
112    }
113    
114    pub fn is_string(&self) -> bool {
115        matches!(self, PakValue::String(_))
116    }
117    
118    pub fn is_float(&self) -> bool {
119        matches!(self, PakValue::Float(_))
120    }
121    
122    pub fn is_boolean(&self) -> bool {
123        matches!(self, PakValue::Boolean(_))
124    }
125    
126    pub fn is_void(&self) -> bool {
127        matches!(self, PakValue::Void)
128    }
129    
130    pub fn as_array(&self) -> Option<&[PakValue]> {
131        match self {
132            PakValue::Array(array) => Some(array),
133            _ => None,
134        }
135    }
136    
137    pub fn as_string(&self) -> Option<String> {
138        match self {
139            PakValue::String(value) => Some(value.clone()),
140            _ => None,
141        }
142    }
143
144    pub fn as_f64(&self) -> Option<f64> {
145        match self {
146            PakValue::Float(bits) => Some(f64::from_bits(*bits)),
147            _ => None,
148        }
149    }
150
151    pub fn as_f32(&self) -> Option<f32> {
152        match self {
153            PakValue::Float(bits) => Some(f64::from_bits(*bits) as f32),
154            _ => None,
155        }
156    }
157    
158    pub fn as_u64(&self) -> Option<u64> {
159        match self {
160            PakValue::Uint(value) => Some(*value),
161            _ => None,
162        }
163    }
164
165    pub fn as_u32(&self) -> Option<u32> {
166        match self {
167            PakValue::Uint(value) => Some(*value as u32),
168            _ => None,
169        }
170    }
171
172    pub fn as_u16(&self) -> Option<u16> {
173        match self {
174            PakValue::Uint(value) => Some(*value as u16),
175            _ => None,
176        }
177    }
178
179    pub fn as_u8(&self) -> Option<u8> {
180        match self {
181            PakValue::Uint(value) => Some(*value as u8),
182            _ => None,
183        }
184    }
185
186    pub fn as_i64(&self) -> Option<i64> {
187        match self {
188            PakValue::Int(value) => Some(*value),
189            _ => None,
190        }
191    }
192
193    pub fn as_i32(&self) -> Option<i32> {
194        match self {
195            PakValue::Int(value) => Some(*value as i32),
196            _ => None,
197        }
198    }
199
200    pub fn as_i16(&self) -> Option<i16> {
201        match self {
202            PakValue::Int(value) => Some(*value as i16),
203            _ => None,
204        }
205    }
206
207    pub fn as_i8(&self) -> Option<i8> {
208        match self {
209            PakValue::Int(value) => Some(*value as i8),
210            _ => None,
211        }
212    }
213
214    pub fn as_bool(&self) -> Option<bool> {
215        match self {
216            PakValue::Boolean(value) => Some(*value),
217            _ => None,
218        }
219    }
220    
221    pub fn float(float : impl Into<f64>) -> Self {
222        let f : f64 = float.into();
223        Self::Float(f.to_bits())
224    }
225    
226    pub fn int(integer : impl Into<i64>) -> Self {
227        let i : i64 = integer.into();
228        Self::Int(i)
229    }
230    
231    pub fn uint(integer : impl Into<u64>) -> Self {
232        let i : u64 = integer.into();
233        Self::Uint(i)
234    }
235    
236    pub fn contains(&self, value : &PakValue) -> bool {
237        match (self, value) {
238            (PakValue::String(a), PakValue::String(b)) => a.contains(b),
239            (PakValue::String(a), PakValue::Int(b)) => a.contains(&b.to_string()),
240            (PakValue::String(a), PakValue::Float(b)) => a.contains(&b.to_string()),
241            (PakValue::String(a), PakValue::Uint(b)) => a.contains(&b.to_string()),
242            (PakValue::String(a), PakValue::Boolean(b)) => a.contains(&b.to_string()),
243            (PakValue::Array(a), _) => a.contains(value),
244            _ => false
245        }
246    }
247    
248    pub fn to_string(&self) -> Option<String> {
249        match self {
250            PakValue::String(a) => Some(a.clone()),
251            PakValue::Int(a) => Some(a.to_string()),
252            PakValue::Uint(a) => Some(a.to_string()),
253            PakValue::Float(a) => Some(a.to_string()),
254            PakValue::Boolean(a) => Some(a.to_string()),
255            PakValue::Void => Some("Void".to_string()),
256            _ => None
257        }
258    }
259}
260
261//==============================================================================================
262//        Easy of use Traits
263//==============================================================================================
264
265pub trait IntoPakValue {
266    fn into_pak_value(self) -> PakValue;
267}
268
269impl <T> IntoPakValue for Option<T> where T : IntoPakValue {
270    fn into_pak_value(self) -> PakValue {
271        match self {
272            Some(value) => value.into_pak_value(),
273            None => PakValue::Void,
274        }
275    }
276}
277
278impl <T> IntoPakValue for T where T : Into<PakValue> {
279    fn into_pak_value(self) -> PakValue {
280        self.into()
281    }
282}
283
284impl <T> IntoPakValue for Vec<T> where T : IntoPakValue {
285    fn into_pak_value(self) -> PakValue {
286        PakValue::Array(self.into_iter().map(|value| value.into_pak_value()).collect())
287    }
288}
289
290impl<'s> From<&'s str> for PakValue {
291    fn from(value: &'s str) -> Self {
292        PakValue::String(value.to_string())
293    }
294}
295
296impl From<String> for PakValue {
297    fn from(value: String) -> Self {
298        PakValue::String(value)
299    }
300}
301
302impl From<f64> for PakValue {
303    fn from(value: f64) -> Self {
304        PakValue::Float(value.to_bits())
305    }
306}
307
308impl From<f32> for PakValue {
309    fn from(value: f32) -> Self {
310        PakValue::Float((value as f64).to_bits())
311    }
312}
313
314impl From<i64> for PakValue {
315    fn from(value: i64) -> Self {
316        PakValue::Int(value)
317    }
318}
319
320impl From<i32> for PakValue {
321    fn from(value: i32) -> Self {
322        PakValue::Int(value as i64)
323    }
324}
325
326impl From<i16> for PakValue {
327    fn from(value: i16) -> Self {
328        PakValue::Int(value as i64)
329    }
330}
331
332impl From<i8> for PakValue {
333    fn from(value: i8) -> Self {
334        PakValue::Int(value as i64)
335    }
336}
337
338impl From<u64> for PakValue {
339    fn from(value: u64) -> Self {
340        PakValue::Uint(value as u64)
341    }
342}
343
344impl From<u32> for PakValue {
345    fn from(value: u32) -> Self {
346        PakValue::Uint(value as u64)
347    }
348}
349
350impl From<u16> for PakValue {
351    fn from(value: u16) -> Self {
352        PakValue::Uint(value as u64)
353    }
354}
355
356impl From<u8> for PakValue {
357    fn from(value: u8) -> Self {
358        PakValue::Uint(value as u64)
359    }
360}
361
362impl From<bool> for PakValue {
363    fn from(value: bool) -> Self {
364        PakValue::Boolean(value)
365    }
366}