hl7-net 0.1.0

Lightweight HL7 V2 parser/writer, ported from the Efferent HL7-V2 .NET library
Documentation
use crate::encoding::HL7Encoding;
use crate::error::Hl7Error;
use crate::sub_component::SubComponent;

/// A component of an HL7 field, containing one or more [`SubComponent`]s
/// separated by the subcomponent delimiter.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Component {
    raw: String,
    /// The parsed subcomponents (always at least one).
    pub sub_components: Vec<SubComponent>,
    /// `true` when the component contains more than one subcomponent.
    pub is_subcomponentized: bool,
}

impl Component {
    /// Parses a component from its raw value, splitting on the subcomponent delimiter.
    pub fn parse(raw: &str, enc: &HL7Encoding) -> Self {
        let sub_components: Vec<SubComponent> = raw
            .split(enc.subcomponent_delimiter)
            .map(SubComponent::new)
            .collect();
        let is_subcomponentized = sub_components.len() > 1;

        Self { raw: raw.to_string(), sub_components, is_subcomponentized }
    }

    /// Builds a component holding a single, unsplit subcomponent. Used for the
    /// MSH delimiter fields where the value must not be split.
    pub(crate) fn single(raw: &str) -> Self {
        Self {
            raw: raw.to_string(),
            sub_components: vec![SubComponent::new(raw)],
            is_subcomponentized: false,
        }
    }

    /// The raw value, or `None` when "present but null".
    pub fn raw(&self, enc: &HL7Encoding) -> Option<&str> {
        if self.raw == enc.present_but_null {
            None
        } else {
            Some(&self.raw)
        }
    }

    /// The decoded value, or `None` when "present but null".
    pub fn value(&self, enc: &HL7Encoding) -> Option<String> {
        if self.raw == enc.present_but_null {
            None
        } else {
            Some(enc.decode(&self.raw))
        }
    }

    /// Re-parses the component from a new raw value.
    pub fn set_value(&mut self, value: &str, enc: &HL7Encoding) {
        *self = Component::parse(value, enc);
    }

    /// Returns the subcomponent at the given 1-based position.
    pub fn sub_component(&self, position: usize) -> Result<&SubComponent, Hl7Error> {
        position
            .checked_sub(1)
            .and_then(|i| self.sub_components.get(i))
            .ok_or_else(|| Hl7Error::new("SubComponent not available"))
    }
}