Skip to main content

haste_x_fhir_query/
conversion.rs

1use haste_fhir_model::r4::generated::{
2    terminology::IssueType,
3    types::{
4        FHIRBase64Binary, FHIRBoolean, FHIRCanonical, FHIRDate, FHIRDateTime, FHIRId, FHIRInstant,
5        FHIRInteger, FHIRMarkdown, FHIROid, FHIRPositiveInt, FHIRString, FHIRTime, FHIRUnsignedInt,
6        FHIRUri, FHIRUrl, FHIRUuid,
7    },
8};
9use haste_fhir_operation_error::OperationOutcomeError;
10use haste_reflect::MetaValue;
11
12fn downcast_meta_value<'a, T: 'static>(value: &'a dyn MetaValue) -> Option<&'a T> {
13    value.as_any().downcast_ref::<T>()
14}
15
16pub fn stringify_meta_value(value: &dyn MetaValue) -> Result<String, OperationOutcomeError> {
17    match value.fhir_type() {
18        "http://hl7.org/fhirpath/System.String" => downcast_meta_value::<String>(value)
19            .map(|s| s.to_string())
20            .ok_or_else(|| {
21                OperationOutcomeError::fatal(
22                    IssueType::Invalid(None),
23                    "http://hl7.org/fhirpath/System.String value is missing.".to_string(),
24                )
25            }),
26        "base64Binary" => downcast_meta_value::<FHIRBase64Binary>(value)
27            .and_then(|s| s.value.as_ref())
28            .map(|s| s.to_string())
29            .ok_or_else(|| {
30                OperationOutcomeError::fatal(
31                    IssueType::Invalid(None),
32                    "base64Binary value is missing.".to_string(),
33                )
34            }),
35        "decimal" => {
36            downcast_meta_value::<haste_fhir_model::r4::generated::types::FHIRDecimal>(value)
37                .and_then(|d| d.value.as_ref())
38                .map(|s| s.to_string())
39                .ok_or_else(|| {
40                    OperationOutcomeError::fatal(
41                        IssueType::Invalid(None),
42                        "decimal value is missing.".to_string(),
43                    )
44                })
45        }
46
47        "boolean" => downcast_meta_value::<FHIRBoolean>(value)
48            .and_then(|b| b.value)
49            .map(|b| b.to_string())
50            .ok_or_else(|| {
51                OperationOutcomeError::fatal(
52                    IssueType::Invalid(None),
53                    "boolean value is missing.".to_string(),
54                )
55            }),
56
57        "url" => downcast_meta_value::<FHIRUrl>(value)
58            .and_then(|u| u.value.as_ref())
59            .map(|s| s.to_string())
60            .ok_or_else(|| {
61                OperationOutcomeError::fatal(
62                    IssueType::Invalid(None),
63                    "url value is missing.".to_string(),
64                )
65            }),
66
67        "code" => downcast_meta_value::<haste_fhir_model::r4::generated::types::FHIRCode>(value)
68            .and_then(|c| c.value.as_ref())
69            .map(|s| s.to_string())
70            .ok_or_else(|| {
71                OperationOutcomeError::fatal(
72                    IssueType::Invalid(None),
73                    "code value is missing.".to_string(),
74                )
75            }),
76
77        "string" => downcast_meta_value::<FHIRString>(value)
78            .and_then(|s| s.value.as_ref())
79            .map(|s| s.to_string())
80            .ok_or_else(|| {
81                OperationOutcomeError::fatal(
82                    IssueType::Invalid(None),
83                    "string value is missing.".to_string(),
84                )
85            }),
86
87        "integer" => downcast_meta_value::<FHIRInteger>(value)
88            .and_then(|i| i.value)
89            .map(|i| i.to_string())
90            .ok_or_else(|| {
91                OperationOutcomeError::fatal(
92                    IssueType::Invalid(None),
93                    "integer value is missing.".to_string(),
94                )
95            }),
96
97        "uri" => downcast_meta_value::<FHIRUri>(value)
98            .and_then(|u| u.value.as_ref())
99            .map(|s| s.to_string())
100            .ok_or_else(|| {
101                OperationOutcomeError::fatal(
102                    IssueType::Invalid(None),
103                    "uri value is missing.".to_string(),
104                )
105            }),
106
107        "canonical" => downcast_meta_value::<FHIRCanonical>(value)
108            .and_then(|c| c.value.as_ref())
109            .map(|s| s.to_string())
110            .ok_or_else(|| {
111                OperationOutcomeError::fatal(
112                    IssueType::Invalid(None),
113                    "canonical value is missing.".to_string(),
114                )
115            }),
116
117        "markdown" => downcast_meta_value::<FHIRMarkdown>(value)
118            .and_then(|m| m.value.as_ref())
119            .map(|s| s.to_string())
120            .ok_or_else(|| {
121                OperationOutcomeError::fatal(
122                    IssueType::Invalid(None),
123                    "markdown value is missing.".to_string(),
124                )
125            }),
126
127        "id" => downcast_meta_value::<FHIRId>(value)
128            .and_then(|id| id.value.as_ref())
129            .map(|s| s.to_string())
130            .ok_or_else(|| {
131                OperationOutcomeError::fatal(
132                    IssueType::Invalid(None),
133                    "id value is missing.".to_string(),
134                )
135            }),
136
137        "oid" => downcast_meta_value::<FHIROid>(value)
138            .and_then(|o| o.value.as_ref())
139            .map(|s| s.to_string())
140            .ok_or_else(|| {
141                OperationOutcomeError::fatal(
142                    IssueType::Invalid(None),
143                    "oid value is missing.".to_string(),
144                )
145            }),
146
147        "uuid" => downcast_meta_value::<FHIRUuid>(value)
148            .and_then(|u| u.value.as_ref())
149            .map(|s| s.to_string())
150            .ok_or_else(|| {
151                OperationOutcomeError::fatal(
152                    IssueType::Invalid(None),
153                    "uuid value is missing.".to_string(),
154                )
155            }),
156
157        "unsignedInt" => downcast_meta_value::<FHIRUnsignedInt>(value)
158            .and_then(|i| i.value)
159            .map(|i| i.to_string())
160            .ok_or_else(|| {
161                OperationOutcomeError::fatal(
162                    IssueType::Invalid(None),
163                    "unsignedInt value is missing.".to_string(),
164                )
165            }),
166        "positiveInt" => downcast_meta_value::<FHIRPositiveInt>(value)
167            .and_then(|i| i.value)
168            .map(|i| i.to_string())
169            .ok_or_else(|| {
170                OperationOutcomeError::fatal(
171                    IssueType::Invalid(None),
172                    "positiveInt value is missing.".to_string(),
173                )
174            }),
175
176        "instant" => downcast_meta_value::<FHIRInstant>(value)
177            .and_then(|dt| dt.value.as_ref())
178            .map(|s| s.to_string())
179            .ok_or_else(|| {
180                OperationOutcomeError::fatal(
181                    IssueType::Invalid(None),
182                    "instant value is missing.".to_string(),
183                )
184            }),
185        "date" => downcast_meta_value::<FHIRDate>(value)
186            .and_then(|dt| dt.value.as_ref())
187            .map(|s| s.to_string())
188            .ok_or_else(|| {
189                OperationOutcomeError::fatal(
190                    IssueType::Invalid(None),
191                    "date value is missing.".to_string(),
192                )
193            }),
194        "time" => downcast_meta_value::<FHIRTime>(value)
195            .and_then(|t| t.value.as_ref())
196            .map(|s| s.to_string())
197            .ok_or_else(|| {
198                OperationOutcomeError::fatal(
199                    IssueType::Invalid(None),
200                    "time value is missing.".to_string(),
201                )
202            }),
203        "dateTime" => downcast_meta_value::<FHIRDateTime>(value)
204            .and_then(|dt| dt.value.as_ref())
205            .map(|s| s.to_string())
206            .ok_or_else(|| {
207                OperationOutcomeError::fatal(
208                    IssueType::Invalid(None),
209                    "dateTime value is missing.".to_string(),
210                )
211            }),
212
213        typename => Err(OperationOutcomeError::fatal(
214            IssueType::Invalid(None),
215            format!(
216                "Unsupported MetaValue type for stringification: '{}'",
217                typename
218            ),
219        )),
220    }
221}