1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::fmt;
#[derive(Debug, PartialEq, Clone)]
pub enum Value {
Variable(String),
Int(i64),
Float(f64),
String(String),
Boolean(bool),
Null,
Enum(String),
List(Vec<Value>),
Object(Vec<(String, Value)>),
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Variable(v) => write!(f, "${v}"),
Self::Int(i) => write!(f, "{i}"),
Self::Float(fl) => write!(f, "{fl}"),
Self::String(s) => {
if s.contains('"') | s.contains('\n') | s.contains('\r') {
write!(f, r#""""{s}""""#)
} else {
write!(f, r#""{s}""#)
}
}
Self::Boolean(b) => write!(f, "{b}"),
Self::Null => write!(f, "null"),
Self::Enum(val) => write!(f, "{val}"),
Self::List(list) => write!(
f,
"[{}]",
list.iter()
.map(|elt| format!("{elt}"))
.collect::<Vec<String>>()
.join(", ")
),
Self::Object(obj) => write!(
f,
"{{ {} }}",
obj.iter()
.map(|(k, v)| format!("{}: {v}", String::from(k)))
.collect::<Vec<String>>()
.join(", ")
),
}
}
}
macro_rules! to_number_value {
($ty: path, $inner_type: path, $value_variant: ident) => {
impl From<$ty> for Value {
fn from(val: $ty) -> Self {
Self::$value_variant(val as $inner_type)
}
}
};
($({$ty: path, $inner_type: path, $value_variant: ident}),+) => {
$(
to_number_value!($ty, $inner_type, $value_variant);
)+
};
}
to_number_value!(
{i64, i64, Int},
{i32, i64, Int},
{i16, i64, Int},
{i8, i64, Int},
{isize, i64, Int},
{u64, i64, Int},
{u32, i64, Int},
{u16, i64, Int},
{u8, i64, Int},
{usize, i64, Int},
{f64, f64, Float},
{f32, f64, Float}
);
impl From<String> for Value {
fn from(val: String) -> Self {
Self::String(val)
}
}
impl From<&str> for Value {
fn from(val: &str) -> Self {
Self::String(val.to_string())
}
}
impl From<bool> for Value {
fn from(val: bool) -> Self {
Self::Boolean(val)
}
}