use crate::edi_parse_error::EdiParseError;
use crate::tokenizer::SegmentTokens;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::VecDeque;
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct GenericSegment<'a> {
#[serde(borrow)]
pub segment_abbreviation: Cow<'a, str>,
#[serde(borrow)]
pub elements: VecDeque<Cow<'a, str>>,
}
impl<'a> GenericSegment<'a> {
pub(crate) fn parse_from_tokens(
tokens: SegmentTokens<'a>,
) -> Result<GenericSegment<'a>, EdiParseError> {
let elements: Vec<&str> = tokens.iter().map(|x| x.trim()).collect();
edi_assert!(
elements.len() >= 2,
"at least two elements are required in a segment",
tokens
);
let segment_abbreviation = Cow::from(elements[0]);
let elements = elements[1..]
.to_vec()
.iter()
.map(|x| Cow::from(*x))
.collect::<VecDeque<Cow<str>>>();
Ok(GenericSegment {
segment_abbreviation,
elements,
})
}
pub fn to_x12_string(&self, element_delimiter: char) -> String {
self.elements
.iter()
.fold(self.segment_abbreviation.to_string(), |mut acc, s| {
acc.push(element_delimiter);
acc.push_str(s);
acc
})
}
}
#[test]
fn convert_generic_segment_to_string() {
let segment = GenericSegment {
segment_abbreviation: Cow::from("BGN"),
elements: ["20", "TEST_ID", "200615", "0000"]
.iter()
.map(|x| Cow::from(*x))
.collect::<VecDeque<Cow<str>>>(),
};
assert_eq!(segment.to_x12_string('*'), "BGN*20*TEST_ID*200615*0000");
}
#[test]
fn construct_generic_segment() {
let test_input = vec![
"GS",
"PO",
"SENDERGS",
"007326879",
"20020226",
"1534",
"1",
"X",
"004010",
];
let expected_result = GenericSegment {
segment_abbreviation: Cow::from("GS"),
elements: [
"PO",
"SENDERGS",
"007326879",
"20020226",
"1534",
"1",
"X",
"004010",
]
.iter()
.map(|x| Cow::from(*x))
.collect::<VecDeque<Cow<str>>>(),
};
assert_eq!(
GenericSegment::parse_from_tokens(test_input).unwrap(),
expected_result
);
}