use nom::bytes::complete::tag;
use nom::bytes::complete::take_until;
use nom::bytes::complete::take_while;
use nom::character::complete::newline;
use nom::combinator::opt;
use nom::multi::separated_list0;
use nom::sequence::delimited;
use nom::IResult;
use nom::Parser as _;
pub mod dt;
pub mod tm;
#[cfg(feature = "v004010")]
pub fn is_equal_payload<T: PartialEq>(
src: &crate::v004010::Transmission<T>,
target: &crate::v004010::Transmission<T>,
) -> bool {
let Some(target_first) = target.functional_group.first() else {
return src.functional_group.is_empty();
};
src.functional_group
.iter()
.all(|item| item.eq(target_first))
}
pub fn parse_line<'a>(input: &'a str, segment_name: &str) -> IResult<&'a str, Vec<&'a str>> {
let tag_name = format!("{segment_name}*");
let (rest, vars) = delimited(tag(tag_name.as_str()), take_until("~"), tag("~")).parse(input)?;
let (_, vars) = separated_list0(
tag("*"),
take_while(|x: char| {
x != '*' && (x.is_alphanumeric() || x.is_whitespace() || x.is_ascii_punctuation())
}),
)
.parse(vars)?;
let (rest, _) = opt(newline).parse(rest)?;
Ok((rest, vars))
}
pub trait Parser<I, O, E> {
fn parse(str: I) -> IResult<I, O>;
}
pub fn unborrow_string(input: &&str) -> String {
input.to_string()
}
#[macro_export]
macro_rules! num_element {
($(#[$meta:meta])* $name:ident) => {
$(#[$meta])*
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct $name {
raw: ::std::string::String,
}
impl $name {
pub fn raw(&self) -> &str {
&self.raw
}
pub fn as_f64(&self) -> ::core::option::Option<f64> {
self.raw.parse().ok()
}
pub fn as_i64(&self) -> ::core::option::Option<i64> {
self.raw.parse().ok()
}
}
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(&self.raw)
}
}
impl $crate::util::X12Element for $name {
fn from_x12(s: &str) -> Self {
Self { raw: s.to_string() }
}
}
impl ::serde::Serialize for $name {
fn serialize<S: ::serde::Serializer>(&self, ser: S) -> ::core::result::Result<S::Ok, S::Error> {
ser.serialize_str(&self.raw)
}
}
impl<'de> ::serde::Deserialize<'de> for $name {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> ::core::result::Result<Self, D::Error> {
let raw = <::std::string::String as ::serde::Deserialize>::deserialize(d)?;
::core::result::Result::Ok(Self { raw })
}
}
};
}
#[macro_export]
macro_rules! time_element {
($(#[$meta:meta])* $name:ident) => {
$(#[$meta])*
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct $name {
raw: ::std::string::String,
}
impl $name {
pub fn raw(&self) -> &str {
&self.raw
}
pub fn time(&self) -> ::core::option::Option<::chrono::NaiveTime> {
::chrono::NaiveTime::parse_from_str(&self.raw, "%H%M%S")
.or_else(|_| ::chrono::NaiveTime::parse_from_str(&self.raw, "%H%M"))
.ok()
}
}
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(&self.raw)
}
}
impl $crate::util::X12Element for $name {
fn from_x12(s: &str) -> Self {
Self { raw: s.to_string() }
}
}
impl ::serde::Serialize for $name {
fn serialize<S: ::serde::Serializer>(&self, ser: S) -> ::core::result::Result<S::Ok, S::Error> {
ser.serialize_str(&self.raw)
}
}
impl<'de> ::serde::Deserialize<'de> for $name {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> ::core::result::Result<Self, D::Error> {
let raw = <::std::string::String as ::serde::Deserialize>::deserialize(d)?;
::core::result::Result::Ok(Self { raw })
}
}
};
}
pub trait X12Element {
fn from_x12(s: &str) -> Self;
}
impl X12Element for String {
fn from_x12(s: &str) -> Self {
s.to_string()
}
}
#[macro_export]
macro_rules! code_enum {
(
$(#[$meta:meta])*
$name:ident {
$($(#[$vmeta:meta])* $code:literal => $variant:ident),* $(,)?
}
) => {
$(#[$meta])*
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum $name {
$($(#[$vmeta])* $variant,)*
Unknown(String),
}
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
let s = match self {
$(Self::$variant => $code,)*
Self::Unknown(s) => s.as_str(),
};
f.write_str(s)
}
}
impl $crate::util::X12Element for $name {
fn from_x12(s: &str) -> Self {
match s {
$($code => Self::$variant,)*
other => Self::Unknown(other.to_string()),
}
}
}
impl ::core::default::Default for $name {
fn default() -> Self {
Self::Unknown(::std::string::String::new())
}
}
impl ::serde::Serialize for $name {
fn serialize<S: ::serde::Serializer>(&self, ser: S) -> ::core::result::Result<S::Ok, S::Error> {
ser.serialize_str(&::std::string::ToString::to_string(self))
}
}
impl<'de> ::serde::Deserialize<'de> for $name {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> ::core::result::Result<Self, D::Error> {
let s = <::std::string::String as ::serde::Deserialize>::deserialize(d)?;
::core::result::Result::Ok(<Self as $crate::util::X12Element>::from_x12(&s))
}
}
};
}
#[macro_export]
macro_rules! date_element {
($(#[$meta:meta])* $name:ident) => {
$(#[$meta])*
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct $name {
raw: ::std::string::String,
}
impl $name {
pub fn raw(&self) -> &str {
&self.raw
}
pub fn date(&self) -> ::core::option::Option<::chrono::NaiveDate> {
::chrono::NaiveDate::parse_from_str(&self.raw, "%Y%m%d").ok()
}
pub fn from_date(d: ::chrono::NaiveDate) -> Self {
Self { raw: d.format("%Y%m%d").to_string() }
}
}
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(&self.raw)
}
}
impl $crate::util::X12Element for $name {
fn from_x12(s: &str) -> Self {
Self { raw: s.to_string() }
}
}
impl ::serde::Serialize for $name {
fn serialize<S: ::serde::Serializer>(&self, ser: S) -> ::core::result::Result<S::Ok, S::Error> {
ser.serialize_str(&self.raw)
}
}
impl<'de> ::serde::Deserialize<'de> for $name {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> ::core::result::Result<Self, D::Error> {
let raw = <::std::string::String as ::serde::Deserialize>::deserialize(d)?;
::core::result::Result::Ok(Self { raw })
}
}
};
}