hl7_parser/message/subcomponent.rs
1use super::Separators;
2use crate::display::SubcomponentDisplay;
3use std::ops::Range;
4
5/// A subcomponent is the smallest unit of data in an HL7 message.
6/// It is a string that may contain escape sequences to encode the separators.
7/// It is the only type that does not have a separator character.
8/// It is always contained within a component.
9///
10/// For parsing performance reasons, the subcomponent does not decode the escape
11/// sequences when it is parsed. Instead, the escape sequences are decoded when
12/// the subcomponent is displayed. This allows the subcomponent to be parsed
13/// without allocating a new string for the decoded value.
14#[derive(Debug, Clone, PartialEq, Eq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize))]
16pub struct Subcomponent<'m> {
17 /// The raw value of the subcomponent, including escape sequences
18 pub value: &'m str,
19 /// The range of the subcomponent in the original message
20 pub range: Range<usize>,
21}
22
23impl<'m> Subcomponent<'m> {
24 pub(crate) fn new_single(source: &'m str, range: Range<usize>) -> Self {
25 Subcomponent {
26 value: source,
27 range,
28 }
29 }
30
31 #[inline]
32 /// Display the subcomponent value, using the separators to decode escape sequences
33 /// by default. Note: if you want to display the raw value without decoding escape
34 /// sequences, use the `#` flag, e.g. `format!("{:#}", subcomponent.display(separators))`
35 ///
36 /// # Examples
37 ///
38 /// ```
39 /// use hl7_parser::message::{Separators, Subcomponent};
40 /// let separators = Separators::default();
41 ///
42 /// let subcomponent = Subcomponent {
43 /// value: r"foo\F\bar",
44 /// range: 0..1, // ignore
45 /// };
46 ///
47 /// assert_eq!(format!("{}", subcomponent.display(&separators)), "foo|bar");
48 /// assert_eq!(format!("{:#}", subcomponent.display(&separators)), r"foo\F\bar");
49 /// ```
50 pub fn display(&'m self, separators: &'m Separators) -> SubcomponentDisplay<'m> {
51 SubcomponentDisplay {
52 value: self.value,
53 separators,
54 }
55 }
56
57 #[inline]
58 /// Get the raw value of the subcomponent. This is the value as it appears in the message,
59 /// without any decoding of escape sequences.
60 pub fn raw_value(&self) -> &'m str {
61 self.value
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn subcomponents_can_display_raw() {
71 let separators = Separators::default();
72
73 let subcomponent = Subcomponent {
74 value: r"foo\F\bar",
75 range: 0..1, // ignore
76 };
77
78 assert_eq!(
79 format!("{:#}", subcomponent.display(&separators)),
80 r"foo\F\bar"
81 );
82 }
83
84 #[test]
85 fn subcomponents_can_display_decoded() {
86 let separators = Separators::default();
87
88 let subcomponent = Subcomponent {
89 value: r"foo\F\bar",
90 range: 0..1, // ignore
91 };
92
93 assert_eq!(format!("{}", subcomponent.display(&separators)), "foo|bar");
94 }
95}