diff --git a/src/cmd_line.rs b/src/cmd_line.rs index 0770d5f..e7f6d55 100644 --- a/src/cmd_line.rs +++ b/src/cmd_line.rs @@ -184,49 +184,52 @@ fn parse_cmd_line_args() -> anyhow::Result { } -fn print_progress(done: usize, total: usize, real_start: Instant, - eta_start: Instant) +fn print_editing_status(done: usize, total: usize, real_start: Instant, + eta_start: Instant, show_progress: bool) { - let progress = match total { - 0 => 0.0, - _ => done as f32 / total as f32 - }; - let now = Instant::now(); let real_elapsed = now.duration_since(real_start); - let eta_elapsed = now.duration_since(eta_start); - let remaining = if progress >= 0.1 { - Some(Duration::from_secs_f32( - eta_elapsed.as_secs_f32() / progress * (1.0 - progress) - )) - } else { - None - }; + if show_progress { + let eta_elapsed = now.duration_since(eta_start); + let progress = match total { + 0 => 0., + _ => done as f32 / total as f32 + }; - const TOTAL_BARS: usize = 25; - let num_bars = (progress * TOTAL_BARS as f32) as usize; - let bars = "=".repeat(num_bars); - - eprint!( - "\r[{bars:= 0.1 { + Some(Duration::from_secs_f32( + eta_elapsed.as_secs_f32() / progress * (1. - progress) + )) } else { - String::from("--:--") - } - ); + None + }; + + const TOTAL_BARS: usize = 25; + let num_bars = (progress * TOTAL_BARS as f32) as usize; + let bars = "=".repeat(num_bars); + + eprint!( + "\r[{bars: { - let time = fmt_duration(start.elapsed()); - inst.status.log_info(format!("Completed vacuum in {}.", time)); + inst.status.log_info(format!("Completed vacuum.")); }, Err(e) => inst.status.log_error(format!("Vacuum failed: {}.", e)) } @@ -24,7 +24,7 @@ pub fn get_command() -> Command { Command { func: vacuum, verify_args: None, - args: vec![], - help: "Rebuild map database to reduce its size" + args: Vec::new(), + help: "Rebuild map database to reduce its size." } } diff --git a/src/instance.rs b/src/instance.rs index aa28450..2e6a80e 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -58,6 +58,7 @@ pub enum InstState { #[derive(Clone)] pub struct InstStatus { + pub show_progress: bool, pub blocks_total: usize, pub blocks_done: usize, pub state: InstState @@ -66,6 +67,7 @@ pub struct InstStatus { impl InstStatus { fn new() -> Self { Self { + show_progress: true, blocks_total: 0, blocks_done: 0, state: InstState::Ignore @@ -115,6 +117,10 @@ impl StatusServer { self.status.lock().unwrap().blocks_done += 1; } + pub fn set_show_progress(&self, sp: bool) { + self.status.lock().unwrap().show_progress = sp; + } + pub fn begin_editing(&self) { self.set_state(InstState::Editing); } diff --git a/src/utils.rs b/src/utils.rs index 2eaf4b0..574ccd9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -12,7 +12,7 @@ pub fn query_keys( db: &mut MapDatabase, status: &StatusServer, // TODO: Allow multiple names for setmetavar and replaceininv. - search_str: Option<&[u8]>, + search_strs: Vec<&Vec>, area: Option, invert: bool, include_partial: bool @@ -21,15 +21,15 @@ pub fn query_keys( // Prepend 16-bit search string length to reduce false positives. // This will break if the name-ID map format changes. - let search_bytes = search_str.map(|s| { + let string16s: Vec> = search_strs.iter().map(|&s| { let mut res = Vec::new(); res.write_u16::(s.len() as u16).unwrap(); res.extend(s); res - }); - let data_searcher = search_bytes.as_ref().map(|b| { + }).collect(); + let data_searchers: Vec = string16s.iter().map(|b| { TwoWaySearcher::new(b) - }); + }).collect(); let mut keys = Vec::new(); // Area of included block positions. @@ -49,8 +49,9 @@ pub fn query_keys( continue; } } - if let Some(s) = &data_searcher { - if s.search_in(&data).is_none() { + if !data_searchers.is_empty() { + // Data must match at least one search string. + if data_searchers.iter().any(|s| s.search_in(&data).is_some()) { continue; } } @@ -91,13 +92,13 @@ pub fn fmt_duration(dur: Duration) -> String { pub fn fmt_big_num(num: u64) -> String { let f_num = num as f32; - let abbrevs = vec![ - ("T".to_string(), 1_000_000_000_000.), - ("B".to_string(), 1_000_000_000.), - ("M".to_string(), 1_000_000.), - ("k".to_string(), 1_000.) + const ABBREVS: [(&str, f32); 4] = [ + ("T", 1_000_000_000_000.), + ("B", 1_000_000_000.), + ("M", 1_000_000.), + ("k", 1_000.) ]; - for (suffix, unit) in abbrevs { + for &(suffix, unit) in &ABBREVS { if f_num >= unit { let mantissa = f_num / unit; let place_vals = @@ -109,3 +110,28 @@ pub fn fmt_big_num(num: u64) -> String { } format!("{}", f_num.round()) } + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_nums() { + let pairs = [ + (0, "0"), + (3, "3"), + (42, "42"), + (999, "999"), + (1_000, "1.00k"), + (33_870, "33.9k"), + (470_999, "471k"), + (555_678_000, "556M"), + (1_672_234_000, "1.67B"), + (77_864_672_234_000, "77.9T"), + ]; + for pair in &pairs { + assert_eq!(fmt_big_num(pair.0), pair.1.to_string()); + } + } +}