1use serde_json::Number;
2use serde_json::Value;
3use std::borrow::Borrow;
4use std::fmt::Display;
5use std::fmt::Formatter;
6use std::fmt::Result as FmtResult;
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
12pub enum JsonType {
13 Null,
14 String,
15 Float,
16 Integer,
17 Boolean,
18 Array,
19 Object,
20}
21
22impl From<&Value> for JsonType {
23 fn from(value: &Value) -> Self {
24 match value {
25 Value::Null => Self::Null,
26 Value::String(_) => Self::String,
27 Value::Number(number) => number.into(),
28 Value::Bool(_) => Self::Boolean,
29 Value::Array(_) => Self::Array,
30 Value::Object(_) => Self::Object,
31 }
32 }
33}
34
35impl From<&Number> for JsonType {
36 fn from(number: &Number) -> Self {
37 if number.is_f64() {
38 JsonType::Float
39 } else {
40 JsonType::Integer
41 }
42 }
43}
44
45impl Display for JsonType {
46 fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
47 let value_type_str: &str = self.borrow();
48 write!(formatter, "{value_type_str}")
49 }
50}
51
52impl Borrow<str> for JsonType {
53 fn borrow(&self) -> &'static str {
54 match *self {
55 Self::Null => "null",
56 Self::String => "string",
57 Self::Float => "float",
58 Self::Integer => "integer",
59 Self::Boolean => "boolean",
60 Self::Array => "array",
61 Self::Object => "object",
62 }
63 }
64}
65
66#[cfg(test)]
67mod test_from {
68 use super::*;
69 use serde_json::json;
70 use std::f64;
71
72 #[test]
73 fn it_should_convert_json_floats_to_float() {
74 let output = JsonType::from(&json!(0.0));
75 assert_eq!(output, JsonType::Float);
76
77 let output = JsonType::from(&json!(123.456));
78 assert_eq!(output, JsonType::Float);
79
80 let output = JsonType::from(&json!(f64::MAX));
81 assert_eq!(output, JsonType::Float);
82
83 let output = JsonType::from(&json!(f64::MIN));
84 assert_eq!(output, JsonType::Float);
85
86 let output = JsonType::from(&json!(f64::consts::PI));
87 assert_eq!(output, JsonType::Float);
88 }
89
90 #[test]
91 fn it_should_convert_json_ints_to_integer() {
92 let output = JsonType::from(&json!(0));
93 assert_eq!(output, JsonType::Integer);
94
95 let output = JsonType::from(&json!(123));
96 assert_eq!(output, JsonType::Integer);
97
98 let output = JsonType::from(&json!(u64::MAX));
99 assert_eq!(output, JsonType::Integer);
100
101 let output = JsonType::from(&json!(u64::MIN));
102 assert_eq!(output, JsonType::Integer);
103
104 let output = JsonType::from(&json!(i64::MAX));
105 assert_eq!(output, JsonType::Integer);
106
107 let output = JsonType::from(&json!(i64::MIN));
108 assert_eq!(output, JsonType::Integer);
109 }
110
111 #[test]
112 fn it_should_convert_json_null_to_null() {
113 let output = JsonType::from(&json!(null));
114 assert_eq!(output, JsonType::Null);
115 }
116
117 #[test]
118 fn it_should_convert_json_boolean_to_boolean() {
119 let output = JsonType::from(&json!(true));
120 assert_eq!(output, JsonType::Boolean);
121
122 let output = JsonType::from(&json!(false));
123 assert_eq!(output, JsonType::Boolean);
124 }
125
126 #[test]
127 fn it_should_convert_json_string_to_string() {
128 let output = JsonType::from(&json!(""));
129 assert_eq!(output, JsonType::String);
130
131 let output = JsonType::from(&json!("abc123"));
132 assert_eq!(output, JsonType::String);
133 }
134
135 #[test]
136 fn it_should_convert_json_array_to_array() {
137 let output = JsonType::from(&json!([]));
138 assert_eq!(output, JsonType::Array);
139
140 let output = JsonType::from(&json!([0, 123.456, "something"]));
141 assert_eq!(output, JsonType::Array);
142 }
143
144 #[test]
145 fn it_should_convert_json_object_to_object() {
146 let output = JsonType::from(&json!({}));
147 assert_eq!(output, JsonType::Object);
148
149 let output = JsonType::from(&json!({
150 "age": 30,
151 "name": "Joe",
152 "ids": [1, 2, 3],
153 }));
154 assert_eq!(output, JsonType::Object);
155 }
156}
157
158#[cfg(test)]
159mod test_fmt {
160 use super::*;
161
162 #[test]
163 fn it_should_display_null() {
164 let output = format!("{}", JsonType::Null);
165 assert_eq!(output, "null");
166 }
167
168 #[test]
169 fn it_should_display_boolean() {
170 let output = format!("{}", JsonType::Boolean);
171 assert_eq!(output, "boolean");
172 }
173
174 #[test]
175 fn it_should_display_integer_type() {
176 let output = format!("{}", JsonType::Integer);
177 assert_eq!(output, "integer");
178 }
179
180 #[test]
181 fn it_should_display_float_type() {
182 let output = format!("{}", JsonType::Float);
183 assert_eq!(output, "float");
184 }
185
186 #[test]
187 fn it_should_display_string_type() {
188 let output = format!("{}", JsonType::String);
189 assert_eq!(output, "string");
190 }
191
192 #[test]
193 fn it_should_display_array_type() {
194 let output = format!("{}", JsonType::Array);
195 assert_eq!(output, "array");
196 }
197
198 #[test]
199 fn it_should_display_object_type() {
200 let output = format!("{}", JsonType::Object);
201 assert_eq!(output, "object");
202 }
203}