haste_fhir_serialization_json_derive/
lib.rs1mod deserialize;
2mod serde_deserialize;
3mod serde_serialize;
4mod serialize;
5mod utilities;
6
7use proc_macro::TokenStream;
8use syn::{Attribute, DeriveInput, Expr, Lit, Meta, parse_macro_input};
9
10fn get_attribute_serialization_type(attrs: &[Attribute]) -> Option<String> {
12 attrs.iter().find_map(|attr| match &attr.meta {
13 Meta::NameValue(name_value) => {
14 if name_value.path.is_ident("fhir_serialize_type") {
15 match &name_value.value {
16 Expr::Lit(lit) => match &lit.lit {
17 Lit::Str(lit) => Some(lit.value()),
18 _ => panic!("Expected a string literal"),
19 },
20 _ => panic!("Expected a string literal"),
21 }
22 } else {
23 None
24 }
25 }
26 _ => None,
27 })
28}
29
30#[proc_macro_derive(
31 FHIRJSONSerialize,
32 attributes(
33 fhir_serialize_type,
34 rename_field,
35 type_choice_field_name,
37 type_choice_variants,
39 primitive,
40 code,
41 cardinality,
43 reference
44 )
45)]
46pub fn serialize(input: TokenStream) -> TokenStream {
47 let input = parse_macro_input!(input as DeriveInput);
48
49 let serialize_type = get_attribute_serialization_type(&input.attrs);
50
51 let result = match serialize_type.unwrap().as_str() {
52 "primitive" => serialize::primitve_serialization(input),
53 "typechoice" => serialize::typechoice_serialization(input),
54 "complex" => {
55 serialize::complex_serialization(input, serialize::ComplexSerializeType::Complex)
56 }
57 "resource" => {
58 serialize::complex_serialization(input, serialize::ComplexSerializeType::Resource)
59 }
60 "valueset" => serialize::value_set_serialization(input),
61 "enum-variant" => serialize::enum_variant_serialization(input),
62 _ => panic!("Must be one of primitive, typechoice, complex or resource."),
64 };
65
66 result
67}
68
69#[derive(PartialEq)]
70enum DeserializeComplexType {
71 Complex,
72 Resource,
73}
74
75#[proc_macro_derive(
76 FHIRJSONDeserialize,
77 attributes(
78 fhir_serialize_type,
79 rename_field,
80
81 type_choice_field_name,
83
84 type_choice_variants,
86
87 primitive,
88
89 determine_by,
91
92 cardinality,
94 reference
95 )
96)]
97
98pub fn deserialize(input: TokenStream) -> TokenStream {
99 let input = parse_macro_input!(input as DeriveInput);
100
101 let serialize_type = get_attribute_serialization_type(&input.attrs);
102
103 let result = match serialize_type.unwrap().as_str() {
104 "primitive" => deserialize::fhir_primitive_deserialization(input),
105 "typechoice" => deserialize::deserialize_typechoice(input),
106 "resource" => deserialize::deserialize_complex(input, DeserializeComplexType::Resource),
107 "complex" => deserialize::deserialize_complex(input, DeserializeComplexType::Complex),
108 "enum-variant" => deserialize::enum_variant_deserialization(input),
109 "valueset" => deserialize::deserialize_valueset(input),
110 _ => panic!("Must be one of primitive, typechoice, complex or resource."),
111 };
112
113 result.into()
114}
115
116#[proc_macro_derive(
117 FHIRSerdeDeserialize,
118 attributes(
119 fhir_serialize_type,
120 rename_field,
121
122 type_choice_field_name,
124
125 type_choice_variants,
127
128 primitive,
129
130 determine_by,
132
133 cardinality,
135 reference
136 )
137)]
138pub fn serde_deserialize(input: TokenStream) -> TokenStream {
139 let input = parse_macro_input!(input as DeriveInput);
140
141 let serialize_type = get_attribute_serialization_type(&input.attrs);
142
143 let result = match serialize_type.unwrap().as_str() {
144 "primitive" => serde_deserialize::fhir_primitive_deserialization(input),
145 "valueset" => serde_deserialize::valueset_deserialization(input),
146 "typechoice" => serde_deserialize::typechoice_deserialization(input),
147 "complex" => {
148 serde_deserialize::complex_deserialization(input, DeserializeComplexType::Complex)
149 }
150 "resource" => {
151 serde_deserialize::complex_deserialization(input, DeserializeComplexType::Resource)
152 }
153 _ => panic!("Only primitive and valueset supported for serde deserialization."),
154 };
155
156 result.into()
157}
158
159#[proc_macro_derive(
160 FHIRSerdeSerialize,
161 attributes(
162 fhir_serialize_type,
163 rename_field,
164 type_choice_field_name,
166 type_choice_variants,
168 primitive,
169 code,
170 cardinality,
172 reference
173 )
174)]
175pub fn serde_serialize(input: TokenStream) -> TokenStream {
176 let input = parse_macro_input!(input as DeriveInput);
177
178 let serialize_type = get_attribute_serialization_type(&input.attrs);
179
180 let result = match serialize_type.unwrap().as_str() {
181 "primitive" => serde_serialize::fhir_primitive_serialization(input),
182 "valueset" => serde_serialize::valueset_serialization(input),
183 "typechoice" => serde_serialize::typechoice_serialization(input),
184 "complex" => serde_serialize::complex_serialization(input, DeserializeComplexType::Complex),
185 "resource" => {
186 serde_serialize::complex_serialization(input, DeserializeComplexType::Resource)
187 }
188 "enum-variant" => serde_serialize::enum_variant_serialization(input),
189 _ => panic!("Only primitive and valueset supported for serde deserialization."),
190 };
191
192 result.into()
193}