pub mod utils; use serde::{Deserialize, Serialize}; use serde_xml_rs::from_reader; use std::{collections::HashMap, fs::File, io::Read, str::FromStr}; use utils::{ generate_mock_data::generate_mock_data_file, parse_field_bytes, DataTypesCast, RecordDescs, }; use crate::utils::DataTypes; // DataTypesCast is generated by the TypeCast derive macro in the examples/utils/mod.rs file. Rust-Analyzer mistakenly classifies this as an `unresolved import` #[derive(Clone, Debug, Default, Serialize, Deserialize)] struct DataRecord { fields: HashMap, } impl DataRecord { pub fn set_field(&mut self, name: &str, value: DataTypesCast) { self.fields.insert(name.to_string(), value); } } fn parse_records(record_descs: RecordDescs, data: &mut &[u8]) -> DataRecord { let mut data_record = DataRecord::default(); for record_description in record_descs.record_desc { let data_type = record_description.data_type; let (tail, mut bytes) = parse_field_bytes(data, &record_description.length).unwrap(); match record_description.number { 1 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 2 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 3 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 4 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 5 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 6 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 7 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 8 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } 9 => { data_record.set_field( record_description.name.as_str(), data_type.parse(&mut bytes), ); } // Add more cases for other record numbers if needed _ => (), } // Move the data slice pointer to the next record *data = tail; // You can now access the data_record fields here and perform the desired operations } return data_record; } fn main() { let directory = "./data/"; let file_name = "data.dat"; let file_path = format!("{}/{}", directory, file_name); generate_mock_data_file(directory, file_name); // Read the XML file let mut xml_file = File::open("./data/desc.xml").expect("Unable to open the file"); let mut contents = String::new(); xml_file .read_to_string(&mut contents) .expect("Unable to read the file"); let record_descs: RecordDescs = from_reader(contents.as_bytes()).unwrap(); // Read the binary data file let file_contents = std::fs::read(&file_path).expect("Unable to read file"); let mut data: &[u8] = &file_contents; let data_record = parse_records(record_descs, &mut data); println!("\nParsed Values into DataTypesCast Enum:"); for (name, value) in &data_record.fields { let formatted_name = format!("{:<15}", name); println!("\t{:?}: {:?}", formatted_name, value); } println!("\nValue Extraction with match:"); for (name, value) in &data_record.fields { let formatted_name = format!("{:<15}", name); match value { DataTypesCast::IEEE754LSBSingle(val) => println!("\t{:<15}: {:?}", name, val), DataTypesCast::IEEE754LSBDouble(val) => println!("\t{:<15}:{:?}", name, val), DataTypesCast::IEEE754LSBSingleArr2(val) => { println!("\t{:<15}:{:?}", formatted_name, val) } DataTypesCast::IEEE754LSBDoubleArr2(val) => { println!("\t{:<15}:{:?}", formatted_name, val) } DataTypesCast::IEEE754MSBSingleArr2(val) => { println!("\t{:<15}:{:?}", formatted_name, val) } DataTypesCast::IEEE754MSBDoubleArr2(val) => { println!("\t{:<15}:{:?}", formatted_name, val) } DataTypesCast::IEEE754LSBSingleArr3(val) => { println!("\t{:<15}:{:?}", formatted_name, val) } DataTypesCast::IEEE754LSBDoubleArr3(val) => { println!("\t{:<15}:{:?}", formatted_name, val) } DataTypesCast::ASCIIString(val) => println!("\t{:<15}:{:?}", formatted_name, val), } } println!("\nIndividual Value Extraction With TryInto:"); let single_val_into: f32 = data_record .fields .get("Single") .unwrap() .clone() .try_into() .unwrap(); println!("\t{:<15}: {}", "Single", single_val_into); let double_val_into: f64 = data_record .fields .get("Double") .unwrap() .clone() .try_into() .unwrap(); println!("\t{:<15}: {}", "Double", double_val_into); let single_arr_val_into: [f32; 2] = data_record .fields .get("SingleArr") .unwrap() .clone() .try_into() .unwrap(); println!( "\t{:<15}: [{}, {}]", "SingleArr", single_arr_val_into[0], single_arr_val_into[1] ); let double_arr_val_into: [f64; 2] = data_record .fields .get("DoubleArr") .unwrap() .clone() .try_into() .unwrap(); println!( "\t{:<15}: [{}, {}]", "DoubleArr", double_arr_val_into[0], double_arr_val_into[1] ); let msb_single_arr_val_into: [f32; 2] = data_record .fields .get("MSBSingleArr") .unwrap() .clone() .try_into() .unwrap(); println!( "\t{:<15}: [{:?}, {:?}]", "MSBSingleArr", msb_single_arr_val_into[0], msb_single_arr_val_into[1] ); let msb_double_arr_val_into: [f64; 2] = data_record .fields .get("MSBDoubleArr") .unwrap() .clone() .try_into() .unwrap(); println!( "\t{:<15}: [{:?}, {:?}]", "MSBDoubleArr", msb_double_arr_val_into[0], msb_double_arr_val_into[1] ); let lsb_single_arr_3_val_into: [f32; 3] = data_record .fields .get("LSBSingleArr3") .unwrap() .clone() .try_into() .unwrap(); println!( "\t{:<15}: [{:?}, {:?}, {:?}]", "LSBSingleArr3", lsb_single_arr_3_val_into[0], lsb_single_arr_3_val_into[1], lsb_single_arr_3_val_into[2] ); let lsb_double_arr_3_val_into: [f64; 3] = data_record .fields .get("LSBDoubleArr3") .unwrap() .clone() .try_into() .unwrap(); println!( "\t{:<15}: [{:?}, {:?}, {:?}]", "LSBDoubleArr3", lsb_double_arr_3_val_into[0], lsb_double_arr_3_val_into[1], lsb_double_arr_3_val_into[2] ); let ascii_string_val_into: String = data_record .fields .get("ASCIIString") .unwrap() .clone() .try_into() .unwrap(); println!("\t{:<15}: {}", "ASCIIString", ascii_string_val_into); println!("\nConvert Str Representations into DataTypes using from_str\n"); let data_types_IEEE754LSBSingle_from_str = DataTypes::from_str("IEEE754LSBSingle"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754LSBSingle\")", data_types_IEEE754LSBSingle_from_str.unwrap() ); let data_types_IEEE754LSBDouble_from_str = DataTypes::from_str("IEEE754LSBDouble"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754LSBDouble\")", data_types_IEEE754LSBDouble_from_str.unwrap() ); println!("\n"); let data_types_IEEE754LSBSingleArr2_from_str = DataTypes::from_str("IEEE754LSBSingleArr2"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754LSBSingleArr2\")", data_types_IEEE754LSBSingleArr2_from_str.unwrap() ); let data_types_IEEE754LSBDoubleArr2_from_str = DataTypes::from_str("IEEE754LSBDoubleArr2"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754LSBDoubleArr2\")", data_types_IEEE754LSBDoubleArr2_from_str.unwrap() ); println!("\n"); let data_types_IEEE754MSBSingleArr2_from_str = DataTypes::from_str("IEEE754MSBSingleArr2"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754MSBSingleArr2\")", data_types_IEEE754MSBSingleArr2_from_str.unwrap() ); let data_types_IEEE754MSBDoubleArr2_from_str = DataTypes::from_str("IEEE754MSBDoubleArr2"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754MSBDoubleArr2\")", data_types_IEEE754MSBDoubleArr2_from_str.unwrap() ); println!("\n"); let data_types_IEEE754LSBSingleArr3_from_str = DataTypes::from_str("IEEE754LSBSingleArr3"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754LSBSingleArr3\")", data_types_IEEE754LSBSingleArr3_from_str.unwrap() ); let data_types_IEEE754LSBDoubleArr3_from_str = DataTypes::from_str("IEEE754LSBDoubleArr3"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"IEEE754LSBDoubleArr3\")", data_types_IEEE754LSBDoubleArr3_from_str.unwrap() ); println!("\n"); let data_types_ASCIIString_from_str = DataTypes::from_str("ASCIIString"); println!( "\t{:<44}:\t{:?}", "DataType::from_str(\"ASCIIString\")", data_types_ASCIIString_from_str.unwrap() ); }