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.
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]]
name = "android-tzdata"
version = "0.1.1"
@ -74,7 +83,10 @@ dependencies = [
"byteorder",
"chrono",
"clap",
"lazy_static",
"regex",
"strum",
"walkdir",
]
[[package]]
@ -208,6 +220,15 @@ dependencies = [
"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]]
name = "libc"
version = "0.2.169"
@ -220,6 +241,12 @@ version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "num-traits"
version = "0.2.19"
@ -253,18 +280,62 @@ dependencies = [
"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]]
name = "rustversion"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "strsim"
version = "0.11.1"
@ -316,6 +387,16 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "wasm-bindgen"
version = "0.2.100"
@ -374,6 +455,15 @@ dependencies = [
"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]]
name = "windows-core"
version = "0.52.0"

View File

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

View File

@ -6,7 +6,16 @@ pub mod asotr_data {
use chrono::{DateTime, Utc};
use std::time::{SystemTime, UNIX_EPOCH, Duration};
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)]
enum AsotrDataType {
Temp = 1,
@ -23,7 +32,7 @@ pub mod asotr_data {
data_type: AsotrDataType,
kit: u8,
}
impl AsotrDataDesc {
pub fn new(time_s: u64, time_mks: u32,
datetime: String, date: String, time: String,
@ -55,120 +64,132 @@ pub mod asotr_data {
ch[i] = match data.read_u16::<LittleEndian>() {
Ok(val) => val,
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);
}
fn parse_filename(filename_full: String) -> Result<(AsotrDataDesc, String), String> {
fn parse_filename(filename_full: String) -> Result<AsotrDataDesc, String> {
let mut filename = String::new();
let msg_prev = format!("Error parsing filename {}:", filename_full);
match filename_full.rfind('/') {
Some(val) => { filename = (filename_full[val+1..filename_full.len()]).to_string(); }
_ => { 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 = match &time_unix_ {
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_u8 = match &data_type_ {
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 { }
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) {
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 = match &_kit {
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_mks = match &_time_str_mks {
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 date_time = DateTime::<Utc>::from(time);
let date_s = date_time.format("%d.%m.%Y").to_string();
let time_s = date_time.format("%H:%M:%S").to_string();
let asotrDataHead = AsotrDataDesc::new(*time_unix, *time_mks,
format!("{} {}", date_s, time_s),
date_s, time_s, data_type, *kit);
let head = AsotrDataDesc::new(*time_unix, *time_mks,
format!("{} {}", date_s, time_s),
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_f32: [f32; 6];
let (asotr_head, filename) = parse_filename(filename_full.clone())?;
let mut buf = Vec::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, msg)) }
};
let asotr_head = parse_filename(filename_full.clone())?;
match data.read_to_end(&mut buf) {
Ok(stat) => stat,
Err(msg) => { return Err(format!("Error reading data file {}: {}", filename, msg)) }
};
let mut buf = Vec::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)) }
};
out.push_str(&asotr_head.time_s.to_string());
out.push(';');
out.push_str(&asotr_head.date);
out.push(';');
out.push_str(&asotr_head.time);
out.push(';');
match data.read_to_end(&mut buf) {
Ok(stat) => stat,
Err(msg) => { return Err(format!("Error reading data file {}: {}", filename_full, msg)) }
};
if asotr_head.data_type == AsotrDataType::Temp ||
asotr_head.data_type == AsotrDataType::TempSet {
out.push_str(&asotr_head.time_s.to_string());
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)?;
for elem in ch_f32 {
out.push_str(&elem.to_string());
out.push(';');
}
}
else if asotr_head.data_type == AsotrDataType::Pow {
ch_u16 = parse_data_u16(buf)?;
for elem in ch_u16 {
out.push_str(&elem.to_string());
out.push(';');
}
else if asotr_head.data_type == AsotrDataType::Pow {
ch_u16 = parse_data_u16(buf)?;
for elem in ch_u16 {
out.push_str(&elem.to_string());
out.push(';');
}
out.remove(out.len() - 1);
}
return Ok(out);
out.remove(out.len() - 1);
return Ok(out);
}
}
@ -183,7 +204,7 @@ fn main() {
Arg::new("file")
.short('f')
.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),
)
.get_matches();
@ -193,11 +214,11 @@ fn main() {
_ => { println!("Error: wrong argument!"); return; }
};
let s = match parse_data(filename.clone()) {
Ok(elem) => elem,
Err(msg) => { println!("{}", msg); return; }
let s = match read_data(filename.clone()) {
Ok(elem) => elem,
Err(msg) => { println!("{}", msg); return; }
};
println!("{}", s);
}