Skip to main content

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::{
23    de::Error as RUMDeJsonError,
24    de::Visitor as RUMDeJsonVisitor,
25    ser::Error as RUMSerJsonError,
26    ser::SerializeMap as RUMSerJsonSerializeMap,
27    ser::SerializeSeq as RUMSerJsonSerializeSequence,
28    ser::SerializeStruct as RUMSerJsonSerializeStruct,
29    Deserialize as RUMDeJson,
30    Deserializer as RUMJsonDeserializer,
31    Serialize as RUMSerJson,
32    Serializer as RUMJsonSerializer,
33};
34use serde_json::{from_str, to_string};
35
36#[inline(always)]
37pub fn from_json<T>(input: &str) -> RUMResult<T>
38where
39    T: for<'a> RUMDeJson<'a>,
40{
41    match from_str(input) {
42        Ok(value) => Ok(value),
43        Err(e) => Err(rumtk_format!(
44            "Failed to deserialize object because of {}",
45            e
46        )),
47    }
48}
49
50#[inline(always)]
51pub fn to_json<T>(input: &T) -> RUMResult<RUMString>
52where
53    T: RUMSerJson,
54{
55    match to_string(input) {
56        Ok(value) => Ok(value),
57        Err(e) => Err(rumtk_format!("Failed to serialize object because of {}", e)),
58    }
59}
60
61///
62/// Serialization macro which will take an object instance decorated with [Serialize] trait
63/// from serde and return the JSON string representation.
64///
65/// You can pass up to two parameters. The first parameter is the serializable object instance.
66/// The second parameter is a boolean indicating whether to pretty print. Omit the second
67/// parameter if not debugging to save on bytes transferred around.
68///
69/// # Examples
70///
71/// ## Default
72/// ```
73/// use rumtk_core::serde::json::{RUMSerJson};
74/// use rumtk_core::strings::RUMString;
75/// use rumtk_core::rumtk_serialize;
76///
77/// #[derive(RUMSerJson)]
78/// struct MyStruct {
79///     hello: RUMString
80/// }
81///
82/// let hw = MyStruct{hello: RUMString::from("World")};
83/// let hw_str = rumtk_serialize!(&hw).unwrap();
84///
85/// assert!(hw_str.len() > 0, "Empty JSON string generated from the test struct!");
86///
87/// ```
88///
89#[macro_export]
90macro_rules! rumtk_serialize {
91    ( $object:expr ) => {{
92        use $crate::serde::json::to_json;
93
94        to_json($object)
95    }};
96}
97
98///
99/// Deserialization macro which will take a JSON string representation and return an instance
100/// of the specified type.
101///
102/// Pass the json string to deserialize. You will need to specify the expected type that will
103/// be generated.
104///
105/// # Example
106///
107/// ```
108/// use rumtk_core::serde::json::{RUMSerJson, RUMDeJson};
109/// use rumtk_core::strings::RUMString;
110/// use rumtk_core::{rumtk_serialize, rumtk_deserialize};
111///
112/// #[derive(RUMSerJson, RUMDeJson, PartialEq)]
113/// struct MyStruct {
114///     hello: RUMString
115/// }
116///
117/// let hw = MyStruct{hello: RUMString::from("World")};
118/// let hw_str = rumtk_serialize!(&hw).unwrap();
119/// let new_hw: MyStruct = rumtk_deserialize!(&hw_str).unwrap();
120///
121/// assert!(
122///    new_hw == hw,
123///    "Deserialized JSON does not match the expected value!"
124/// );
125///
126/// ```
127///
128#[macro_export]
129macro_rules! rumtk_deserialize {
130    ( $string:expr ) => {{
131        use $crate::serde::json::from_json;
132
133        from_json($string)
134    }};
135}