1use std::collections::HashMap;
2use std::fmt::{Display, Formatter};
3
4#[derive(Clone, Debug, Default, PartialEq)]
5pub enum State {
6 #[default]
7 Null,
8 Boolean(bool),
9 Integer(u64),
10 Signed(i64),
11 Float(f64),
12 String(String),
13 Array(Vec<State>),
14 Object(HashMap<String, State>),
15}
16
17impl Display for State {
18 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
19 match self {
20 State::Null => write!(f, "Null"),
21 State::Boolean(b) => write!(f, "{}", b),
22 State::Integer(i) => write!(f, "{}", i),
23 State::Signed(s) => write!(f, "{}", s),
24 State::Float(fl) => write!(f, "{}", fl),
25 State::String(s) => write!(f, "\"{}\"", s),
26 State::Array(arr) => {
27 let elements = arr
28 .iter()
29 .map(|e| e.to_string())
30 .collect::<Vec<String>>()
31 .join(", ");
32 write!(f, "[{}]", elements)
33 }
34 State::Object(obj) => {
35 let entries = obj
36 .iter()
37 .map(|(key, value)| format!("\"{}\": {}", key, value))
38 .collect::<Vec<String>>()
39 .join(", ");
40 write!(f, "{{{}}}", entries)
41 }
42 }
43 }
44}
45
46#[cfg(feature = "serde")]
51impl serde::Serialize for State {
52 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
53 where
54 S: serde::ser::Serializer,
55 {
56 match self {
57 State::Null => serializer.serialize_none(),
58 State::Boolean(b) => serializer.serialize_bool(*b),
59 State::Integer(i) => serializer.serialize_u64(*i),
60 State::Signed(i) => serializer.serialize_i64(*i),
61 State::Float(f) => serializer.serialize_f64(*f),
62 State::String(s) => serializer.serialize_str(s),
63 State::Array(a) => serializer.collect_seq(a),
64 State::Object(o) => serializer.collect_map(o),
65 }
66 }
67}
68
69#[cfg(feature = "serde")]
70impl<'de> ::serde::Deserialize<'de> for State {
71 fn deserialize<D>(de: D) -> Result<State, D::Error>
72 where
73 D: serde::de::Deserializer<'de>,
74 {
75 Ok(State::from(serde_json::Value::deserialize(de)?))
76 }
77}
78
79#[cfg(feature = "serde")]
80impl From<serde_json::Value> for State {
81 fn from(value: serde_json::Value) -> Self {
82 match value {
83 serde_json::Value::Null => State::Null,
84 serde_json::Value::Bool(b) => State::Boolean(b),
85 serde_json::Value::Number(n) => {
86 if let Some(u) = n.as_u64() {
87 State::Integer(u)
88 } else if let Some(i) = n.as_i64() {
89 State::Signed(i)
90 } else {
91 State::Float(n.as_f64().unwrap())
92 }
93 }
94 serde_json::Value::String(s) => State::String(s),
95 serde_json::Value::Array(list) => {
96 State::Array(list.into_iter().map(Into::into).collect())
97 }
98 serde_json::Value::Object(map) => State::Object(
99 map.into_iter()
100 .map(|(key, value)| (key, value.into()))
101 .collect(),
102 ),
103 }
104 }
105}
106
107#[cfg(feature = "serde")]
108impl State {
109 pub fn into_state<T: serde::Serialize>(value: T) -> State {
110 serde_json::to_value(value).unwrap().into()
111 }
112}
113
114impl State {
118 pub fn is_null(&self) -> bool {
119 *self == State::Null
120 }
121
122 pub fn as_bool(&self) -> bool {
124 match self {
125 State::Null => false,
126 State::Boolean(b) => *b,
127 State::Integer(u) => *u > 0,
128 State::Signed(i) => *i > 0,
129 State::Float(f) => *f > 0.0,
130 State::String(s) => !s.is_empty(),
131 State::Array(a) => !a.is_empty(),
132 State::Object(o) => !o.is_empty(),
133 }
134 }
135
136 pub fn as_integer(&self) -> u64 {
138 match *self {
139 State::Boolean(b) => u64::from(b),
140 State::Integer(u) => u,
141 State::Signed(i) => match i > 0 {
142 true => i as u64,
143 false => 0,
144 },
145 State::Float(f) => f as u64,
146 _ => 0,
147 }
148 }
149 pub fn as_signed_integer(&self) -> i64 {
151 match *self {
152 State::Boolean(b) => i64::from(b),
153 State::Integer(i) => i as i64,
154 State::Signed(i) => i,
155 State::Float(f) => f as i64,
156 _ => 0,
157 }
158 }
159 pub fn as_float(&self) -> f64 {
161 match *self {
162 State::Boolean(b) => f64::from(b),
163 State::Integer(u) => u as f64,
164 State::Signed(i) => i as f64,
165 State::Float(f) => f,
166 _ => 0.0,
167 }
168 }
169
170 pub fn as_string(&self) -> String {
172 match self {
173 State::Integer(u) => format!("{}", u),
174 State::Signed(i) => format!("{}", i),
175 State::Float(f) => format!("{}", f),
176 State::String(s) => s.clone(),
177 _ => String::default(),
178 }
179 }
180
181 pub fn as_str(&self) -> &str {
183 match self {
184 State::String(ref s) => s,
185 _ => "",
186 }
187 }
188 pub fn as_array(&self) -> Vec<State> {
190 match *self {
191 State::Array(ref a) => a.clone(),
192 _ => vec![],
193 }
194 }
195 pub fn as_object(&self) -> HashMap<String, State> {
197 match self {
198 State::Object(map) => map.clone(),
199 _ => HashMap::<String, State>::default(),
200 }
201 }
202}
203
204macro_rules! impl_from_converter {
209 ($variant:ident : $T:ty) => {
210 impl From<$T> for State {
211 #[inline]
212 fn from(val: $T) -> State {
213 State::$variant(val.into())
214 }
215 }
216 };
217}
218
219impl_from_converter!(String: String);
220impl_from_converter!(Integer: u8);
221impl_from_converter!(Integer: u16);
222impl_from_converter!(Integer: u32);
223impl_from_converter!(Integer: u64);
224impl_from_converter!(Signed: i8);
225impl_from_converter!(Signed: i16);
226impl_from_converter!(Signed: i32);
227impl_from_converter!(Signed: i64);
228impl_from_converter!(Float: f32);
229impl_from_converter!(Float: f64);
230impl_from_converter!(Boolean: bool);
231impl<T: Into<State>> From<Vec<T>> for State {
235 fn from(f: Vec<T>) -> Self {
237 State::Array(f.into_iter().map(Into::into).collect())
238 }
239}
240
241impl<T: Clone + Into<State>> From<&[T]> for State {
242 fn from(f: &[T]) -> Self {
244 State::Array(f.iter().cloned().map(Into::into).collect())
245 }
246}
247
248impl<T: Into<State>> FromIterator<T> for State {
249 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
251 State::Array(iter.into_iter().map(Into::into).collect())
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use std::collections::HashMap;
258
259 use super::*;
260
261 #[test]
262 fn test_as_boolean() {
263 assert!(!State::Null.as_bool());
264
265 assert!(!State::Boolean(false).as_bool());
266 assert!(State::Boolean(true).as_bool());
267
268 assert!(!State::Integer(0).as_bool());
269 assert!(State::Integer(10).as_bool());
270
271 assert!(!State::Signed(-10).as_bool());
272 assert!(!State::Signed(0).as_bool());
273 assert!(State::Signed(10).as_bool());
274
275 assert!(!State::Float(-0.5).as_bool());
276 assert!(!State::Float(0.0).as_bool());
277 assert!(State::Float(10.5).as_bool());
278
279 assert!(!State::String(String::from("")).as_bool());
280 assert!(State::String(" ".into()).as_bool());
281
282 assert!(!State::Array(vec!()).as_bool());
283 assert!(State::Array(vec![1.into()]).as_bool());
284
285 let mut map = HashMap::new();
286 assert!(!State::Object(map.clone()).as_bool());
287 map.insert("key".to_string(), State::Integer(42));
288 assert!(State::Object(map).as_bool());
289 }
290
291 #[test]
292 fn test_as_integer() {
293 assert_eq!(State::Null.as_integer(), 0);
294 assert_eq!(State::Boolean(false).as_integer(), 0);
295 assert_eq!(State::Boolean(true).as_integer(), 1);
296 assert_eq!(State::Integer(42).as_integer(), 42);
297 assert_eq!(State::Signed(-12).as_integer(), 0);
298 assert_eq!(State::Signed(12).as_integer(), 12);
299 assert_eq!(State::Float(69.5).as_integer(), 69);
300 assert_eq!(State::Float(-69.5).as_integer(), 0);
301 assert_eq!(State::String(String::from("test")).as_integer(), 0);
302 assert_eq!(State::Array(vec![1.into()]).as_integer(), 0);
303 assert_eq!(State::Object(HashMap::new()).as_integer(), 0);
304 }
305
306 #[test]
307 fn test_as_signed_integer() {
308 assert_eq!(State::Null.as_signed_integer(), 0);
309 assert_eq!(State::Boolean(false).as_signed_integer(), 0);
310 assert_eq!(State::Boolean(true).as_signed_integer(), 1);
311 assert_eq!(State::Integer(42).as_signed_integer(), 42);
312 assert_eq!(State::Signed(-12).as_signed_integer(), -12);
313 assert_eq!(State::Signed(12).as_signed_integer(), 12);
314 assert_eq!(State::Float(69.5).as_signed_integer(), 69);
315 assert_eq!(State::Float(-69.5).as_signed_integer(), -69);
316 assert_eq!(State::String(String::from("test")).as_signed_integer(), 0);
317 assert_eq!(State::Array(vec![1.into()]).as_signed_integer(), 0);
318 assert_eq!(State::Object(HashMap::new()).as_signed_integer(), 0);
319 }
320
321 #[test]
322 fn test_as_float() {
323 assert_eq!(State::Null.as_float(), 0.0);
324 assert_eq!(State::Boolean(false).as_float(), 0.0);
325 assert_eq!(State::Boolean(true).as_float(), 1.0);
326 assert_eq!(State::Integer(42).as_float(), 42.0);
327 assert_eq!(State::Signed(-12).as_float(), -12.0);
328 assert_eq!(State::Signed(12).as_float(), 12.0);
329 assert_eq!(State::Float(69.5).as_float(), 69.5);
330 assert_eq!(State::Float(-69.5).as_float(), -69.5);
331 assert_eq!(State::String(String::from("test")).as_float(), 0.0);
332 assert_eq!(State::Array(vec![1.into()]).as_float(), 0.0);
333 assert_eq!(State::Object(HashMap::new()).as_float(), 0.0);
334 }
335
336 #[test]
337 fn test_as_string() {
338 assert_eq!(State::Null.as_string(), String::from(""));
339 assert_eq!(State::Boolean(false).as_string(), String::from(""));
340 assert_eq!(State::Boolean(true).as_string(), String::from(""));
341 assert_eq!(State::Integer(42).as_string(), String::from("42"));
342 assert_eq!(State::Signed(-12).as_string(), String::from("-12"));
343 assert_eq!(State::Signed(12).as_string(), String::from("12"));
344 assert_eq!(State::Float(69.5).as_string(), String::from("69.5"));
345 assert_eq!(
346 State::String(String::from("test")).as_string(),
347 String::from("test")
348 );
349 assert_eq!(State::Array(vec![1.into()]).as_string(), String::from(""));
350 assert_eq!(State::Object(HashMap::new()).as_string(), String::from(""));
351 }
352
353 #[test]
354 fn test_as_str() {
355 assert_eq!(State::Null.as_str(), "");
356 assert_eq!(State::Boolean(false).as_str(), "");
357 assert_eq!(State::Boolean(true).as_str(), "");
358 assert_eq!(State::Integer(42).as_str(), "");
359 assert_eq!(State::Signed(-12).as_str(), "");
360 assert_eq!(State::Signed(12).as_str(), "");
361 assert_eq!(State::Float(69.5).as_str(), "");
362 assert_eq!(State::String(String::from("test")).as_str(), "test");
363 assert_eq!(State::Array(vec![1.into()]).as_str(), "");
364 assert_eq!(State::Object(HashMap::new()).as_str(), "");
365 }
366
367 #[test]
368 fn test_as_array() {
369 assert_eq!(State::Null.as_array(), vec![]);
370 assert_eq!(State::Boolean(false).as_array(), vec![]);
371 assert_eq!(State::Boolean(true).as_array(), vec![]);
372 assert_eq!(State::Integer(42).as_array(), vec![]);
373 assert_eq!(State::Signed(-12).as_array(), vec![]);
374 assert_eq!(State::Signed(12).as_array(), vec![]);
375 assert_eq!(State::Float(69.5).as_array(), vec![]);
376 assert_eq!(State::String(String::from("test")).as_array(), vec![]);
377 assert_eq!(
378 State::Array(vec![1u8.into(), 2u8.into()]).as_array(),
379 vec![State::Integer(1), State::Integer(2)]
380 );
381 assert_eq!(State::Object(HashMap::new()).as_array(), vec![]);
382 }
383
384 #[test]
385 fn test_as_object() {
386 let empty = HashMap::new();
387 assert_eq!(State::Null.as_object(), empty);
388 assert_eq!(State::Boolean(false).as_object(), empty);
389 assert_eq!(State::Boolean(true).as_object(), empty);
390 assert_eq!(State::Integer(42).as_object(), empty);
391 assert_eq!(State::Signed(-12).as_object(), empty);
392 assert_eq!(State::Signed(12).as_object(), empty);
393 assert_eq!(State::Float(69.5).as_object(), empty);
394 assert_eq!(State::String(String::from("test")).as_object(), empty);
395 assert_eq!(State::Array(vec![1.into()]).as_object(), empty);
396
397 let mut map = HashMap::new();
398 map.insert("key".to_string(), State::Integer(42));
399
400 let state = State::Object(map.clone());
401 assert_eq!(state.as_object(), map);
402 }
403
404 #[test]
405 fn test_is_null() {
406 assert!(State::Null.is_null());
407 assert!(!State::Boolean(false).is_null());
408 assert!(!State::Boolean(true).is_null());
409 assert!(!State::Integer(42).is_null());
410 assert!(!State::Signed(-12).is_null());
411 assert!(!State::Signed(12).is_null());
412 assert!(!State::Float(69.5).is_null());
413 assert!(!State::String(String::from("test")).is_null());
414 assert!(!State::Array(vec![1.into()]).is_null());
415 assert!(!State::Object(HashMap::new()).is_null());
416 }
417
418 #[test]
419 fn test_from_conversions() {
420 let state: State = "test".to_string().into();
421 assert_eq!(state, State::String("test".into()));
422
423 let state: State = 42u8.into();
424 assert_eq!(state, State::Integer(42));
425
426 let state: State = 42u16.into();
427 assert_eq!(state, State::Integer(42));
428
429 let state: State = 42u32.into();
430 assert_eq!(state, State::Integer(42));
431
432 let state: State = 42u64.into();
433 assert_eq!(state, State::Integer(42));
434
435 let state: State = (-42i8).into();
436 assert_eq!(state, State::Signed(-42));
437
438 let state: State = (-42i16).into();
439 assert_eq!(state, State::Signed(-42));
440
441 let state: State = (-42i32).into();
442 assert_eq!(state, State::Signed(-42));
443
444 let state: State = (-42i64).into();
445 assert_eq!(state, State::Signed(-42));
446
447 let state: State = std::f32::consts::PI.into();
448 assert!(matches!(state, State::Float(f) if (f - std::f64::consts::PI).abs() < 0.00001),);
449
450 let state: State = std::f64::consts::PI.into();
451 assert_eq!(state, State::Float(std::f64::consts::PI));
452
453 let state: State = true.into();
454 assert_eq!(state, State::Boolean(true));
455
456 let vec_state: State = vec![1u8, 2u8, 3u8].into();
457 assert_eq!(
458 vec_state,
459 State::Array(vec![
460 State::Integer(1),
461 State::Integer(2),
462 State::Integer(3)
463 ])
464 );
465
466 let state: State = [1, 2].as_slice().into();
467 assert_eq!(
468 state,
469 State::Array(vec![State::Signed(1), State::Signed(2)])
470 );
471
472 let state: State = vec![1, 2].into_iter().collect();
473 assert_eq!(
474 state,
475 State::Array(vec![State::Signed(1), State::Signed(2)])
476 );
477 }
478
479 #[test]
480 fn test_display_null() {
481 let state = State::Null;
482 assert_eq!(state.to_string(), "Null");
483 }
484
485 #[test]
486 fn test_display_boolean() {
487 let state_true = State::Boolean(true);
488 let state_false = State::Boolean(false);
489 assert_eq!(state_true.to_string(), "true");
490 assert_eq!(state_false.to_string(), "false");
491 }
492
493 #[test]
494 fn test_display_integer() {
495 let state = State::Integer(42);
496 assert_eq!(state.to_string(), "42");
497 }
498
499 #[test]
500 fn test_display_signed() {
501 let state_positive = State::Signed(42);
502 let state_negative = State::Signed(-42);
503 assert_eq!(state_positive.to_string(), "42");
504 assert_eq!(state_negative.to_string(), "-42");
505 }
506
507 #[test]
508 fn test_display_float() {
509 #[allow(clippy::approx_constant)]
510 let state = State::Float(3.14);
511 assert_eq!(state.to_string(), "3.14");
512 }
513
514 #[test]
515 fn test_display_string() {
516 let state = State::String("Hello".to_string());
517 assert_eq!(state.to_string(), "\"Hello\"");
518 }
519
520 #[test]
521 fn test_display_array() {
522 let state = State::Array(vec![
523 State::Integer(1),
524 State::Boolean(false),
525 State::String("test".to_string()),
526 ]);
527 assert_eq!(state.to_string(), "[1, false, \"test\"]");
528 }
529
530 #[test]
531 fn test_display_object() {
532 let mut obj = HashMap::new();
533 obj.insert("key1".to_string(), State::Integer(10));
534 obj.insert("key2".to_string(), State::Boolean(true));
535
536 let state = State::Object(obj);
537 let result = state.to_string();
539 let expected1 = "{\"key1\": 10, \"key2\": true}";
540 let expected2 = "{\"key2\": true, \"key1\": 10}";
541
542 assert!(result == expected1 || result == expected2);
543 }
544
545 #[cfg(feature = "serde")]
546 #[cfg(test)]
547 mod serde_tests {
548 use serde_json;
549
550 use super::*;
551
552 #[test]
553 fn test_serialize_null() {
554 let state = State::Null;
555 let json = serde_json::to_string(&state).unwrap();
556 assert_eq!(json, "null");
557 }
558
559 #[test]
560 fn test_serialize_boolean() {
561 let state = State::Boolean(true);
562 let json = serde_json::to_string(&state).unwrap();
563 assert_eq!(json, "true");
564 }
565
566 #[test]
567 fn test_serialize_integer() {
568 let state = State::Integer(42);
569 let json = serde_json::to_string(&state).unwrap();
570 assert_eq!(json, "42");
571 }
572
573 #[test]
574 fn test_serialize_signed() {
575 let state = State::Signed(-42);
576 let json = serde_json::to_string(&state).unwrap();
577 assert_eq!(json, "-42");
578 }
579
580 #[test]
581 fn test_serialize_float() {
582 let state = State::Float(42.42);
583 let json = serde_json::to_string(&state).unwrap();
584 assert_eq!(json, "42.42");
585 }
586
587 #[test]
588 fn test_serialize_string() {
589 let state = State::String("test".into());
590 let json = serde_json::to_string(&state).unwrap();
591 assert_eq!(json, r#""test""#);
592 }
593
594 #[test]
595 fn test_serialize_array() {
596 let state = State::Array(vec![State::Integer(1), State::Integer(2)]);
597 let json = serde_json::to_string(&state).unwrap();
598 assert_eq!(json, "[1,2]");
599 }
600
601 #[test]
602 fn test_serialize_object() {
603 let mut map = HashMap::new();
604 map.insert("key".to_string(), State::Integer(42));
605 let state = State::Object(map);
606 let json = serde_json::to_string(&state).unwrap();
607 assert_eq!(json, r#"{"key":42}"#);
608 }
609
610 #[test]
611 fn test_deserialize_null() {
612 let json = "null";
613 let state: State = serde_json::from_str(json).unwrap();
614 assert_eq!(state, State::Null);
615 }
616
617 #[test]
618 fn test_deserialize_boolean() {
619 let json = "true";
620 let state: State = serde_json::from_str(json).unwrap();
621 assert_eq!(state, State::Boolean(true));
622 }
623
624 #[test]
625 fn test_deserialize_integer() {
626 let json = "42";
627 let state: State = serde_json::from_str(json).unwrap();
628 assert_eq!(state, State::Integer(42));
629 }
630
631 #[test]
632 fn test_deserialize_signed() {
633 let json = "-42";
634 let state: State = serde_json::from_str(json).unwrap();
635 assert_eq!(state, State::Signed(-42));
636 }
637
638 #[test]
639 fn test_deserialize_float() {
640 let json = "42.42";
641 let state: State = serde_json::from_str(json).unwrap();
642 assert_eq!(state, State::Float(42.42));
643 }
644
645 #[test]
646 fn test_deserialize_nan() {
647 let json = serde_json::to_string(&(f64::NAN)).unwrap();
648 let state: State = serde_json::from_str(json.as_str()).unwrap();
649 assert_eq!(state, State::Null);
650 }
651
652 #[test]
653 fn test_deserialize_string() {
654 let json = r#""test""#;
655 let state: State = serde_json::from_str(json).unwrap();
656 assert_eq!(state, State::String("test".into()));
657 }
658
659 #[test]
660 fn test_deserialize_array() {
661 let json = "[1,2]";
662 let state: State = serde_json::from_str(json).unwrap();
663 assert_eq!(
664 state,
665 State::Array(vec![State::Integer(1), State::Integer(2)])
666 );
667 }
668
669 #[test]
670 fn test_deserialize_object() {
671 let json = r#"{"key":42}"#;
672 let state: State = serde_json::from_str(json).unwrap();
673 let mut map = HashMap::new();
674 map.insert("key".to_string(), State::Integer(42));
675 assert_eq!(state, State::Object(map));
676 }
677
678 #[test]
679 fn test_deserialize_complex() {
680 let json = r#"{"key":42, "state": {"key": 42}}"#;
681 let state: State = serde_json::from_str(json).unwrap();
682 let mut map = HashMap::new();
683 map.insert("key".to_string(), State::Integer(42));
684 map.insert("state".to_string(), State::Object(map.clone()));
685 assert_eq!(state, State::Object(map));
686 }
687
688 #[test]
689 fn test_into_state() {
690 let input = "hello world";
691 let state = State::into_state(input);
692 assert_eq!(state.as_string(), String::from("hello world"));
693 }
694 }
695}