use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Cardinality {
Mandatory,
Required,
Dependent,
Optional,
NotUsed,
Conditional,
}
impl Cardinality {
pub fn from_status(status: &str) -> Self {
match status.trim() {
"M" => Cardinality::Mandatory,
"R" => Cardinality::Required,
"D" => Cardinality::Dependent,
"O" => Cardinality::Optional,
"N" => Cardinality::NotUsed,
"C" => Cardinality::Conditional,
_ => Cardinality::Conditional, }
}
pub fn is_required(&self) -> bool {
matches!(self, Cardinality::Mandatory | Cardinality::Required)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CodeDefinition {
pub value: String,
pub name: String,
pub description: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum EdifactDataType {
Alphabetic,
Numeric,
Alphanumeric,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EdifactFormat {
pub data_type: EdifactDataType,
pub min_length: Option<usize>,
pub max_length: usize,
}
impl EdifactFormat {
pub fn parse(format: &str) -> Option<Self> {
let format = format.trim();
if format.is_empty() {
return None;
}
let (type_str, rest) = if let Some(rest) = format.strip_prefix("an") {
("an", rest)
} else if let Some(rest) = format.strip_prefix('a') {
("a", rest)
} else if let Some(rest) = format.strip_prefix('n') {
("n", rest)
} else {
return None;
};
let data_type = match type_str {
"a" => EdifactDataType::Alphabetic,
"n" => EdifactDataType::Numeric,
"an" => EdifactDataType::Alphanumeric,
_ => return None,
};
let (is_variable, length_str) = if let Some(stripped) = rest.strip_prefix("..") {
(true, stripped)
} else {
(false, rest)
};
let max_length: usize = length_str.parse().ok()?;
let min_length = if is_variable { None } else { Some(max_length) };
Some(EdifactFormat {
data_type,
min_length,
max_length,
})
}
}