Add optional regex to uniq

This commit is contained in:
Austen Adler 2022-03-09 22:10:25 -05:00
parent 9b847eff0d
commit 84861d8574

View File

@ -1,12 +1,15 @@
use crate::{ use crate::{
get_selections_desc, set_selections, set_selections_desc, KakMessage, SelectionWithDesc, get_selections_desc, set_selections, set_selections_desc, KakMessage, SelectionWithDesc,
}; };
use regex::Regex;
use std::{ use std::{
collections::{hash_map::DefaultHasher, BTreeSet}, collections::{hash_map::DefaultHasher, BTreeSet},
hash::{Hash, Hasher}, hash::{Hash, Hasher},
}; };
#[derive(clap::StructOpt, Debug)] #[derive(clap::StructOpt, Debug)]
pub struct Options { pub struct Options {
#[clap(index = 1)]
regex: Option<Regex>,
#[clap(short, long)] #[clap(short, long)]
ignore_case: bool, ignore_case: bool,
// TODO: Can we invert a boolean? This name is terrible // TODO: Can we invert a boolean? This name is terrible
@ -23,12 +26,24 @@ pub fn uniq(options: &Options) -> Result<KakMessage, KakMessage> {
.into_iter() .into_iter()
// Create a BTreeSet of hashes of lines. This way, string content is not stored, but uniqueness can be determined // Create a BTreeSet of hashes of lines. This way, string content is not stored, but uniqueness can be determined
.scan(BTreeSet::new(), |state, s| { .scan(BTreeSet::new(), |state, s| {
let key = if options.no_skip_whitespace { // Strip whitespace if requested
let mut key = if options.no_skip_whitespace {
s.content.as_str() s.content.as_str()
} else { } else {
s.content.trim() s.content.trim()
}; };
if let Some(regex_match) = (|| {
let captures = options.regex.as_ref()?.captures(key)?;
captures
.get(1)
.or_else(|| captures.get(0))
.map(|m| m.as_str())
})() {
key = regex_match;
}
// Ignore case if requested
let key = if options.ignore_case { let key = if options.ignore_case {
key.to_lowercase() key.to_lowercase()
} else { } else {