Skip to main content

haste_hl7v2/
serialize.rs

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// component separator, repetition separator, escape character, and subcomponent separator.
16
17pub 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}