1use 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
261pub 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}