Skip to main content

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