use std::fs::OpenOptions;
use std::io::Read;
use asterix_parser::asterix::uap_json::enums::{AttributeItem, AttributeType, AttributeValueType, ConstraintType, DataItemType, DataItemValueType, DataType, DenominatorType, ElementType, ElementValueType, LsbType};
use asterix_parser::asterix::uap_json::structures::{AttributeRule, ConstraintRule, DataItemRule, DataRecord};
#[test]
pub(crate) fn test_read_asterix_json_spec_from_file() {
let _cat034_1_29_file_path = "resources/uaps/cat034_1_29_definition.json";
let _cat048_1_30_file_path = "resources/uaps/cat048_1_30_definition.json";
let _cat048_1_31_file_path = "resources/uaps/cat048_1_31_definition.json";
let mut myfile = match OpenOptions::new()
.read(true)
.write(false)
.create(false)
.open(_cat048_1_31_file_path) {
Ok(f) => f,
Err(e) => panic!("Error opening file {}", e),
};
let mut raw_json = String::new();
myfile.read_to_string(&mut raw_json).unwrap();
let trimmed_json = raw_json.trim();
let deserialized:DataRecord = match serde_json::from_str(&trimmed_json) {
Ok(d) => d,
Err(e) => {
panic!("Error message: {}", e.to_string())
},
};
println!("Category: {:03}, {}, edition: {}.{}",
deserialized.number,
deserialized.title,
deserialized.edition.major,
deserialized.edition.minor);
println!();
for dataitem in &deserialized.catalogue {
println!("DataItem: {}, {}", dataitem.name, dataitem.title);
let describe = true;
if describe {
if dataitem.name == "030" {
let description = describe_data_item(dataitem);
println!("{}", description)
}
}
}
}
fn describe_data_item(dataitem: &DataItemRule) -> String {
let mut description: Vec<String> = vec![format!("Dataitem: {}, {}", dataitem.name, dataitem.title)];
let rule_desc: String;
match &dataitem.rule {
DataItemType::ContextFree { value } => {
rule_desc = match value {
DataItemValueType::Element { rule, size} => describe_element(rule, size),
DataItemValueType::Group { items } => describe_option_attribute_item(&items),
DataItemValueType::Extended { items } => describe_option_attribute_item(&items),
DataItemValueType::Repetitive { rep, variation }
=> describe_repetitive(rep, &variation),
DataItemValueType::Compound { fspec, items }
=> describe_compound(&fspec, &items),
DataItemValueType::Explicit { expl } => format!("Explicit: {}", expl)
};
},
};
description.push(rule_desc);
description.join("\n")
}
fn describe_option_attribute_item(items: &Vec<Option<AttributeItem>>) -> String {
let mut description = vec![String::from("Attributes: "), ];
for attribute_item in items {
let attribute_description = match attribute_item {
Some(a) => { describe_attribute_item(a) }
None => continue
};
description.push(attribute_description);
}
description.join("\n")
}
fn describe_attribute_item(attribute_item: &AttributeItem) -> String {
let description = match attribute_item {
AttributeItem::SpareEntry { length, spare } => {
if *spare
{
format!("Spare entry: length:{}", length)
}
else {
String::new()
}
},
AttributeItem::AttributeEntry(e) => describe_attribute_entry(e)
};
description
}
fn describe_attribute_entry(attribute_rule: &AttributeRule) -> String {
let mut description = format!("Attributo {} - {}", attribute_rule.name, attribute_rule.title);
let mut _rule: String;
match &attribute_rule.rule {
AttributeType::ContextFree { value } => { _rule = describe_attribute_value_type(value);},
};
description.push_str(_rule.as_str());
description
}
fn describe_attribute_value_type(attribute_value_type: &AttributeValueType) -> String {
let attribute_value_type_desc = match attribute_value_type {
AttributeValueType::Element { rule, size } => describe_element(rule, &size),
AttributeValueType::Group { items } => describe_group(items),
AttributeValueType::Table { values } => describe_table(&values),
AttributeValueType::Repetitive { rep, variation } => describe_repetitive(rep, &variation),
};
attribute_value_type_desc
}
fn describe_element(element_rule: &ElementType, size: &u8) -> String {
let mut description: Vec<String> = vec![String::from("Element Type: ")];
match element_rule {
ElementType::ContextFree { value } => {
let element_desc = describe_element_type(value);
description.push(element_desc);
}
};
description.push(format!("Size: {}", size));
description.join("\n")
}
fn describe_element_type(value: &ElementValueType) -> String {
let element_desc = match value {
ElementValueType::Fx => format!("{}", "Fx"),
ElementValueType::Integer {
constraints,
signed
} => describe_integer(constraints, signed),
ElementValueType::Raw => format!("{}", "Raw"),
ElementValueType::Regular { size } => format!("{}:{:?}", "Regular", size),
ElementValueType::Quantity {
constraints,
lsb,
signed,
unit } => {
describe_quantity(constraints, lsb, signed, unit)
},
ElementValueType::String { variation } => format!("{}:{}", "String", variation),
ElementValueType::Table { values } => describe_table(values),
};
element_desc
}
fn describe_quantity(constraints: &[ConstraintRule], lsb: &LsbType, signed: &bool, unit: &str) -> String {
let mut quantity_desc: Vec<String> = vec![String::from("Quantity: ")];
if constraints.len() > 0 {
quantity_desc.push(String::from("Constraint(s): "))
}
for constraint in constraints {
let mut constraint_desc: String = match constraint.constraint_type {
ConstraintType::Less => format!("constraint, type: {}", "Less"),
ConstraintType::Great => format!("constraint, type: {}", "Great"),
ConstraintType::LessOrEqual => format!("constraint, type: {}", "LessOrEqual"),
ConstraintType::GreatOrEqual => format!("constraint, type: {}", "GreatOrEqual"),
};
let constraint_value: String = match constraint.value {
DataType::Integer { value } => format!(", value: {}", value),
};
constraint_desc.push_str(constraint_value.as_str());
quantity_desc.push(constraint_desc);
}
let lsb_desc = match lsb {
LsbType::Integer { value } => format!("Lsb type Integer: {}", value),
LsbType::Div { denominator, numerator } => {
let denomminator = match denominator {
DenominatorType::Pow { base, exponent } => format!("Denom base {}, exponent {}", base, exponent),
};
let numerator = match numerator {
DataType::Integer { value } => format!("Num {}", value),
};
format!("Lsb type Div, denominator {}, numerator {}", denomminator, numerator)
}
};
quantity_desc.push(lsb_desc);
quantity_desc.push(format!("Signed: {}", signed));
quantity_desc.push(format!("Unit: {}", unit));
quantity_desc.join("\n")
}
fn describe_integer(constraints: &[ConstraintRule], signed: &bool) -> String {
let mut integer_desc: Vec<String> = vec![String::from("Integer: ")];
if constraints.len() > 0 {
integer_desc.push(String::from("Constraint(s): "))
}
for constraint in constraints {
let mut constraint_desc: String = match constraint.constraint_type {
ConstraintType::Less => format!("constraint, type: {}", "Less"),
ConstraintType::Great => format!("constraint, type: {}", "Great"),
ConstraintType::LessOrEqual => format!("constraint, type: {}", "LessOrEqual"),
ConstraintType::GreatOrEqual => format!("constraint, type: {}", "GreatOrEqual"),
};
let constraint_value: String = match constraint.value {
DataType::Integer { value } => format!(", value: {}", value),
};
constraint_desc.push_str(constraint_value.as_str());
integer_desc.push(constraint_desc);
}
if *signed {
integer_desc.push("Signed: {}".to_owned());
}
integer_desc.join("\n")
}
fn describe_group(items: &Vec<Option<AttributeItem>>) -> String {
let mut description = vec!["Attributes: ".to_owned()];
for item in items {
match item {
Some(e) => { description.push(describe_attribute_item(e)); },
None => ()
}
}
description.join("\n")
}
fn describe_table(values: &Vec<(i32, String)>) -> String {
let mut description = vec!["Table values: ".to_owned()];
for item in values {
description.push(format!("{}:{}", item.0, item.1));
}
description.join("\n")
}
fn describe_compound(fspec: &Option<u8>, items: &Vec<Option<AttributeItem>>) -> String {
let mut description = vec!["Compound: ".to_owned()];
match fspec {
Some(v) => { description.push(format!("fspec: {:?}", v)); },
None => (),
}
for item in items {
let attribute_item = match item {
Some(a) => a,
None => continue,
};
let attribute_desc = match attribute_item {
AttributeItem::SpareEntry { length, spare } => {
if *spare
{
format!("Spare entry: length:{}", length)
}
else {
String::new()
}
},
AttributeItem::AttributeEntry(e) => describe_attribute_entry(&e),
};
description.push(attribute_desc);
}
description.join("\n")
}
fn describe_repetitive(rep: &ElementValueType, variation: &AttributeValueType) -> String {
let mut description = vec!["Repetitive: ".to_owned()];
let rep_desc = describe_element_type(rep);
description.push(format!("rep: {}", rep_desc));
let attribute_type_desc = describe_attribute_value_type(variation);
description.push(format!("variation: {}", attribute_type_desc));
description.join("\n")
}