use edifact_rs::{EdifactDeserialize, EdifactSerialize};
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "BGM")]
pub struct Bgm {
#[edifact(element = 0)]
pub document_code: String,
#[edifact(element = 1)]
pub document_id: Option<String>,
#[edifact(element = 2)]
pub function: Option<String>,
}
impl Bgm {
#[must_use]
pub fn pruefidentifikator(&self) -> Option<crate::Pruefidentifikator> {
self.document_id
.as_deref()
.and_then(|s| s.parse::<u32>().ok())
.and_then(|code| crate::Pruefidentifikator::new(code).ok())
}
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "DTM")]
pub struct Dtm {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 0, component = 1)]
pub value: Option<String>,
#[edifact(element = 0, component = 2)]
pub format: Option<String>,
}
impl Dtm {
#[must_use]
pub fn is_document_date(&self) -> bool {
self.qualifier == "137"
}
#[must_use]
pub fn is_period_start(&self) -> bool {
self.qualifier == "163"
}
#[must_use]
pub fn is_period_end(&self) -> bool {
self.qualifier == "164"
}
#[must_use]
pub fn value_str(&self) -> Option<&str> {
self.value.as_deref()
}
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "NAD", qualifier_from = 0)]
pub struct Nad {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 1)]
pub party_id: Option<String>,
#[edifact(element = 1, component = 2)]
pub agency_code: Option<String>,
#[edifact(element = 3)]
pub party_name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "RFF")]
pub struct Rff {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 0, component = 1)]
pub reference: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "IDE")]
pub struct Ide {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 1)]
pub object_id: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "LOC")]
pub struct Loc {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 1)]
pub location_id: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "ERC")]
pub struct Erc {
#[edifact(element = 0)]
pub error_code: String,
#[edifact(element = 0, component = 1)]
pub code_list_id: Option<String>,
#[edifact(element = 0, component = 2)]
pub agency_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "FTX")]
pub struct Ftx {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 3)]
pub text: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "QTY")]
pub struct Qty {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 0, component = 1)]
pub value: Option<String>,
#[edifact(element = 0, component = 2)]
pub unit: Option<String>,
}
impl Qty {
#[must_use]
pub fn value_f64(&self) -> Option<f64> {
self.value
.as_deref()
.map(|s| s.replace(',', "."))
.and_then(|s| s.parse::<f64>().ok())
}
#[must_use]
pub fn is_metered(&self) -> bool {
self.qualifier == "220"
}
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UCI")]
pub struct Uci {
#[edifact(element = 0)]
pub interchange_ref: String,
#[edifact(element = 1)]
pub sender: Option<String>,
#[edifact(element = 2)]
pub recipient: Option<String>,
#[edifact(element = 3)]
pub action_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UNH")]
pub struct Unh {
#[edifact(element = 0)]
pub message_ref: String,
#[edifact(element = 1)]
pub message_type: String,
#[edifact(element = 1, component = 4)]
pub assoc_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UNT")]
pub struct Unt {
#[edifact(element = 0)]
pub segment_count: String,
#[edifact(element = 1)]
pub message_ref: String,
}
pub(crate) fn find_nad(segments: &[edifact_rs::Segment<'_>], qualifier: &str) -> Option<Nad> {
segments
.iter()
.filter(|s| s.tag == "NAD")
.find(|s| s.element_str(0) == Some(qualifier))
.and_then(|seg| Nad::edifact_deserialize(std::slice::from_ref(seg)).ok())
}
pub(crate) fn collect_dtm(segments: &[edifact_rs::Segment<'_>]) -> Vec<Dtm> {
segments
.iter()
.filter(|s| s.tag == "DTM")
.filter_map(|seg| Dtm::edifact_deserialize(std::slice::from_ref(seg)).ok())
.collect()
}
pub(crate) fn find_bgm(segments: &[edifact_rs::Segment<'_>]) -> Option<Bgm> {
segments
.iter()
.filter(|s| s.tag == "BGM")
.find_map(|seg| Bgm::edifact_deserialize(std::slice::from_ref(seg)).ok())
}
pub(crate) fn find_uci(segments: &[edifact_rs::Segment<'_>]) -> Option<Uci> {
segments
.iter()
.filter(|s| s.tag == "UCI")
.find_map(|seg| Uci::edifact_deserialize(std::slice::from_ref(seg)).ok())
}
pub(crate) fn find_rff(segments: &[edifact_rs::Segment<'_>], qualifier: &str) -> Option<Rff> {
segments
.iter()
.filter(|s| s.tag == "RFF")
.find(|s| s.element_str(0) == Some(qualifier))
.and_then(|seg| Rff::edifact_deserialize(std::slice::from_ref(seg)).ok())
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UCM")]
pub struct Ucm {
#[edifact(element = 0)]
pub message_ref: String,
#[edifact(element = 1)]
pub message_type: String,
#[edifact(element = 1, component = 4)]
pub assoc_code: Option<String>,
#[edifact(element = 2)]
pub action_code: String,
#[edifact(element = 3)]
pub syntax_error: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UCS")]
pub struct Ucs {
#[edifact(element = 0)]
pub segment_position: String,
#[edifact(element = 0, component = 1)]
pub segment_tag: Option<String>,
#[edifact(element = 1)]
pub error_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UCD")]
pub struct Ucd {
#[edifact(element = 0)]
pub error_code: String,
#[edifact(element = 1)]
pub element_position: Option<String>,
#[edifact(element = 1, component = 1)]
pub component_position: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "LIN")]
pub struct Lin {
#[edifact(element = 0)]
pub line_number: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "PIA")]
pub struct Pia {
#[edifact(element = 0)]
pub qualifier: String,
#[edifact(element = 1)]
pub item_number: Option<String>,
#[edifact(element = 1, component = 1)]
pub item_type: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "CCI")]
pub struct Cci {
#[edifact(element = 0)]
pub category: Option<String>,
#[edifact(element = 2)]
pub characteristic_id: Option<String>,
#[edifact(element = 2, component = 1)]
pub code_list_id: Option<String>,
#[edifact(element = 2, component = 2)]
pub agency_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "STS")]
pub struct Sts {
#[edifact(element = 0)]
pub category: Option<String>,
#[edifact(element = 1)]
pub status_code: Option<String>,
#[edifact(element = 1, component = 1)]
pub sub_qualifier: Option<String>,
#[edifact(element = 1, component = 2)]
pub agency_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "UNS")]
pub struct Uns {
#[edifact(element = 0)]
pub section_id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "CTA")]
pub struct Cta {
#[edifact(element = 0)]
pub function_code: Option<String>,
#[edifact(element = 1)]
pub name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, EdifactDeserialize, EdifactSerialize)]
#[edifact(segment = "COM")]
pub struct Com {
#[edifact(element = 0)]
pub number: Option<String>,
#[edifact(element = 0, component = 1)]
pub channel: Option<String>,
}
pub(crate) fn try_deserialize<T: edifact_rs::EdifactDeserialize>(
seg: &edifact_rs::Segment<'_>,
) -> Option<T> {
T::edifact_deserialize(std::slice::from_ref(seg)).ok()
}