use crate::edi_parse_error::EdiParseError;
use crate::interchange_control::InterchangeControl;
use crate::tokenizer::tokenize;
use serde::{Deserialize, Serialize};
use std::collections::VecDeque;
#[derive(Serialize, Deserialize)]
pub struct EdiDocument<'a, 'b> {
#[serde(borrow = "'a + 'b")]
pub interchanges: VecDeque<InterchangeControl<'a, 'b>>,
}
pub fn parse(input: &str) -> Result<EdiDocument, EdiParseError> {
parse_inner(input, false)
}
pub fn loose_parse(input: &str) -> Result<EdiDocument, EdiParseError> {
parse_inner(input, true)
}
fn parse_inner(input: &str, loose: bool) -> Result<EdiDocument, EdiParseError> {
let document_tokens = tokenize(input).expect("unsupported EDI format");
let mut interchanges: VecDeque<InterchangeControl> = VecDeque::new();
for segment in document_tokens {
match segment[0] {
"ISA" => {
interchanges.push_back(
InterchangeControl::parse_from_tokens(segment)
.expect("failed to parse interchange header"),
);
}
"GS" => {
interchanges.back_mut().expect("unable to enqueue functional group when no interchanges have been enqueued").add_functional_group(segment);
}
"ST" => {
interchanges
.back_mut()
.expect("unable to enqueue transaction when no interchanges have been enqueued")
.add_transaction(segment);
}
"IEA" => {
if !loose {
interchanges
.back()
.expect("unable to validate IEA without initial ISA")
.validate_interchange_control(segment)
.expect("interchange control validation failed");
}
}
"GE" => {
if !loose {
interchanges
.back()
.expect("unable to validate GE without interchange")
.validate_functional_group(segment)
.expect("functional group validation failed");
}
}
"SE" => {
if !loose {
interchanges
.back()
.expect("unable to validate SE without interchange")
.validate_transaction(segment)
.expect("transaction validation failed")
}
}
_ => {
interchanges
.back_mut()
.expect(
"unable to enqueue generic segment when no interchanges have been enqueued",
)
.add_generic_segment(segment);
}
}
}
return Ok(EdiDocument { interchanges });
}