98 lines
2.7 KiB
Rust
Raw Normal View History

2022-06-06 18:01:49 -04:00
use kakplugin::Selection;
use regex::Regex;
use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
};
2022-06-09 18:11:03 -04:00
pub fn get_key(
2022-06-06 18:01:49 -04:00
selection: &Selection,
skip_whitespace: bool,
regex: Option<&Regex>,
ignore_case: bool,
) -> String {
// Strip whitespace if requested
let mut key = if skip_whitespace {
selection.as_str()
} else {
selection.trim()
};
// If they requested a regex match, set the key to the string slice of that match
if let Some(regex_match) = (|| {
let captures = 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
// Lowercase at the end to not mangle regex
if ignore_case {
key.to_lowercase()
} else {
// TODO: Do not perform an allocation here
key.to_string()
}
}
/// Get a key out of a selection based on options
2022-06-09 18:11:03 -04:00
pub fn get_hash(
2022-10-02 10:43:21 -04:00
// TODO: Accept any Into<AsRef<Selection>>
2022-06-06 18:01:49 -04:00
selection: &Selection,
skip_whitespace: bool,
regex: Option<&Regex>,
ignore_case: bool,
) -> u64 {
let mut hasher = DefaultHasher::new();
get_key(selection, skip_whitespace, regex, ignore_case).hash(&mut hasher);
hasher.finish()
}
2022-10-02 09:57:37 -04:00
/// Splits an `&str` into (string_value, trailing_newlines)
///
/// # Examples
///
/// ```
/// assert_eq!(split_trailing_newlines("asdf\n"), ("asdf", "\n"));
/// assert_eq!(split_trailing_newlines("asdf\n\nhjk\n"), ("asdf\n\nhjk", "\n"));
/// assert_eq!(split_trailing_newlines("asdf"), ("asdf", ""));
/// assert_eq!(split_trailing_newlines(""), ("", ""));
/// ```
pub fn split_trailing_newlines<'a>(s: &'a str) -> (&'a str, &'a str) {
s.rfind(|c| c != '\n')
.map(|idx| s.split_at(idx + 1))
.unwrap_or((s, ""))
}
/// Splits an `&str` into (leading_newlines, string_value, trailing_newlines)
///
/// # Examples
///
/// ```
/// assert_eq!(split_newlines("asdf\n"), ("", "asdf", "\n"));
/// assert_eq!(split_newlines("asdf\n\nhjk\n"), ("", "asdf\n\nhjk", "\n"));
/// assert_eq!(split_newlines("\nasdf\n\nhjk\n"), ("\n", "asdf\n\nhjk", "\n"));
/// assert_eq!(split_newlines("asdf"), ("", "asdf", ""));
/// assert_eq!(split_newlines("\n\n\nasdf"), ("\n\n\n", "asdf", ""));
/// assert_eq!(split_newlines(""), ("", "", ""));
/// ```
pub fn split_newlines<'a>(s: &'a str) -> (&'a str, &'a str, &'a str) {
let (leading_newlines, s) = s
.find(|c| c != '\n')
.map(|idx| s.split_at(idx))
.unwrap_or(("", s));
let (s, trailing_newlines) = s
.rfind(|c| c != '\n')
.map(|idx| s.split_at(idx + 1))
.unwrap_or((s, ""));
(leading_newlines, s, trailing_newlines)
}