haste_fhir_serialization_json/
deserialize_primitives.rs

1use crate::errors::DeserializeError;
2use crate::traits::{Context, FHIRJSONDeserializer};
3use serde_json::Value;
4
5fn get_value<'a>(value: &'a Value, context: &Context) -> Option<&'a Value> {
6    match context {
7        Context::AsValue => Some(value),
8        Context::AsField(field_context) => value.get(field_context.field),
9    }
10}
11
12impl FHIRJSONDeserializer for i64 {
13    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
14        let json_value: Value = serde_json::from_str(s)?;
15        i64::from_serde_value(&json_value, Context::AsValue)
16    }
17    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
18        let k = get_value(value, &context).and_then(|v| v.as_i64());
19        k.ok_or_else(|| DeserializeError::FailedToConvertType("i64".to_string()))
20    }
21}
22
23impl FHIRJSONDeserializer for u64 {
24    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
25        let json_value: Value = serde_json::from_str(s)?;
26        u64::from_serde_value(&json_value, Context::AsValue)
27    }
28    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
29        let k = get_value(value, &context).and_then(|v| v.as_u64());
30        k.ok_or_else(|| DeserializeError::FailedToConvertType("u64".to_string()))
31    }
32}
33
34impl FHIRJSONDeserializer for f64 {
35    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
36        let json_value: Value = serde_json::from_str(s)?;
37        f64::from_serde_value(&json_value, Context::AsValue)
38    }
39    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
40        let k = get_value(value, &context).and_then(|v| v.as_f64());
41        k.ok_or_else(|| DeserializeError::FailedToConvertType("f64".to_string()))
42    }
43}
44
45impl FHIRJSONDeserializer for bool {
46    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
47        let json_value: Value = serde_json::from_str(s)?;
48        bool::from_serde_value(&json_value, Context::AsValue)
49    }
50    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
51        let k = get_value(value, &context).and_then(|v| v.as_bool());
52        k.ok_or_else(|| DeserializeError::FailedToConvertType("bool".to_string()))
53    }
54}
55
56impl FHIRJSONDeserializer for String {
57    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
58        let json_value: Value = serde_json::from_str(s)?;
59        String::from_serde_value(&json_value, Context::AsValue)
60    }
61    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
62        let k = get_value(value, &context)
63            .and_then(|v| v.as_str())
64            .and_then(|s| Some(s.to_string()));
65        k.ok_or_else(|| DeserializeError::FailedToConvertType("String".to_string()))
66    }
67}
68
69impl<T> FHIRJSONDeserializer for Vec<T>
70where
71    T: FHIRJSONDeserializer,
72{
73    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
74        let json_value: Value = serde_json::from_str(s)?;
75        Vec::<T>::from_serde_value(&json_value, Context::AsValue)
76    }
77    fn from_serde_value(v: &Value, context: Context) -> Result<Self, DeserializeError> {
78        match &context {
79            Context::AsValue => {
80                if let Some(json_array) = v.as_array() {
81                    json_array
82                        .iter()
83                        .map(|item| T::from_serde_value(item, Context::AsValue))
84                        .collect()
85                } else {
86                    Err(DeserializeError::InvalidType(
87                        "Expected an array".to_string(),
88                    ))
89                }
90            }
91            Context::AsField(field_context) => {
92                if !field_context.is_primitive {
93                    if let Some(json) = v.get(field_context.field)
94                        && let Some(json_array) = json.as_array()
95                    {
96                        json_array
97                            .iter()
98                            .map(|item| T::from_serde_value(item, Context::AsValue))
99                            .collect()
100                    } else {
101                        Err(DeserializeError::InvalidType(
102                            "Expected an array".to_string(),
103                        ))
104                    }
105                }
106                // Special handling because array primitives live in two locations _<field> for element fields and <field> for values.
107                else {
108                    let mut return_v = vec![];
109                    let values = {
110                        if let Some(v) = v.get(field_context.field) {
111                            if let Some(array) = v.as_array() {
112                                Ok(Some(array))
113                            } else {
114                                Err(DeserializeError::InvalidType(
115                                    "Expected an array".to_string(),
116                                ))
117                            }
118                        } else {
119                            Ok(None)
120                        }
121                    }?;
122                    let elements = {
123                        if let Some(v) = v.get(&format!("_{}", field_context.field)) {
124                            if let Some(array) = v.as_array() {
125                                Ok(Some(array))
126                            } else {
127                                Err(DeserializeError::InvalidType(
128                                    "Expected an array".to_string(),
129                                ))
130                            }
131                        } else {
132                            Ok(None)
133                        }
134                    }?;
135
136                    let length = std::cmp::max(
137                        values.map(|v| v.len()).unwrap_or(0),
138                        elements.map(|v| v.len()).unwrap_or(0),
139                    );
140
141                    for i in 0..length {
142                        let mut json_v = serde_json::map::Map::new();
143                        let value = values.and_then(|v| v.get(i));
144                        let element = elements.and_then(|v| v.get(i));
145                        if let Some(value) = value {
146                            json_v.insert("fake_v".to_string(), value.clone());
147                        }
148                        if let Some(element) = element {
149                            json_v.insert("_fake_v".to_string(), element.clone());
150                        }
151                        let res =
152                            T::from_serde_value(&Value::Object(json_v), ("fake_v", true).into())?;
153                        return_v.push(res);
154                    }
155
156                    Ok(return_v)
157                }
158            }
159        }
160    }
161}
162
163impl<T> FHIRJSONDeserializer for Option<T>
164where
165    T: FHIRJSONDeserializer,
166{
167    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
168        let json_value: Value = serde_json::from_str(s)?;
169        Option::<T>::from_serde_value(&json_value, Context::AsValue)
170    }
171
172    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
173        match &context {
174            Context::AsField(field_context) => match value.get(field_context.field) {
175                Some(_v) => T::from_serde_value(value, context).map(|res| Some(res)),
176                None => Ok(None),
177            },
178            Context::AsValue => {
179                if value.is_null() {
180                    Ok(None)
181                } else {
182                    T::from_serde_value(value, context).map(|res| Some(res))
183                }
184            }
185        }
186    }
187}
188
189impl<T> FHIRJSONDeserializer for Box<T>
190where
191    T: FHIRJSONDeserializer,
192{
193    fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
194        let json_value: Value = serde_json::from_str(s)?;
195        Box::<T>::from_serde_value(&json_value, Context::AsValue)
196    }
197    fn from_serde_value(value: &Value, context: Context) -> Result<Self, DeserializeError> {
198        T::from_serde_value(value, context).map(|res| Box::new(res))
199    }
200}