1use std::ops::{Deref, DerefMut};
2
3use serde::de::{DeserializeOwned, Error as DeError};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug)]
34pub struct JsonResult<T, E>(pub Result<T, E>);
35
36impl<T, E> Serialize for JsonResult<T, E>
37where
38 T: Serialize,
39 E: Serialize,
40{
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where
43 S: serde::Serializer,
44 {
45 match &self.0 {
46 Ok(v) => v.serialize(serializer),
47 Err(e) => e.serialize(serializer),
48 }
49 }
50}
51
52impl<'de, T, E> Deserialize<'de> for JsonResult<T, E>
53where
54 T: DeserializeOwned,
55 E: DeserializeOwned,
56{
57 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
58 where
59 D: serde::Deserializer<'de>,
60 {
61 let value = serde_json::Value::deserialize(deserializer)?;
63
64 let try_t: Result<T, _> = serde_json::from_value(value.clone());
65 let try_e: Result<E, _> = serde_json::from_value(value.clone());
66
67 match (try_t, try_e) {
68 (Ok(v), _) => Ok(JsonResult(Ok(v))),
69 (_, Ok(e)) => Ok(JsonResult(Err(e))),
70 (Err(t_err), Err(e_err)) => {
71 let t_name = std::any::type_name::<T>();
72 let e_name = std::any::type_name::<E>();
73
74 let msg = format!(
75 "Failed to parse as {}: {}\nFailed to parse as {}: {}",
76 t_name, t_err, e_name, e_err
77 );
78
79 Err(DeError::custom(msg))
80 }
81 }
82 }
83}
84
85impl<T, E> From<JsonResult<T, E>> for serde_json::Value
86where
87 T: Serialize,
88 E: Serialize,
89{
90 fn from(value: JsonResult<T, E>) -> Self {
91 match value.0 {
92 Ok(v) => serde_json::json!(v),
93 Err(e) => serde_json::json!(e),
94 }
95 }
96}
97
98impl<T, E> Deref for JsonResult<T, E> {
100 type Target = Result<T, E>;
101
102 fn deref(&self) -> &Self::Target {
103 &self.0
104 }
105}
106
107impl<T, E> DerefMut for JsonResult<T, E> {
108 fn deref_mut(&mut self) -> &mut Self::Target {
109 &mut self.0
110 }
111}
112
113impl<T, E> From<Result<T, E>> for JsonResult<T, E> {
114 fn from(r: Result<T, E>) -> Self {
115 JsonResult(r)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use std::ops::DerefMut;
122
123 use super::JsonResult;
124 use serde::{Deserialize, Serialize};
125
126 #[derive(Debug, Serialize, Deserialize, PartialEq)]
127 struct GoodT {
128 v: u32,
129 }
130
131 #[derive(Debug, Serialize, Deserialize, PartialEq)]
132 struct BadE {
133 msg: String,
134 }
135
136 #[test]
137 fn test_ok_serialization() {
138 let jr = JsonResult::<i32, String>(Ok(100));
139 let s = serde_json::to_string(&jr).unwrap();
140 assert_eq!(s, "100");
141 }
142
143 #[test]
144 fn test_err_serialization() {
145 let jr = JsonResult::<i32, &str>(Err("boom"));
146 let s = serde_json::to_string(&jr).unwrap();
147 assert_eq!(s, "\"boom\"");
148 }
149
150 #[test]
151 fn test_deserialize_ok() {
152 let json = "42";
153 let jr: JsonResult<i32, String> = serde_json::from_str(json).unwrap();
154 assert_eq!(jr.0, Ok(42));
155 }
156
157 #[test]
158 fn test_deserialize_err() {
159 let json = "\"error occurred\"";
160 let jr: JsonResult<i32, String> = serde_json::from_str(json).unwrap();
161 assert_eq!(jr.0, Err("error occurred".to_string()));
162 }
163
164 #[test]
165 fn test_struct_ok_case() {
166 let json = serde_json::json!({ "v": 123 });
167 let jr: JsonResult<GoodT, BadE> = serde_json::from_value(json).unwrap();
168
169 assert_eq!(jr.0, Ok(GoodT { v: 123 }));
170 }
171
172 #[test]
173 fn test_struct_err_case() {
174 let json = serde_json::json!({ "msg": "fail" });
175 let jr: JsonResult<GoodT, BadE> = serde_json::from_value(json).unwrap();
176
177 assert_eq!(jr.0, Err(BadE { msg: "fail".into() }));
178 }
179
180 #[test]
181 fn test_round_trip_ok() {
182 let original = JsonResult::<GoodT, BadE>(Ok(GoodT { v: 55 }));
183 let json = serde_json::to_value(&original).unwrap();
184 let parsed: JsonResult<GoodT, BadE> = serde_json::from_value(json).unwrap();
185
186 assert_eq!(parsed.0, Ok(GoodT { v: 55 }));
187 }
188
189 #[test]
190 fn test_round_trip_err() {
191 let original = JsonResult::<GoodT, BadE>(Err(BadE { msg: "x".into() }));
192 let json = serde_json::to_value(&original).unwrap();
193 let parsed: JsonResult<GoodT, BadE> = serde_json::from_value(json).unwrap();
194
195 assert_eq!(parsed.0, Err(BadE { msg: "x".into() }));
196 }
197
198 #[test]
199 fn test_invalid_json_fails() {
200 let json = serde_json::json!([1, 2, 3]); let result = serde_json::from_value::<JsonResult<GoodT, BadE>>(json);
202 assert!(result.is_err());
203 }
204
205 #[test]
206 fn test_error_message_contains_type_names() {
207 #[derive(Debug, Serialize, Deserialize)]
208 struct Complex {
209 a: String,
210 }
211
212 let json = serde_json::json!(12345);
213
214 let result = serde_json::from_value::<JsonResult<Complex, Complex>>(json);
215 assert!(result.is_err());
216
217 let msg = result.unwrap_err().to_string();
218 assert!(msg.contains("Complex"));
219 assert!(msg.contains("Failed to parse"));
220 }
221
222 #[test]
223 fn test_ambiguous_matches_t_first() {
224 #[derive(Debug, Serialize, Deserialize, PartialEq)]
225 struct Amb {
226 x: u32,
227 }
228
229 let json = serde_json::json!({ "x": 10 });
230
231 let jr: JsonResult<Amb, Amb> = serde_json::from_value(json).unwrap();
232
233 assert_eq!(jr.0, Ok(Amb { x: 10 }));
235 }
236
237 #[test]
238 fn test_null_fails() {
239 let json = serde_json::json!(null);
240 let result = serde_json::from_value::<JsonResult<GoodT, BadE>>(json);
241 assert!(result.is_err());
242 }
243
244 #[test]
245 fn test_value_into_serde_value_ok() {
246 let jr = JsonResult::<i32, &str>(Ok(7));
247 let v: serde_json::Value = jr.into();
248 assert_eq!(v, serde_json::json!(7));
249 }
250
251 #[test]
252 fn test_value_into_serde_value_err() {
253 let jr = JsonResult::<i32, &str>(Err("oops"));
254 let v: serde_json::Value = jr.into();
255 assert_eq!(v, serde_json::json!("oops"));
256 }
257
258 #[test]
259 fn deref_allows_calling_result_methods() {
260 let jr = JsonResult::<u32, &'static str>(Ok(42));
261
262 assert!(jr.is_ok());
264 assert_eq!(jr.as_ref().unwrap(), &42);
265 }
266
267 #[test]
268 fn deref_works_with_pattern_matching() {
269 let jr = JsonResult::<u32, &'static str>(Ok(7));
270
271 match *jr {
273 Ok(v) => assert_eq!(v, 7),
274 Err(_) => panic!("Expected Ok"),
275 }
276 }
277
278 #[test]
279 fn deref_mut_allows_modifying_result() {
280 let mut jr = JsonResult::<u32, &'static str>(Ok(10));
281
282 if let Ok(v) = jr.deref_mut() {
284 *v = 99;
285 }
286
287 assert_eq!(jr.unwrap(), 99);
288 }
289
290 #[test]
291 fn deref_mut_replaces_result() {
292 let mut jr = JsonResult::<u32, &'static str>(Ok(1));
293
294 *jr = Err("failed");
296
297 assert!(jr.is_err());
298 assert_eq!(jr.unwrap_err(), "failed");
299 }
300
301 #[test]
302 fn can_be_used_like_result_in_functions() {
303 fn take_result(r: &Result<u32, &'static str>) -> u32 {
304 *r.as_ref().unwrap()
305 }
306
307 let jr = JsonResult(Ok(55));
308
309 assert_eq!(take_result(&jr), 55);
311 }
312
313 #[derive(Debug, PartialEq)]
314 struct OKData(i32);
315
316 #[derive(Debug, PartialEq)]
317 struct ErrData(&'static str);
318
319 #[test]
320 fn from_result_ok() {
321 let r: Result<OKData, ErrData> = Ok(OKData(99));
322
323 let jr: JsonResult<OKData, ErrData> = r.into();
324
325 assert!(jr.0.is_ok());
326 assert_eq!(jr.0.unwrap(), OKData(99));
327 }
328
329 #[test]
330 fn from_result_err() {
331 let r: Result<OKData, ErrData> = Err(ErrData("error"));
332
333 let jr: JsonResult<OKData, ErrData> = r.into();
334
335 assert!(jr.0.is_err());
336 assert_eq!(jr.0.unwrap_err(), ErrData("error"));
337 }
338
339 #[test]
340 fn from_result_type_inference_ok() {
341 let r = Ok::<i32, &str>(123);
342 let jr: JsonResult<i32, &str> = r.into();
343
344 assert_eq!(jr.0.unwrap(), 123);
345 }
346
347 #[test]
348 fn from_result_type_inference_err() {
349 let r = Err::<i32, &str>("bad");
350 let jr: JsonResult<i32, &str> = r.into();
351
352 assert_eq!(jr.0.unwrap_err(), "bad");
353 }
354
355 #[test]
356 fn from_result_does_not_clone() {
357 let msg = String::from("boom");
360 let ptr = msg.as_ptr();
361
362 let r: Result<(), String> = Err(msg);
363 let jr: JsonResult<(), String> = r.into();
364
365 let inner = jr.0.unwrap_err();
366 assert_eq!(inner.as_ptr(), ptr); }
368
369 #[test]
370 fn from_result_owned_types() {
371 let r: Result<String, String> = Ok("hello".to_string());
372 let jr: JsonResult<String, String> = r.into();
373 assert_eq!(jr.0.unwrap(), "hello");
374 }
375
376 #[test]
377 fn from_result_reference_error() {
378 let r: Result<i32, &str> = Err("fail");
379 let jr: JsonResult<i32, &str> = r.into();
380 assert_eq!(jr.0.unwrap_err(), "fail");
381 }
382}