1use std::collections::BTreeMap;
2use std::num::{ParseFloatError, ParseIntError};
3use std::str::FromStr;
4
5use crate::dump::JsonDumper;
6use crate::error::{Error, Result};
7
8pub struct Number {
9 value: String,
10}
11
12impl Number {
13 pub fn new(value: String) -> Self {
14 Self { value }
15 }
16 pub fn parse<F: FromStr>(&self) -> std::result::Result<F, F::Err> {
17 self.value.parse()
18 }
19 pub fn from<T: std::string::ToString>(val: T) -> Self {
20 Self {
21 value: val.to_string(),
22 }
23 }
24}
25
26impl ToString for Number {
27 fn to_string(&self) -> String {
28 self.value.to_string()
29 }
30}
31
32pub enum JsonValue {
34 Null,
36 Bool(bool),
38 Number(Number),
40 String(String),
42 Array(Vec<JsonValue>),
44 Object(BTreeMap<String, JsonValue>),
46}
47
48impl ToString for JsonValue {
49 fn to_string(&self) -> String {
50 JsonDumper::new(false).dump(self)
51 }
52}
53
54pub trait FromJsonValue: Sized {
56 fn from_json_value(value: &JsonValue) -> Result<Self>;
57}
58
59impl FromJsonValue for () {
60 fn from_json_value(value: &JsonValue) -> Result<Self> {
61 match value {
62 JsonValue::Null => Ok(()),
63 _ => Err(Error::validate_err("expect `JsonValue::Null`")),
64 }
65 }
66}
67
68macro_rules! from_json_value_for_int {
69 ( $( $i:ident ),* ) => {
70 $(
71 impl FromJsonValue for $i {
72 fn from_json_value(value: &JsonValue) -> Result<Self> {
73 match value {
74 JsonValue::Number(num) => num
75 .value
76 .parse()
77 .map_err(|err: ParseIntError| Error::validate_err(err.to_string().as_str())),
78 _ => Err(Error::validate_err("expect `JsonValue::Number`")),
79 }
80 }
81 }
82 )*
83 };
84}
85
86from_json_value_for_int!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
87
88macro_rules! from_json_value_for_float {
89 ( $( $i:ident ),* ) => {
90 $(
91 impl FromJsonValue for $i {
92 fn from_json_value(value: &JsonValue) -> Result<Self> {
93 match value {
94 JsonValue::Number(num) => num
95 .value
96 .parse()
97 .map_err(|err: ParseFloatError| Error::validate_err(err.to_string().as_str())),
98 _ => Err(Error::validate_err("expect `JsonValue::Number`")),
99 }
100 }
101 }
102 )*
103 };
104}
105
106from_json_value_for_float!(f32, f64);
107
108impl FromJsonValue for String {
109 fn from_json_value(value: &JsonValue) -> Result<Self> {
110 match value {
111 JsonValue::String(s) => Ok(s.to_string()),
112 _ => Err(Error::validate_err("expect `JsonValue::String`")),
113 }
114 }
115}
116
117impl FromJsonValue for bool {
118 fn from_json_value(value: &JsonValue) -> Result<Self> {
119 match value {
120 JsonValue::Bool(b) => Ok(*b),
121 _ => Err(Error::validate_err("expect `JsonValue::Bool`")),
122 }
123 }
124}
125
126impl<T: FromJsonValue> FromJsonValue for Vec<T> {
127 fn from_json_value(value: &JsonValue) -> Result<Self> {
128 match value {
129 JsonValue::Array(arr) => {
130 let mut buffer = Vec::with_capacity(arr.len());
131 for val in arr.iter() {
132 buffer.push(FromJsonValue::from_json_value(val)?);
133 }
134 Ok(buffer)
135 }
136 _ => Err(Error::validate_err("expect `JsonValue::Array`")),
137 }
138 }
139}
140
141impl<T: FromJsonValue> FromJsonValue for Option<T> {
142 fn from_json_value(value: &JsonValue) -> Result<Self> {
143 match value {
144 JsonValue::Null => Ok(None),
145 _ => Ok(Some(FromJsonValue::from_json_value(value)?)),
146 }
147 }
148}
149
150impl<T: FromJsonValue> FromJsonValue for Box<T> {
151 fn from_json_value(value: &JsonValue) -> Result<Self> {
152 Ok(Box::new(FromJsonValue::from_json_value(value)?))
153 }
154}
155
156pub trait ToJsonValue {
158 fn to_json_value(&self) -> JsonValue;
159}
160
161impl ToJsonValue for () {
162 fn to_json_value(&self) -> JsonValue {
163 JsonValue::Null
164 }
165}
166
167macro_rules! to_json_value_for_num {
168 ( $( $i:ident ),* ) => {
169 $(
170 impl ToJsonValue for $i {
171 fn to_json_value(&self) -> JsonValue {
172 JsonValue::Number(Number::new(self.to_string()))
173 }
174 }
175 )*
176 };
177}
178
179to_json_value_for_num!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64);
180
181impl ToJsonValue for String {
182 fn to_json_value(&self) -> JsonValue {
183 JsonValue::String(self.to_string())
184 }
185}
186
187impl ToJsonValue for bool {
188 fn to_json_value(&self) -> JsonValue {
189 JsonValue::Bool(*self)
190 }
191}
192
193impl<T: ToJsonValue> ToJsonValue for Vec<T> {
194 fn to_json_value(&self) -> JsonValue {
195 JsonValue::Array(
196 self.iter()
197 .map(|val| ToJsonValue::to_json_value(val))
198 .collect(),
199 )
200 }
201}
202
203impl<T: ToJsonValue> ToJsonValue for Option<T> {
204 fn to_json_value(&self) -> JsonValue {
205 match self {
206 None => JsonValue::Null,
207 Some(val) => ToJsonValue::to_json_value(val),
208 }
209 }
210}
211
212impl<T: ToJsonValue> ToJsonValue for Box<T> {
213 fn to_json_value(&self) -> JsonValue {
214 T::to_json_value(self)
215 }
216}