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