rumtk_core/serde/json.rs
1/*
2 * rumtk attempts to implement HL7 and medical protocols for interoperability in medicine.
3 * This toolkit aims to be reliable, simple, performant, and standards compliant.
4 * Copyright (C) 2026 Luis M. Santos, M.D. <lsantos@medicalmasses.com>
5 * Copyright (C) 2026 MedicalMasses L.L.C. <contact@medicalmasses.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20use crate::base::RUMResult;
21use crate::strings::{rumtk_format, RUMString};
22pub use serde::{Deserialize as RUMDeJson, Deserializer as RUMJsonDeserializer, Serialize as RUMSerJson, Serializer as RUMJsonSerializer};
23use serde_json::{from_str, to_string};
24
25#[inline(always)]
26 pub fn from_json<T>(input: &str) -> RUMResult<T>
27 where
28 T: for<'a> RUMDeJson<'a>
29 {
30 match from_str(input) {
31 Ok(value) => Ok(value),
32 Err(e) => Err(rumtk_format!("Failed to deserialize object because of {}", e))
33 }
34 }
35
36 #[inline(always)]
37 pub fn to_json<T>(input: &T) -> RUMResult<RUMString>
38 where
39 T: RUMSerJson
40 {
41 match to_string(input) {
42 Ok(value) => Ok(value),
43 Err(e) => Err(rumtk_format!("Failed to serialize object because of {}", e))
44 }
45 }
46
47 ///
48 /// Serialization macro which will take an object instance decorated with [Serialize] trait
49 /// from serde and return the JSON string representation.
50 ///
51 /// You can pass up to two parameters. The first parameter is the serializable object instance.
52 /// The second parameter is a boolean indicating whether to pretty print. Omit the second
53 /// parameter if not debugging to save on bytes transferred around.
54 ///
55 /// # Examples
56 ///
57 /// ## Default
58 /// ```
59 /// use rumtk_core::serde::json::{RUMSerJson};
60 /// use rumtk_core::strings::RUMString;
61 /// use rumtk_core::rumtk_serialize;
62 ///
63 /// #[derive(RUMSerJson)]
64 /// struct MyStruct {
65 /// hello: RUMString
66 /// }
67 ///
68 /// let hw = MyStruct{hello: RUMString::from("World")};
69 /// let hw_str = rumtk_serialize!(&hw).unwrap();
70 ///
71 /// assert!(hw_str.len() > 0, "Empty JSON string generated from the test struct!");
72 ///
73 /// ```
74 ///
75 #[macro_export]
76 macro_rules! rumtk_serialize {
77 ( $object:expr ) => {{
78 use $crate::serde::json::{to_json};
79
80 to_json($object)
81 }};
82 }
83
84 ///
85 /// Deserialization macro which will take a JSON string representation and return an instance
86 /// of the specified type.
87 ///
88 /// Pass the json string to deserialize. You will need to specify the expected type that will
89 /// be generated.
90 ///
91 /// # Example
92 ///
93 /// ```
94 /// use rumtk_core::serde::json::{RUMSerJson, RUMDeJson};
95 /// use rumtk_core::strings::RUMString;
96 /// use rumtk_core::{rumtk_serialize, rumtk_deserialize};
97 ///
98 /// #[derive(RUMSerJson, RUMDeJson, PartialEq)]
99 /// struct MyStruct {
100 /// hello: RUMString
101 /// }
102 ///
103 /// let hw = MyStruct{hello: RUMString::from("World")};
104 /// let hw_str = rumtk_serialize!(&hw).unwrap();
105 /// let new_hw: MyStruct = rumtk_deserialize!(&hw_str).unwrap();
106 ///
107 /// assert!(
108 /// new_hw == hw,
109 /// "Deserialized JSON does not match the expected value!"
110 /// );
111 ///
112 /// ```
113 ///
114 #[macro_export]
115 macro_rules! rumtk_deserialize {
116 ( $string:expr ) => {{
117 use $crate::serde::json::from_json;
118
119 from_json($string)
120 }};
121 }