1use haste_fhir_model::r4::generated::resources::{
2 HL7V2, HL7V2Segments, HL7V2SegmentsFields, HL7V2SegmentsFieldsValue,
3 HL7V2SegmentsFieldsValueValue,
4};
5
6pub struct EncodingInformation {
7 pub field_separator: String,
8 pub component_separator: String,
9 pub repetition_separator: String,
10 #[allow(dead_code)]
11 pub escape_character: String,
12 pub subcomponent_separator: String,
13}
14
15pub fn component_to_string(
18 encoding_characters: &EncodingInformation,
19 component: &HL7V2SegmentsFieldsValueValue,
20) -> Option<String> {
21 if let Some(subcomponents) = &component.subcomponents {
22 let value = subcomponents
23 .into_iter()
24 .map(|s| &s.value)
25 .map(|v| {
26 if let Some(s) = v {
27 s.clone()
28 } else {
29 "".to_string()
30 }
31 })
32 .collect::<Vec<_>>()
33 .join(&encoding_characters.subcomponent_separator);
34 Some(value)
35 } else {
36 component.value.as_ref().and_then(|s| s.value.clone())
37 }
38}
39
40pub fn segment_field_repititon_to_string(
41 encoding_characters: &EncodingInformation,
42 segment: &HL7V2SegmentsFieldsValue,
43) -> String {
44 let mut result = "".to_string();
45
46 if let Some(components) = &segment.components {
47 result.push_str(
48 &components
49 .into_iter()
50 .map(|c| component_to_string(encoding_characters, c).unwrap_or_default())
51 .collect::<Vec<_>>()
52 .join(&encoding_characters.component_separator),
53 )
54 } else if let Some(value) = &segment.value {
55 result.push_str(&component_to_string(encoding_characters, value).unwrap_or_default());
56 }
57
58 result
59}
60
61pub fn segment_field_to_string(
62 encoding_characters: &EncodingInformation,
63 segment: &HL7V2SegmentsFields,
64) -> String {
65 let mut result = "".to_string();
66
67 if let Some(repititions) = &segment.repetitions {
68 result.push_str(
69 &repititions
70 .into_iter()
71 .map(|r| segment_field_repititon_to_string(encoding_characters, r))
72 .collect::<Vec<_>>()
73 .join(&encoding_characters.repetition_separator),
74 );
75 } else if let Some(value) = &segment.value {
76 result.push_str(&segment_field_repititon_to_string(
77 encoding_characters,
78 value,
79 ));
80 }
81
82 result
83}
84
85pub fn segment_to_string(
86 encoding_characters: &EncodingInformation,
87 segment: &HL7V2Segments,
88) -> String {
89 let mut result = segment
90 .id
91 .value
92 .as_ref()
93 .map(|s| s.as_str())
94 .unwrap_or("")
95 .to_string();
96
97 result.push_str(&encoding_characters.field_separator);
98
99 let default_fields = vec![];
100 result.push_str(
101 &segment
102 .fields
103 .as_ref()
104 .unwrap_or(&default_fields)
105 .into_iter()
106 .map(|s| segment_field_to_string(encoding_characters, s))
107 .collect::<Vec<_>>()
108 .join(&encoding_characters.field_separator),
109 );
110
111 result
112}
113
114fn get_encoding_characters(hl7v2_message: &HL7V2) -> Option<String> {
115 let Some(msh) = hl7v2_message.segments.as_ref().and_then(|segments| {
116 segments
117 .iter()
118 .find(|s| s.id.value.as_ref().map(|s| s.as_str()) == Some("MSH"))
119 }) else {
120 return None;
121 };
122
123 let Some(encoding_characters_str) = msh
124 .fields
125 .as_ref()
126 .and_then(|fields| fields.into_iter().next())
127 .and_then(|field| {
128 field.value.as_ref().and_then(|v| {
129 v.value
130 .as_ref()
131 .and_then(|s| s.value.as_ref())
132 .and_then(|s| s.value.as_ref().map(|s| s.as_str()))
133 })
134 })
135 else {
136 return None;
137 };
138
139 Some(encoding_characters_str.to_string())
140}
141
142pub struct SerializeMessage<'a>(pub &'a HL7V2);
143
144impl<'a> From<SerializeMessage<'a>> for String {
145 fn from(value: SerializeMessage<'a>) -> Self {
146 let hl7v2_message = value.0;
147 let field_seperator = hl7v2_message
148 .fieldSeparator
149 .value
150 .as_ref()
151 .map(|s| s.as_str())
152 .unwrap_or("|");
153 let encoding_characters_str =
154 get_encoding_characters(&hl7v2_message).unwrap_or("^~\\&".to_string());
155
156 let mut result = "".to_string();
157
158 let encoding_characters = EncodingInformation {
159 field_separator: field_seperator.to_string(),
160 component_separator: encoding_characters_str
161 .chars()
162 .nth(0)
163 .unwrap_or('^')
164 .to_string(),
165 repetition_separator: encoding_characters_str
166 .chars()
167 .nth(1)
168 .unwrap_or('~')
169 .to_string(),
170 escape_character: encoding_characters_str
171 .chars()
172 .nth(2)
173 .unwrap_or('\\')
174 .to_string(),
175
176 subcomponent_separator: encoding_characters_str
177 .chars()
178 .nth(3)
179 .unwrap_or('&')
180 .to_string(),
181 };
182
183 if let Some(segments) = &hl7v2_message.segments {
184 let k = segments
185 .into_iter()
186 .map(|s| segment_to_string(&encoding_characters, s))
187 .collect::<Vec<_>>()
188 .join("\n");
189
190 result.push_str(&k);
191 }
192
193 result
194 }
195}