///|
pub struct NormalizedElement {
code : String
raw_value : String
numeric_value : Int?
decimal_places : Int?
date_value : String?
} derive(Debug, Eq)
///|
pub fn GS1Message::normalized_element(
self : GS1Message,
code : String,
) -> NormalizedElement? {
for element in self.elements {
if element.code() == code {
let numeric_value = if is_all_digits(element.value) {
Some(decimal_digits(element.value))
} else {
None
}
let decimal_places = implied_decimal_places(code)
let date_value = if is_date_ai(code) {
Some(yymmdd_to_iso(element.value))
} else {
None
}
return Some({
code,
raw_value: element.value,
numeric_value,
decimal_places,
date_value,
})
}
}
None
}
///|
pub fn NormalizedElement::code(self : NormalizedElement) -> String {
self.code
}
///|
pub fn NormalizedElement::raw(self : NormalizedElement) -> String {
self.raw_value
}
///|
fn decimal_digits(value : String) -> Int {
value.fold(init=0, fn(acc, ch) {
acc * 10 + ch.to_int() - ('0' : UInt16).to_int()
})
}
///|
fn implied_decimal_places(code : String) -> Int? {
match code {
"3101"
| "3111"
| "3121"
| "3131"
| "3141"
| "3151"
| "3161"
| "3201"
| "3211"
| "3221"
| "3231"
| "3241"
| "3251"
| "3261"
| "3271"
| "3281"
| "3291" => Some(1)
"3102"
| "3112"
| "3122"
| "3132"
| "3142"
| "3152"
| "3162"
| "3202"
| "3212"
| "3222"
| "3232"
| "3242"
| "3252"
| "3262"
| "3272"
| "3282"
| "3292" => Some(2)
"3103"
| "3113"
| "3123"
| "3133"
| "3143"
| "3153"
| "3163"
| "3203"
| "3213"
| "3223"
| "3233"
| "3243"
| "3253"
| "3263"
| "3273"
| "3283"
| "3293" => Some(3)
"3104"
| "3114"
| "3124"
| "3134"
| "3144"
| "3154"
| "3164"
| "3204"
| "3214"
| "3224"
| "3234"
| "3244"
| "3254"
| "3264"
| "3274"
| "3284"
| "3294" => Some(4)
"3105"
| "3115"
| "3125"
| "3135"
| "3145"
| "3155"
| "3165"
| "3205"
| "3215"
| "3225"
| "3235"
| "3245"
| "3255"
| "3265"
| "3275"
| "3285"
| "3295" => Some(5)
"3106"
| "3116"
| "3126"
| "3136"
| "3146"
| "3156"
| "3166"
| "3206"
| "3216"
| "3226"
| "3236"
| "3246"
| "3256"
| "3266"
| "3276"
| "3286"
| "3296" => Some(6)
_ => None
}
}
///|
fn yymmdd_to_iso(value : String) -> String {
if value.length() != 6 || !is_all_digits(value) {
""
} else {
let year = two_digits(value, 0) + 2000
let month = two_digits(value, 2)
let day = two_digits(value, 4)
"\{year}-\{pad_two(month)}-\{pad_two(day)}"
}
}
///|
fn pad_two(value : Int) -> String {
if value < 10 {
"0\{value}"
} else {
"\{value}"
}
}