diff --git a/src/helper.rs b/src/helper.rs index d0321f3..5d1507f 100644 --- a/src/helper.rs +++ b/src/helper.rs @@ -1329,7 +1329,7 @@ impl PubP2poolApi { let mut sum: f64 = 0.0; let mut count: u128 = 0; for i in iter { - if let Some(word) = regex.float.find(i.as_str()) { + if let Some(word) = regex.payout_float.find(i.as_str()) { match word.as_str().parse::() { Ok(num) => { sum += num; count += 1; }, Err(e) => error!("P2Pool | Total XMR sum calculation error: [{}]", e), diff --git a/src/macros.rs b/src/macros.rs index 133aab5..3d0732c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -17,22 +17,22 @@ // These are general QoL macros, nothing too scary, I promise. // -// | MACRO | PURPOSE | EQUIVALENT CODE | -// |---------|----------------------------------------------|------------------------------------------------------------| -// | lock | Lock an [Arc] | a.lock().unwrap() | -// | lock2 | Lock a field inside a struct, both Arc] | std::sync::Arc::new(std::sync::Mutex::new(my_value)) | -// | sleep | Sleep the current thread for x milliseconds | std::thread::sleep(std::time::Duration::from_millis(1000)) | -// | flip | Flip a bool in place | my_bool = !my_bool | +// | MACRO | PURPOSE | EQUIVALENT CODE | +// |---------|-----------------------------------------------|------------------------------------------------------------| +// | lock | Lock an [Arc] | a.lock().unwrap() | +// | lock2 | Lock a field inside a struct, both Arc | a.lock().unwrap().b.lock().unwrap() | +// | arc_mut | Create a new [Arc] | std::sync::Arc::new(std::sync::Mutex::new(my_value)) | +// | sleep | Sleep the current thread for x milliseconds | std::thread::sleep(std::time::Duration::from_millis(1000)) | +// | flip | Flip a bool in place | my_bool = !my_bool | // // Hopefully the long ass code on the right justifies usage of macros :D // // [lock2!()] works like this: "lock2!(my_first, my_second)" // and expects it be a [Struct]-[field] relationship, e.g: // -// let my_first = Struct { +// let my_first = Arc::new(Mutex::new(Struct { // my_second: Arc::new(Mutex::new(true)), -// }; +// })); // lock2!(my_first, my_second); // // The equivalent code is: "my_first.lock().unwrap().my_second.lock().unwrap()" (see? this is long as hell) @@ -45,14 +45,6 @@ macro_rules! lock { } pub(crate) use lock; -// Creates a new [Arc] -macro_rules! arc_mut { - ($arc_mutex:expr) => { - std::sync::Arc::new(std::sync::Mutex::new($arc_mutex)) - }; -} -pub(crate) use arc_mut; - // Locks and unwraps a field of a struct, both of them being [Arc] // Yes, I know this is bad code. macro_rules! lock2 { @@ -62,6 +54,14 @@ macro_rules! lock2 { } pub(crate) use lock2; +// Creates a new [Arc] +macro_rules! arc_mut { + ($arc_mutex:expr) => { + std::sync::Arc::new(std::sync::Mutex::new($arc_mutex)) + }; +} +pub(crate) use arc_mut; + // Sleeps a [std::thread] using milliseconds macro_rules! sleep { ($millis:expr) => { @@ -72,11 +72,11 @@ pub(crate) use sleep; // Flips a [bool] in place macro_rules! flip { - ($b:expr) => { - match $b { - true|false => $b = !$b, - }; - }; + ($b:expr) => { + match $b { + true|false => $b = !$b, + } + }; } pub(crate) use flip; diff --git a/src/main.rs b/src/main.rs index dd01745..d1797c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1326,7 +1326,7 @@ impl eframe::App for App { } } let color = if hide { BLACK } else { BRIGHT_YELLOW }; - if ui.add_sized([box_width, height], Button::new(RichText::new("👁").color(color))).on_hover_text(PASSWORD_HIDE).clicked() { flip!(sudo.hide) } + if ui.add_sized([box_width, height], Button::new(RichText::new("👁").color(color))).on_hover_text(PASSWORD_HIDE).clicked() { flip!(sudo.hide); } }); if (key.is_esc() && !sudo.testing) || ui.add_sized([width, height*4.0], Button::new("Leave")).on_hover_text(PASSWORD_LEAVE).clicked() { self.error_state.reset(); }; // If [test_sudo()] finished, reset error state. diff --git a/src/regex.rs b/src/regex.rs index 0a09f36..8bb802c 100644 --- a/src/regex.rs +++ b/src/regex.rs @@ -69,21 +69,56 @@ impl Regexes { // Both are nominally fast enough where it doesn't matter too much but meh, why not use regex. #[derive(Clone,Debug)] pub struct P2poolRegex { - pub payout: regex::Regex, - pub float: regex::Regex, pub date: regex::Regex, + pub payout: regex::Regex, + pub payout_float: regex::Regex, pub block: regex::Regex, - pub int: regex::Regex, + pub block_int: regex::Regex, } impl P2poolRegex { pub fn new() -> Self { Self { - payout: regex::Regex::new("payout of [0-9].[0-9]+ XMR").unwrap(), - float: regex::Regex::new("[0-9].[0-9]+").unwrap(), date: regex::Regex::new("[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+.[0-9]+").unwrap(), - block: regex::Regex::new("block [0-9]+").unwrap(), - int: regex::Regex::new("[0-9]+").unwrap(), + payout: regex::Regex::new("payout of [0-9].[0-9]+ XMR").unwrap(), // Assumes 12 digits after the dot. + payout_float: regex::Regex::new("[0-9].[0-9]{12}").unwrap(), // Assumes 12 digits after the dot. + block: regex::Regex::new("block [0-9]{7}").unwrap(), // Monero blocks will be 7 digits for... the next 10,379 years + block_int: regex::Regex::new("[0-9]{7}").unwrap(), } } } + +//---------------------------------------------------------------------------------------------------- TESTS +#[cfg(test)] +mod test { + #[test] + fn build_regexes() { + use regex::Regex; + let r = crate::Regexes::new(); + assert!(Regex::is_match(&r.name, "_this_ is... a n-a-m-e.")); + assert!(Regex::is_match(&r.address, "44hintoFpuo3ugKfcqJvh5BmrsTRpnTasJmetKC4VXCt6QDtbHVuixdTtsm6Ptp7Y8haXnJ6j8Gj2dra8CKy5ewz7Vi9CYW")); + assert!(Regex::is_match(&r.ipv4, "192.168.1.2")); + assert!(Regex::is_match(&r.ipv4, "127.0.0.1")); + assert!(Regex::is_match(&r.domain, "my.node.com")); + assert!(Regex::is_match(&r.domain, "my.monero-node123.net")); + assert!(Regex::is_match(&r.domain, "www.my-node.org")); + assert!(Regex::is_match(&r.domain, "www.my-monero-node123.io")); + for i in 1..=65535 { + assert!(Regex::is_match(&r.port, &i.to_string())); + } + assert!(!Regex::is_match(&r.port, "0")); + assert!(!Regex::is_match(&r.port, "65536")); + } + + #[test] + fn build_p2pool_regex() { + use regex::Regex; + let r = crate::P2poolRegex::new(); + let text = "NOTICE 2022-11-11 11:11:11.1111 P2Pool You received a payout of 0.111111111111 XMR in block 1111111"; + assert_eq!(r.payout.find(text).unwrap().as_str(), "payout of 0.111111111111 XMR"); + assert_eq!(r.payout_float.find(text).unwrap().as_str(), "0.111111111111"); + assert_eq!(r.date.find(text).unwrap().as_str(), "2022-11-11 11:11:11.1111"); + assert_eq!(r.block.find(text).unwrap().as_str(), "block 1111111"); + assert_eq!(r.block_int.find(text).unwrap().as_str(), "1111111"); + } +} diff --git a/src/xmr.rs b/src/xmr.rs index a2d5cd3..18b1711 100644 --- a/src/xmr.rs +++ b/src/xmr.rs @@ -127,7 +127,7 @@ impl PayoutOrd { }; // AtomicUnit let atomic_unit = if let Some(word) = regex.payout.find(line) { - if let Some(word) = regex.float.find(word.as_str()) { + if let Some(word) = regex.payout_float.find(word.as_str()) { match word.as_str().parse::() { Ok(au) => AtomicUnit::from_f64(au), Err(e) => { error!("P2Pool | AtomicUnit parse error: [{}] on [{}]", e, line); AtomicUnit::new() }, @@ -140,7 +140,7 @@ impl PayoutOrd { }; // Block let block = if let Some(word) = regex.block.find(line) { - if let Some(word) = regex.int.find(word.as_str()) { + if let Some(word) = regex.block_int.find(word.as_str()) { match word.as_str().parse::() { Ok(b) => HumanNumber::from_u64(b), Err(e) => { error!("P2Pool | Block parse error: [{}] on [{}]", e, line); HumanNumber::unknown() }, @@ -225,18 +225,18 @@ mod test { fn update_p2pool_payout_log() { use crate::xmr::PayoutOrd; let log = -r#"NOTICE 2021-12-21 01:01:01.1111 P2Pool You received a payout of 0.001000000000 XMR in block 1 -NOTICE 2021-12-21 02:01:01.1111 P2Pool You received a payout of 0.002000000000 XMR in block 2 -NOTICE 2021-12-21 03:01:01.1111 P2Pool You received a payout of 0.003000000000 XMR in block 3 +r#"NOTICE 2021-12-21 01:01:01.1111 P2Pool You received a payout of 0.001000000000 XMR in block 1234567 +NOTICE 2021-12-21 02:01:01.1111 P2Pool You received a payout of 0.002000000000 XMR in block 2345678 +NOTICE 2021-12-21 03:01:01.1111 P2Pool You received a payout of 0.003000000000 XMR in block 3456789 "#; let mut payout_ord = PayoutOrd::new(); println!("BEFORE: {}", payout_ord); PayoutOrd::update_from_payout_log(&mut payout_ord, log); println!("AFTER: {}", payout_ord); let should_be = -r#"2021-12-21 01:01:01.1111 | 0.001000000000 XMR | Block 1 -2021-12-21 02:01:01.1111 | 0.002000000000 XMR | Block 2 -2021-12-21 03:01:01.1111 | 0.003000000000 XMR | Block 3 +r#"2021-12-21 01:01:01.1111 | 0.001000000000 XMR | Block 1,234,567 +2021-12-21 02:01:01.1111 | 0.002000000000 XMR | Block 2,345,678 +2021-12-21 03:01:01.1111 | 0.003000000000 XMR | Block 3,456,789 "#; assert_eq!(payout_ord.to_string(), should_be) }