diff --git a/Cargo.lock b/Cargo.lock index facedb5..7e43bc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 10b770d..237e18b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/main.rs b/src/main.rs index 681a2fb..a3eb72d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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::() { 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 { 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::(); 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::(); 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::(); 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::(); 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::::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 { + pub fn read_data(filename_full: String) -> Result { 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); }