expect_json/
json_type.rs

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/// A helper enum to represent the many types contained in Json.
9///
10/// This can be built from looking at Json Values.
11#[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}