From 2e2fdb200d17c9d7d303457d3fc3e287d22744d7 Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Sun, 6 Mar 2022 21:29:15 -0500 Subject: [PATCH] Use a BTreeSet of hashesh instead of a HashMap of unit --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + README.adoc | 2 -- src/main.rs | 21 +++++++++++---------- src/uniq.rs | 25 ++++++++++++------------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9f28d7..507279d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,12 @@ dependencies = [ "syn", ] +[[package]] +name = "evalexpr" +version = "7.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90c8b61e4acbb2e4fbcf9d4c7af4d431f38c2a60b975b1d03d0276fbb032ec5d" + [[package]] name = "getrandom" version = "0.2.4" @@ -124,6 +130,7 @@ version = "0.1.0" dependencies = [ "alphanumeric-sort", "clap", + "evalexpr", "rand", "regex", "shellwords", diff --git a/Cargo.toml b/Cargo.toml index 3477dde..1ca20af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ clap = {version = "3", features = ["derive", "env"]} alphanumeric-sort = "1" shellwords = "1" rand = "0.8" +evalexpr = "7" [profile.release] lto = true diff --git a/README.adoc b/README.adoc index ef1f589..b0aa03e 100644 --- a/README.adoc +++ b/README.adoc @@ -43,12 +43,10 @@ define-command sort-selections -params 0.. %{ regex="${1:-.*}" # use kak_command_fifo kak_response_fifo; ~/syncthing/code/kakutils-rs/target/debug/kakutils-rs sort "$regex" -- "$@" - } exec R } } - ---- == Usage diff --git a/src/main.rs b/src/main.rs index 35d540b..9d307d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ mod uniq; use clap::{Parser, Subcommand}; use errors::KakMessage; use std::{ + convert::Into, env, fs, fs::{File, OpenOptions}, io::Write, @@ -168,7 +169,7 @@ fn run() -> Result { pub fn kak_exec(cmd: &str) -> Result<(), KakMessage> { let mut f = open_command_fifo()?; - write!(f, "{}", cmd).map_err(|e| e.into()) + write!(f, "{}", cmd).map_err(Into::into) } pub fn kak_response(msg: &str) -> Result, KakMessage> { @@ -187,7 +188,7 @@ pub fn open_command_fifo() -> Result { .write(true) .append(true) .open(&get_var("kak_command_fifo")?) - .map_err(|e| e.into()) + .map_err(Into::into) } pub fn get_var(var_name: &str) -> Result { @@ -229,13 +230,13 @@ mod test { #[test] fn test_contains() { assert_true!(sd.contains(sd)); - assert_false!(sd.contains(SelectionDesc::from_str("17.9,10.1").unwrap())) - assert_false!(sd.contains(SelectionDesc::from_str("18.8,10.1").unwrap())) - assert_false!(sd.contains(SelectionDesc::from_str("18.9,11.1").unwrap())) - assert_false!(sd.contains(SelectionDesc::from_str("18.9,10.2").unwrap())) - assert_true!(sd.contains(SelectionDesc::from_str("19.9,10.1").unwrap())) - assert_true!(sd.contains(SelectionDesc::from_str("18.10,10.1").unwrap())) - assert_true!(sd.contains(SelectionDesc::from_str("18.9,9.1").unwrap())) - assert_true!(sd.contains(SelectionDesc::from_str("18.9,10.0").unwrap())) + assert_false!(sd.contains(SelectionDesc::from_str("17.9,10.1").unwrap())); + assert_false!(sd.contains(SelectionDesc::from_str("18.8,10.1").unwrap())); + assert_false!(sd.contains(SelectionDesc::from_str("18.9,11.1").unwrap())); + assert_false!(sd.contains(SelectionDesc::from_str("18.9,10.2").unwrap())); + assert_true!(sd.contains(SelectionDesc::from_str("19.9,10.1").unwrap())); + assert_true!(sd.contains(SelectionDesc::from_str("18.10,10.1").unwrap())); + assert_true!(sd.contains(SelectionDesc::from_str("18.9,9.1").unwrap())); + assert_true!(sd.contains(SelectionDesc::from_str("18.9,10.0").unwrap())); } } diff --git a/src/uniq.rs b/src/uniq.rs index 32a914a..c77f5b6 100644 --- a/src/uniq.rs +++ b/src/uniq.rs @@ -1,6 +1,7 @@ use crate::{kak_response, open_command_fifo, KakMessage}; use std::{ - collections::{hash_map::Entry, HashMap}, + collections::{hash_map::DefaultHasher, BTreeSet}, + hash::{Hash, Hasher}, io::Write, }; #[derive(clap::StructOpt, Debug)] @@ -17,7 +18,7 @@ pub fn uniq(options: &Options) -> Result { let mut f = open_command_fifo()?; write!(f, "reg '\"'")?; - for i in selections.iter().scan(HashMap::new(), |state, s| { + for i in selections.iter().scan(BTreeSet::new(), |state, s| { let key = if options.no_skip_whitespace { s } else { @@ -31,18 +32,16 @@ pub fn uniq(options: &Options) -> Result { key.to_string() }; - let ret = match state.entry(key) { - Entry::Vacant(e) => { - e.insert(()); - s - } - Entry::Occupied(_) => { - // We've seen this selection before, so empty it - "" - } - }; + let mut hasher = DefaultHasher::new(); + key.hash(&mut hasher); - Some(ret) + Some(if state.insert(hasher.finish()) { + // True if this is a new line + s + } else { + // Nothing was inserted because we already saw this line + "" + }) }) { let new_selection = i.replace('\'', "''"); write!(f, " '{}'", new_selection)?;