105 lines
2.8 KiB
Rust
105 lines
2.8 KiB
Rust
#![crate_name = "fzf"]
|
|
|
|
|
|
/**
|
|
* Return a filtered `Vec` of elements that contain the substring `needle`.
|
|
*/
|
|
pub fn filter_substring<'a>(needle: &str, haystack: &Vec<&'a str>) -> Vec<&'a str> {
|
|
return haystack
|
|
.iter()
|
|
.filter(|s| s.contains(needle))
|
|
.cloned()
|
|
.collect();
|
|
}
|
|
|
|
/**
|
|
* Return a filtered `Vec` of elements which `needle` is a subsequence of.
|
|
* (I know what I’m doing. Let me end a sentence with a preposition.) :^)
|
|
* See `is_subsequence` for more information on that.
|
|
*/
|
|
pub fn filter_subsequence<'a>(needle: &str, haystack: &Vec<&'a str>) -> Vec<&'a str> {
|
|
return haystack
|
|
.iter()
|
|
.filter(|s| is_subsequence(needle, s))
|
|
.cloned()
|
|
.collect();
|
|
}
|
|
|
|
/**
|
|
* Check whether the needle is a subsequence of the string.
|
|
* This is the case if string contains all of the characters in needle in the correct order, but
|
|
* not necessarily in succession.
|
|
*
|
|
* ```
|
|
* use fzf::is_subsequence;
|
|
* // ‘as’ is contained in ‘a(d)s’
|
|
* assert!(is_subsequence("as", "ads"));
|
|
* // but not in ‘sa’
|
|
* assert!(!is_subsequence("as", "sa"));
|
|
* ```
|
|
*/
|
|
pub fn is_subsequence(needle: &str, string: &str) -> bool {
|
|
let mut chars = string.chars();
|
|
'needle: for nc in needle.chars() {
|
|
for c in &mut chars {
|
|
if c == nc {
|
|
continue 'needle;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
true
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{filter_subsequence, filter_substring};
|
|
|
|
#[test]
|
|
fn test_filter_substring_single() {
|
|
let needle = "sdf";
|
|
let hay = vec!["asdf", "qwer"];
|
|
let expected = vec!["asdf"];
|
|
assert_eq!(filter_substring(&needle, &hay), expected);
|
|
}
|
|
|
|
#[test]
|
|
fn test_filter_substring_none() {
|
|
let needle = "sdf";
|
|
let hay = vec!["qwertz"];
|
|
let expected: Vec<&str> = Vec::new();
|
|
assert_eq!(filter_substring(&needle, &hay), expected);
|
|
}
|
|
|
|
#[test]
|
|
fn test_filter_substring_multiple() {
|
|
let needle = "sdf";
|
|
let hay = vec!["asdf", "asd", "sdfg", "dfgh"];
|
|
let expected = vec!["asdf", "sdfg"];
|
|
assert_eq!(filter_substring(&needle, &hay), expected);
|
|
}
|
|
|
|
#[test]
|
|
fn test_filter_subsequence_single() {
|
|
let needle = "asa";
|
|
let hay = vec!["aaass", "aasda"];
|
|
let expected = vec!["aasda"];
|
|
assert_eq!(filter_subsequence(&needle, &hay), expected);
|
|
}
|
|
|
|
#[test]
|
|
fn test_filter_subsequence_none() {
|
|
let needle = "asa";
|
|
let hay = vec!["aas"];
|
|
let expected: Vec<&str> = Vec::new();
|
|
assert_eq!(filter_subsequence(&needle, &hay), expected);
|
|
}
|
|
|
|
#[test]
|
|
fn test_filter_subsequence_multiple() {
|
|
let needle = "asa";
|
|
let hay = vec!["asa", "assa", "qwerafwfsferfssaas"];
|
|
assert_eq!(filter_subsequence(&needle, &hay), hay);
|
|
}
|
|
}
|