use edifact_rs::OwnedSegment;
use crate::{AnyMessage, Error, MessageType, Pruefidentifikator, Release};
#[derive(Debug)]
pub struct LightMessage {
pub(crate) segments: Vec<OwnedSegment>,
message_type_code: Box<str>,
assoc_code: Box<str>,
message_ref: Box<str>,
pruefidentifikator: Option<u32>,
}
impl LightMessage {
pub(crate) fn from_segments(
segments: Vec<OwnedSegment>,
registry: &crate::registry::ReleaseRegistry,
) -> Result<Self, Error> {
let (message_ref, message_type_code, assoc_code) = {
let unh = segments
.iter()
.find(|s| s.tag == "UNH")
.ok_or(Error::MissingSegment("UNH"))?;
let message_ref = unh.element_str(0).unwrap_or_default().to_owned();
let message_type_code = unh
.component_str(1, 0)
.ok_or(Error::MalformedSegment("UNH"))?
.to_owned();
let assoc_code = unh.component_str(1, 4).unwrap_or_default().to_owned();
(message_ref, message_type_code, assoc_code)
};
let pruefidentifikator: Option<u32> =
match crate::parse::resolve_pid_source_pub(&message_type_code, &assoc_code, registry) {
crate::registry::PidSource::RffZ13 => segments
.iter()
.find(|s| s.tag == "RFF" && s.element_str(0).is_some_and(|q| q == "Z13"))
.and_then(|rff| rff.component_str(0, 1))
.and_then(|s| s.parse().ok()),
crate::registry::PidSource::BgmDe1004 => segments
.iter()
.find(|s| s.tag == "BGM")
.and_then(|bgm| bgm.element_str(1))
.and_then(|s| s.parse().ok()),
};
Ok(Self {
segments,
message_type_code: message_type_code.into_boxed_str(),
assoc_code: assoc_code.into_boxed_str(),
message_ref: message_ref.into_boxed_str(),
pruefidentifikator,
})
}
#[must_use]
pub fn message_type_code(&self) -> &str {
&self.message_type_code
}
#[must_use]
pub fn try_message_type(&self) -> Option<MessageType> {
MessageType::from_unh_code(&self.message_type_code)
}
#[must_use]
pub fn assoc_code(&self) -> &str {
&self.assoc_code
}
#[must_use]
pub fn release(&self) -> Release {
Release::new(&self.assoc_code)
}
#[must_use]
pub fn message_ref(&self) -> &str {
&self.message_ref
}
#[must_use]
pub fn pruefidentifikator(&self) -> Option<Pruefidentifikator> {
self.pruefidentifikator
.and_then(|n| Pruefidentifikator::new(n).ok())
}
#[must_use]
pub fn segments(&self) -> &[OwnedSegment] {
&self.segments
}
pub fn into_message(self) -> Result<AnyMessage, Error> {
crate::parse::dispatch_message(self.segments, crate::registry::ReleaseRegistry::global())
}
}