From 788ea0219a69e44e8fd7512d4f323c6086523167 Mon Sep 17 00:00:00 2001 From: Gustav Eek Date: Mon, 6 Mar 2023 10:28:35 +0100 Subject: [PATCH] Sys. Refactor number parsing for length and readability "The rule of index of the longest match" is introduced also for bullet parsing. In finding longest index, the length vector middle step is removed for the benefit of iterator chaining. The *conf* templates are produced symmetrically between bullet and number patterns. Debug printing is reduced, concentrated and made symmetric. Finally, a bullet test is updated as a consequence of introducing the longest index rule for bullets. --- src/main.rs | 90 ++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/main.rs b/src/main.rs index 86fd7f1..35eaa64 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,60 +20,63 @@ fn winnow(mut list: Vec) -> (Conf, Vec ) { list.retain(|x| x != ""); // only keep nonempty // Search patterns + let bullet = Regex::new(r"^(\s*[\*-]\s*)").unwrap(); let number = Regex::new(r"^(\s*)([0-9]+)([).]\s*)").unwrap(); let prio = Regex::new(r"^\s*[0-9]+\s*%\s*").unwrap(); - // Use index of the longest second group match to create conf template - if DEBUG { - eprintln!( - "Match: '{}', '{}', '{}', '{}'", - match number.captures(&list[0]){None => "", Some(x) => x.get(0).unwrap().as_str()}, - match number.captures(&list[0]){None => "", Some(x) => x.get(1).unwrap().as_str()}, - match number.captures(&list[0]){None => "", Some(x) => x.get(2).unwrap().as_str()}, - match number.captures(&list[0]){None => "", Some(x) => x.get(3).unwrap().as_str()}, - ); - } + if DEBUG { eprintln!( // debug patterns + "Matches first item: '{}', '{}', '{}'", + match bullet.captures(&list[0]){ + None => "", + Some(x) => x.get(0).unwrap().as_str()}, + match number.captures(&list[0]){ + None => "", + Some(x) => x.get(0).unwrap().as_str()}, + match prio.captures(&list[0]){ + None => "", + Some(x) => x.get(0).unwrap().as_str()});} + + // Use index of the longest relevant group match to create conf + // template. Call this "the rule of index of the longest match". + + let maxi_bullet = list.iter().map( + |y| match bullet.captures(y) { + None => 0, + Some(x) => x.get(1).unwrap().as_str().len(), + }).enumerate().fold( + (0, 0), |max, (ind, val)| if val > max.1 {(ind, val)} else {max}).0; - let lens: Vec = list.iter().map( + let maxi_number = list.iter().map( |y| match number.captures(y) { None => 0, Some(x) => x.get(2).unwrap().as_str().len(), - }).collect(); - - let maxi = lens.iter().enumerate().fold( - (0, 0), - |max, (ind, &val)| if val > max.1 {(ind, val)} else {max}); - - let tmpl = match number.captures(&list[maxi.0]) { - None => "".to_string(), - Some(x) => { - if DEBUG { - eprintln!("Test matches '{}', '{}', '{}'", - x.get(1).unwrap().as_str(), - x.get(2).unwrap().as_str(), - x.get(3).unwrap().as_str()); - } - format!( - "{}{{}}{}", - x.get(1).unwrap().as_str(), - x.get(3).unwrap().as_str()) - }, - }; - - if DEBUG { - eprint!("Lens index {}, {}: ", maxi.0, maxi.1); - for n in lens {eprint!("{}, ", n);} - eprintln!("\x08\x08."); - eprintln!("Pattern: '{}'", tmpl); - } + }).enumerate().fold( + (0, 0), |max, (ind, val)| if val > max.1 {(ind, val)} else {max}).0; + + if DEBUG { eprintln!( // debug longest match + "Longest match: {}, '{}'; {}, '{}'", + maxi_bullet, + match bullet.captures(&list[maxi_bullet]) { + None => "", + Some(x) => x.get(1).unwrap().as_str()}, + maxi_number, + match number.captures(&list[maxi_number]) { + None => "", + Some(x) => x.get(2).unwrap().as_str()})}; let conf = Conf { - bullet: match bullet.captures(&list[0]) { + bullet: match bullet.captures(&list[maxi_bullet]) { None => "".to_string(), Some(x) => x.get(1).unwrap().as_str().to_string(), }, - number: tmpl, + number: match number.captures(&list[maxi_number]) { + None => "".to_string(), + Some(x) => format!( + "{}{{}}{}", + x.get(1).unwrap().as_str(), + x.get(3).unwrap().as_str()) + }, }; if DEBUG { @@ -81,6 +84,7 @@ fn winnow(mut list: Vec) -> (Conf, Vec ) { } // Remove patterns and trim + for l in &mut *list { *l = bullet.replace_all(&l, "").to_string(); *l = number.replace_all(&l, "").to_string(); @@ -298,7 +302,7 @@ fn bullets() { .split("\n").map(|x| x.to_owned()).collect(); let (conf, res) = winnow(arg); assert_eq!(exp, res); - assert_eq!(conf.bullet, " * ".to_owned()); + assert_eq!(conf.bullet, " - ".to_owned()); assert_eq!(conf.number, "".to_owned()); } @@ -307,7 +311,7 @@ fn bullets() { fn numbers() { let arg: Vec = - "1. Hej du\n 459. glade\n 2)ta en\n" + "1) Hej du\n 459. glade\n 2)ta en\n" .split("\n").map(|x| x.to_owned()) .collect(); let exp: Vec = -- 2.39.2