1use std::any::Any;
2
3#[derive(Debug, Clone)]
6pub enum Value {
7 Null,
8 Bool(bool),
9 Num(Num),
10 String(String),
11 Array(Vec<Value>),
12 }
14
15#[derive(Debug, Clone)]
17pub enum Num {
18 I64(i64),
19 U64(u64),
20 F64(f64),
21}
22
23impl Value {
24 pub fn new<T: Any>(value: T) -> Value {
27 let any_val = &value as &dyn Any;
28 if let Some(val) = any_val.downcast_ref::<bool>() {
29 Value::Bool(*val)
30 } else if let Some(val) = any_val.downcast_ref::<i64>() {
31 Value::Num(Num::I64(*val))
32 } else if let Some(val) = any_val.downcast_ref::<u64>() {
33 Value::Num(Num::U64(*val))
34 } else if let Some(val) = any_val.downcast_ref::<f64>() {
35 Value::Num(Num::F64(*val))
36 } else if let Some(val) = any_val.downcast_ref::<&'static str>() {
37 Value::String(val.to_string())
38 } else if let Some(val) = any_val.downcast_ref::<String>() {
39 Value::String(val.to_string())
40 } else if let Some(val) = any_val.downcast_ref::<Vec<Value>>() {
41 Value::Array(val.to_vec())
42 } else {
43 Value::Null
44 }
45 }
46
47 pub fn bool(&self) -> Option<bool> {
48 if let Value::Bool(val) = self {
49 Some(*val)
50 } else {
51 None
52 }
53 }
54
55 pub fn i64(&self) -> Option<i64> {
56 if let Value::Num(Num::I64(val)) = self {
57 Some(*val)
58 } else {
59 None
60 }
61 }
62
63 pub fn u64(&self) -> Option<u64> {
64 if let Value::Num(Num::U64(val)) = self {
65 Some(*val)
66 } else {
67 None
68 }
69 }
70
71 pub fn f64(&self) -> Option<f64> {
72 if let Value::Num(Num::F64(val)) = self {
73 Some(*val)
74 } else {
75 None
76 }
77 }
78
79 #[allow(non_snake_case)]
80 pub fn String(&self) -> Option<String> {
81 if let Value::String(string) = self {
82 Some(string.to_string())
83 } else {
84 None
85 }
86 }
87}