refactor parser: rename error messages, add static variables with lazy_static

This commit is contained in:
Danila Gamkov 2025-01-23 16:43:29 +03:00
parent 1364ca85aa
commit b738243634
3 changed files with 169 additions and 55 deletions

90
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "android-tzdata" name = "android-tzdata"
version = "0.1.1" version = "0.1.1"
@ -74,7 +83,10 @@ dependencies = [
"byteorder", "byteorder",
"chrono", "chrono",
"clap", "clap",
"lazy_static",
"regex",
"strum", "strum",
"walkdir",
] ]
[[package]] [[package]]
@ -208,6 +220,15 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.169" version = "0.2.169"
@ -220,6 +241,12 @@ version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@ -253,18 +280,62 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.19" version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
@ -316,6 +387,16 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.100" version = "0.2.100"
@ -374,6 +455,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys",
]
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.52.0" version = "0.52.0"

View File

@ -8,3 +8,6 @@ byteorder = "1.4.3"
chrono = "0.4" chrono = "0.4"
strum = { version = "0.26", features = ["derive"] } strum = { version = "0.26", features = ["derive"] }
clap = "4.*" clap = "4.*"
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
regex = "1.7.0"
walkdir = "2.3.2"

View File

@ -6,6 +6,15 @@ pub mod asotr_data {
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use std::time::{SystemTime, UNIX_EPOCH, Duration}; use std::time::{SystemTime, UNIX_EPOCH, Duration};
use strum::FromRepr; use strum::FromRepr;
use lazy_static::lazy_static;
use std::path::PathBuf;
use regex::Regex;
use walkdir::WalkDir;
lazy_static! {
pub static ref support_dtypes: String =
String::from(".data01.asotr01(02), data02.asotr01(02), data06.asotr01(02)");
}
#[derive(Debug, FromRepr, PartialEq)] #[derive(Debug, FromRepr, PartialEq)]
enum AsotrDataType { enum AsotrDataType {
@ -55,56 +64,69 @@ pub mod asotr_data {
ch[i] = match data.read_u16::<LittleEndian>() { ch[i] = match data.read_u16::<LittleEndian>() {
Ok(val) => val, Ok(val) => val,
Err(msg) => { Err(msg) => {
return Err(format!("Error parsing file: failed parsing float32 data: {}", msg)); } return Err(format!("Error parsing file: failed parsing uint16 data: {}", msg)); }
} }
} }
return Ok(ch); return Ok(ch);
} }
fn parse_filename(filename_full: String) -> Result<AsotrDataDesc, String> {
fn parse_filename(filename_full: String) -> Result<(AsotrDataDesc, String), String> {
let mut filename = String::new(); let mut filename = String::new();
let msg_prev = format!("Error parsing filename {}:", filename_full);
match filename_full.rfind('/') { match filename_full.rfind('/') {
Some(val) => { filename = (filename_full[val+1..filename_full.len()]).to_string(); } Some(val) => { filename = (filename_full[val+1..filename_full.len()]).to_string(); }
_ => { filename = filename_full.clone(); } _ => { filename = filename_full.clone(); }
} }
if filename.len() != 32 { return Err(format!("Error parsing filename: Unsupported file ({})", filename)); } if filename.len() != 32 {
return Err(format!("{} unsupported file", msg_prev));
}
let time_unix_ = filename[0..10].parse::<u64>(); let time_unix_ = filename[0..10].parse::<u64>();
let time_unix = match &time_unix_ { let time_unix = match &time_unix_ {
Ok(data) => data, Ok(data) => data,
Err(msg) => { return Err(format!("Error parsing filename: expected digits in timestamp sec part ({})", msg)); } Err(msg) => {
return Err(format!("{} expected digits in timestamp sec part ({})",
msg_prev, msg));
}
}; };
let data_type_ = filename[22..24].parse::<u8>(); let data_type_ = filename[22..24].parse::<u8>();
let data_type_u8 = match &data_type_ { let data_type_u8 = match &data_type_ {
Ok(data) => data, Ok(data) => data,
Err(msg) => { return Err(format!("Error parsing filename: expected digits in data type part ({})", msg)); } Err(msg) => {
return Err(format!("{} expected digits in data type part ({})",
msg_prev, msg));
}
}; };
if *data_type_u8 == 1 || *data_type_u8 == 2 || *data_type_u8 == 6 { } if *data_type_u8 == 1 || *data_type_u8 == 2 || *data_type_u8 == 6 { }
else { else {
return Err("unsupported file type! Parser supports data types: .data01.asotr01(02), data02.asotr01(02), data06.asotr01(02)".to_string()); return Err(format!("{} parser supports data types: {}",
msg_prev, support_dtypes.to_string()));
} }
let data_type = match AsotrDataType::from_repr(*data_type_u8 as usize) { let data_type = match AsotrDataType::from_repr(*data_type_u8 as usize) {
Some(value) => value, Some(value) => value,
_ => return Err(format!("Error parsing filename d: expected digits in data type part")) _ => return Err(format!("{} expected digits in data type part",
msg_prev))
}; };
let _kit = filename[30..32].parse::<u8>(); let _kit = filename[30..32].parse::<u8>();
let kit = match &_kit { let kit = match &_kit {
Ok(data) => data, Ok(data) => data,
Err(msg) => { return Err(format!("Error parsing filename: expected digits in asotr kit part ({})", msg)); } Err(msg) => { return Err(format!("{}: expected digits in asotr kit part ({})",
msg_prev, msg)); }
}; };
let _time_str_mks = filename[11..17].parse::<u32>(); let _time_str_mks = filename[11..17].parse::<u32>();
let time_mks = match &_time_str_mks { let time_mks = match &_time_str_mks {
Ok(data) => data, Ok(data) => data,
Err(msg) => { return Err(format!("Error parsing filename: expected digits in timestamp mks part ({})", msg)); } Err(msg) => { return Err(format!("{}: expected digits in timestamp mks part ({})",
msg_prev, msg)); }
}; };
let time: SystemTime = UNIX_EPOCH + Duration::from_secs(*time_unix); let time: SystemTime = UNIX_EPOCH + Duration::from_secs(*time_unix);
@ -112,63 +134,62 @@ pub mod asotr_data {
let date_s = date_time.format("%d.%m.%Y").to_string(); let date_s = date_time.format("%d.%m.%Y").to_string();
let time_s = date_time.format("%H:%M:%S").to_string(); let time_s = date_time.format("%H:%M:%S").to_string();
let asotrDataHead = AsotrDataDesc::new(*time_unix, *time_mks, let head = AsotrDataDesc::new(*time_unix, *time_mks,
format!("{} {}", date_s, time_s), format!("{} {}", date_s, time_s),
date_s, time_s, data_type, *kit); date_s, time_s, data_type, *kit);
return Ok((asotrDataHead, filename)); return Ok(head);
} }
pub fn parse_data(filename_full: String) -> Result<String, String> { pub fn read_data(filename_full: String) -> Result<String, String> {
let ch_u16: [u16; 6]; let ch_u16: [u16; 6];
let ch_f32: [f32; 6]; let ch_f32: [f32; 6];
let (asotr_head, filename) = parse_filename(filename_full.clone())?; let asotr_head = parse_filename(filename_full.clone())?;
let mut buf = Vec::new(); let mut buf = Vec::new();
let mut out = String::new(); let mut out = String::new();
let mut data = match File::open(filename_full.clone())
{
Ok(file) => file,
Err(msg) => { return Err(format!("Error opening data file {}: {}", filename_full, msg)) }
};
let mut data = match File::open(filename_full.clone()) match data.read_to_end(&mut buf) {
{ Ok(stat) => stat,
Ok(file) => file, Err(msg) => { return Err(format!("Error reading data file {}: {}", filename_full, msg)) }
Err(msg) => { return Err(format!("Error opening data file {}: {}", filename, msg)) } };
};
match data.read_to_end(&mut buf) { out.push_str(&asotr_head.time_s.to_string());
Ok(stat) => stat, out.push(';');
Err(msg) => { return Err(format!("Error reading data file {}: {}", filename, msg)) } out.push_str(&asotr_head.date);
}; out.push(';');
out.push_str(&asotr_head.time);
out.push(';');
if asotr_head.data_type == AsotrDataType::Temp ||
out.push_str(&asotr_head.time_s.to_string()); asotr_head.data_type == AsotrDataType::TempSet {
out.push(';');
out.push_str(&asotr_head.date);
out.push(';');
out.push_str(&asotr_head.time);
out.push(';');
if asotr_head.data_type == AsotrDataType::Temp ||
asotr_head.data_type == AsotrDataType::TempSet {
ch_f32 = parse_data_f32(buf)?; ch_f32 = parse_data_f32(buf)?;
for elem in ch_f32 { for elem in ch_f32 {
out.push_str(&elem.to_string()); out.push_str(&elem.to_string());
out.push(';'); out.push(';');
} }
} }
else if asotr_head.data_type == AsotrDataType::Pow { else if asotr_head.data_type == AsotrDataType::Pow {
ch_u16 = parse_data_u16(buf)?; ch_u16 = parse_data_u16(buf)?;
for elem in ch_u16 { for elem in ch_u16 {
out.push_str(&elem.to_string()); out.push_str(&elem.to_string());
out.push(';'); out.push(';');
}
} }
}
out.remove(out.len() - 1); out.remove(out.len() - 1);
return Ok(out); return Ok(out);
} }
} }
@ -183,7 +204,7 @@ fn main() {
Arg::new("file") Arg::new("file")
.short('f') .short('f')
.long("filename") .long("filename")
.help("input ASOTR MVN data (.data01.asotr01(02), .data02.asotr01(02), .data06.asotr01(02))") .help(format!("input ASOTR MVN data ({})", support_dtypes.to_string()))
.required(true), .required(true),
) )
.get_matches(); .get_matches();
@ -193,9 +214,9 @@ fn main() {
_ => { println!("Error: wrong argument!"); return; } _ => { println!("Error: wrong argument!"); return; }
}; };
let s = match parse_data(filename.clone()) { let s = match read_data(filename.clone()) {
Ok(elem) => elem, Ok(elem) => elem,
Err(msg) => { println!("{}", msg); return; } Err(msg) => { println!("{}", msg); return; }
}; };
println!("{}", s); println!("{}", s);