Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
fn invalid(reason: &str) -> HsCodeCheck {
HsCodeCheck {
valid: false,
normalised: None,
kind: None,
chapter: None,
heading: None,
subheading: None,
reason: Some(reason.to_string()),
}
}
/// Check the format of a 6-digit HS, 8-digit CN or 10-digit TARIC/UK
/// commodity code. Validators answer rather than panic: a malformed code is
/// the answer "no".
pub fn validate_hs_code(value: &str) -> HsCodeCheck {
let mut digits = String::new();
for ch in value.chars() {
if ch == ' ' || ch == '.' {
continue;
}
if !ch.is_ascii_digit() {
return invalid("bad-character");
}
digits.push(ch);
}
if digits.is_empty() {
return invalid("empty");
}
let kind = match digits.len() {
6 => "hs",
8 => "cn",
10 => "taric",
_ => return invalid("bad-length"),
};
// Text, not a number: chapter "01" must keep its zero.
let chapter = &digits[0..2];
if chapter == "00" {
return invalid("bad-chapter");
}
if chapter == "77" {
return invalid("reserved-chapter");
}
// 98 and 99 are left to national tariffs, so only a national-length code may use them.
if (chapter == "98" || chapter == "99") && kind == "hs" {
return invalid("national-chapter");
}
if &digits[2..4] == "00" {
return invalid("bad-heading");
}
HsCodeCheck {
valid: true,
chapter: Some(chapter.to_string()),
heading: Some(digits[0..4].to_string()),
subheading: Some(digits[0..6].to_string()),
kind: Some(kind.to_string()),
normalised: Some(digits.clone()),
reason: None,
}
}
pub fn hs_code_check_to_value(result: &HsCodeCheck) -> Value {
let text = |field: &Option<String>| match field {
Some(s) => Value::str(s),
None => Value::Null,
};
Value::obj(vec![
("valid", Value::Bool(result.valid)),
("normalised", text(&result.normalised)),
("kind", text(&result.kind)),
("chapter", text(&result.chapter)),
("heading", text(&result.heading)),
("subheading", text(&result.subheading)),
("reason", text(&result.reason)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
hs_code_check_to_value(&validate_hs_code(args[0].as_str()))
}