1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::edi_parse_error::{try_option, 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)?;
let mut interchanges: VecDeque<InterchangeControl> = VecDeque::new();
for segment in document_tokens {
match segment[0] {
"ISA" => {
interchanges.push_back(InterchangeControl::parse_from_tokens(segment)?);
}
"GS" => {
try_option(interchanges.back_mut(), &segment)?.add_functional_group(segment)?;
}
"ST" => {
try_option(interchanges.back_mut(), &segment)?.add_transaction(segment)?;
}
"IEA" => {
if !loose {
try_option(interchanges.back(), &segment)?
.validate_interchange_control(segment)?;
};
}
"GE" => {
if !loose {
try_option(interchanges.back(), &segment)?
.validate_functional_group(segment)?;
};
}
"SE" => {
if !loose {
try_option(interchanges.back(), &segment)?.validate_transaction(segment)?;
};
}
_ => {
try_option(interchanges.back_mut(), &segment)?.add_generic_segment(segment)?;
}
}
}
return Ok(EdiDocument { interchanges });
}