Skip to main content

hl7_net/
component.rs

1use crate::encoding::HL7Encoding;
2use crate::error::Hl7Error;
3use crate::sub_component::SubComponent;
4
5/// A component of an HL7 field, containing one or more [`SubComponent`]s
6/// separated by the subcomponent delimiter.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct Component {
9    raw: String,
10    /// The parsed subcomponents (always at least one).
11    pub sub_components: Vec<SubComponent>,
12    /// `true` when the component contains more than one subcomponent.
13    pub is_subcomponentized: bool,
14}
15
16impl Component {
17    /// Parses a component from its raw value, splitting on the subcomponent delimiter.
18    pub fn parse(raw: &str, enc: &HL7Encoding) -> Self {
19        let sub_components: Vec<SubComponent> = raw
20            .split(enc.subcomponent_delimiter)
21            .map(SubComponent::new)
22            .collect();
23        let is_subcomponentized = sub_components.len() > 1;
24
25        Self { raw: raw.to_string(), sub_components, is_subcomponentized }
26    }
27
28    /// Builds a component holding a single, unsplit subcomponent. Used for the
29    /// MSH delimiter fields where the value must not be split.
30    pub(crate) fn single(raw: &str) -> Self {
31        Self {
32            raw: raw.to_string(),
33            sub_components: vec![SubComponent::new(raw)],
34            is_subcomponentized: false,
35        }
36    }
37
38    /// The raw value, or `None` when "present but null".
39    pub fn raw(&self, enc: &HL7Encoding) -> Option<&str> {
40        if self.raw == enc.present_but_null {
41            None
42        } else {
43            Some(&self.raw)
44        }
45    }
46
47    /// The decoded value, or `None` when "present but null".
48    pub fn value(&self, enc: &HL7Encoding) -> Option<String> {
49        if self.raw == enc.present_but_null {
50            None
51        } else {
52            Some(enc.decode(&self.raw))
53        }
54    }
55
56    /// Re-parses the component from a new raw value.
57    pub fn set_value(&mut self, value: &str, enc: &HL7Encoding) {
58        *self = Component::parse(value, enc);
59    }
60
61    /// Returns the subcomponent at the given 1-based position.
62    pub fn sub_component(&self, position: usize) -> Result<&SubComponent, Hl7Error> {
63        position
64            .checked_sub(1)
65            .and_then(|i| self.sub_components.get(i))
66            .ok_or_else(|| Hl7Error::new("SubComponent not available"))
67    }
68}