1use alloc::string::{String, ToString};
10use alloc::vec::Vec;
11
12use crate::number::JsonNumber;
13use crate::value::JsonValue;
14use crate::write::{to_compact_string, to_compact_vec};
15
16pub trait JsonEncode {
22 fn to_json_value(&self) -> JsonValue;
24}
25
26pub fn to_json_string<T: JsonEncode + ?Sized>(value: &T) -> String {
28 to_compact_string(&value.to_json_value())
29}
30
31pub fn to_json_vec<T: JsonEncode + ?Sized>(value: &T) -> Vec<u8> {
33 to_compact_vec(&value.to_json_value())
34}
35
36macro_rules! impl_int {
37 ($($t:ty),* $(,)?) => {$(
38 impl JsonEncode for $t {
39 fn to_json_value(&self) -> JsonValue {
40 JsonValue::Number(JsonNumber::from_validated(self.to_string()))
42 }
43 }
44 )*};
45}
46impl_int!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
47
48impl JsonEncode for bool {
49 fn to_json_value(&self) -> JsonValue {
50 JsonValue::Bool(*self)
51 }
52}
53
54impl JsonEncode for str {
55 fn to_json_value(&self) -> JsonValue {
56 JsonValue::String(self.into())
57 }
58}
59
60impl JsonEncode for String {
61 fn to_json_value(&self) -> JsonValue {
62 JsonValue::String(self.clone())
63 }
64}
65
66impl<T: JsonEncode> JsonEncode for Option<T> {
67 fn to_json_value(&self) -> JsonValue {
68 match self {
69 Some(value) => value.to_json_value(),
70 None => JsonValue::Null,
71 }
72 }
73}
74
75impl<T: JsonEncode> JsonEncode for Vec<T> {
76 fn to_json_value(&self) -> JsonValue {
77 JsonValue::Array(self.iter().map(JsonEncode::to_json_value).collect())
78 }
79}
80
81impl<T: JsonEncode> JsonEncode for [T] {
82 fn to_json_value(&self) -> JsonValue {
83 JsonValue::Array(self.iter().map(JsonEncode::to_json_value).collect())
84 }
85}
86
87impl<T: JsonEncode + ?Sized> JsonEncode for &T {
88 fn to_json_value(&self) -> JsonValue {
89 (**self).to_json_value()
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use crate::value::JsonObject;
97
98 #[test]
99 fn scalars_encode_to_exact_text() {
100 assert_eq!(to_json_string(&255u8), "255");
101 assert_eq!(to_json_string(&(-5i32)), "-5");
102 assert_eq!(
103 to_json_string(&u128::MAX),
104 "340282366920938463463374607431768211455"
105 );
106 assert_eq!(to_json_string(&true), "true");
107 assert_eq!(to_json_string(&false), "false");
108 assert_eq!(to_json_string("hi"), "\"hi\"");
109 assert_eq!(to_json_string(&String::from("hi")), "\"hi\"");
110 }
111
112 #[test]
113 fn option_encodes_none_as_null() {
114 assert_eq!(to_json_string(&Option::<u8>::None), "null");
115 assert_eq!(to_json_string(&Some(7u8)), "7");
116 }
117
118 #[test]
119 fn sequences_encode_to_arrays() {
120 assert_eq!(to_json_string(&vec![1u8, 2, 3]), "[1,2,3]");
121 assert_eq!(to_json_string(&Vec::<u8>::new()), "[]");
122 let slice: &[u8] = &[9, 8];
123 assert_eq!(to_json_string(slice), "[9,8]");
124 }
125
126 #[test]
127 fn object_member_order_is_preserved() {
128 let mut obj = JsonObject::new();
131 obj.insert("b".into(), 2u8.to_json_value());
132 obj.insert("a".into(), 1u8.to_json_value());
133 assert_eq!(
134 to_compact_string(&JsonValue::Object(obj)),
135 r#"{"b":2,"a":1}"#
136 );
137 }
138
139 #[test]
140 fn array_constructor_and_reference_forwarding() {
141 let array = JsonValue::array([1u8.to_json_value(), 2u8.to_json_value()]);
142 assert_eq!(to_compact_string(&array), "[1,2]");
143
144 let n = 5u8;
146 assert_eq!(to_json_string(&&n), "5");
147 }
148}