2022-08-13 14:09:48 +00:00
|
|
|
mod finder;
|
2022-08-26 09:25:05 +00:00
|
|
|
mod matcher;
|
2022-08-13 14:09:48 +00:00
|
|
|
mod sorter;
|
|
|
|
|
mod thread_pool;
|
|
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::ffi::CStr;
|
2022-08-26 09:25:05 +00:00
|
|
|
use std::ffi::CString;
|
|
|
|
|
use std::os::raw::{c_char, c_int};
|
|
|
|
|
use std::sync::Mutex;
|
2022-08-13 14:09:48 +00:00
|
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
|
extern crate lazy_static;
|
|
|
|
|
|
|
|
|
|
lazy_static! {
|
2022-08-26 09:25:05 +00:00
|
|
|
static ref GLOBAL_FILE_CACHE: Mutex<HashMap<String, Vec<String>>> = Mutex::new(HashMap::new());
|
2022-08-13 14:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn to_string(input: *const c_char) -> String {
|
2022-08-26 09:25:05 +00:00
|
|
|
unsafe { CStr::from_ptr(input) }
|
|
|
|
|
.to_str()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.to_string()
|
2022-08-13 14:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_files(directory: &String) -> Vec<String> {
|
|
|
|
|
let mut cache = GLOBAL_FILE_CACHE.lock().unwrap();
|
|
|
|
|
if !cache.contains_key(directory) {
|
2022-08-26 09:25:05 +00:00
|
|
|
let finder_options = finder::Options {
|
|
|
|
|
directory: directory.clone(),
|
|
|
|
|
};
|
|
|
|
|
cache.insert(directory.clone(), finder::find_files(finder_options));
|
2022-08-13 14:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cache.get(directory).unwrap().to_vec();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-08-25 18:40:49 +00:00
|
|
|
pub extern "C" fn ivy_init(c_base_dir: *const c_char) {
|
|
|
|
|
let directory = to_string(c_base_dir);
|
|
|
|
|
get_files(&directory);
|
|
|
|
|
}
|
2022-08-13 14:09:48 +00:00
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
|
pub extern "C" fn ivy_match(c_pattern: *const c_char, c_text: *const c_char) -> c_int {
|
|
|
|
|
let pattern = to_string(c_pattern);
|
|
|
|
|
let text = to_string(c_text);
|
|
|
|
|
|
2022-08-26 13:20:17 +00:00
|
|
|
inner_match(pattern, text)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn inner_match(pattern: String, text: String) -> i32 {
|
2022-08-26 09:25:05 +00:00
|
|
|
let m = matcher::Matcher::new(pattern);
|
|
|
|
|
|
|
|
|
|
m.score(text) as i32
|
2022-08-13 14:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
|
pub extern "C" fn ivy_files(c_pattern: *const c_char, c_base_dir: *const c_char) -> *const c_char {
|
|
|
|
|
let pattern = to_string(c_pattern);
|
|
|
|
|
let directory = to_string(c_base_dir);
|
|
|
|
|
|
2022-08-26 13:20:17 +00:00
|
|
|
let output = inner_files(pattern, directory);
|
|
|
|
|
|
|
|
|
|
CString::new(output).unwrap().into_raw()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn inner_files(pattern: String, base_dir: String) -> String {
|
2022-08-26 15:01:22 +00:00
|
|
|
let mut output = String::new();
|
|
|
|
|
|
|
|
|
|
// Bail out early if the pattern is empty; it's never going to find anything
|
2022-08-13 14:09:48 +00:00
|
|
|
if pattern.is_empty() {
|
2022-08-26 15:01:22 +00:00
|
|
|
return output;
|
2022-08-13 14:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-26 13:20:17 +00:00
|
|
|
let files = get_files(&base_dir);
|
2022-08-13 14:09:48 +00:00
|
|
|
|
|
|
|
|
let sorter_options = sorter::Options::new(pattern);
|
|
|
|
|
|
|
|
|
|
let files = sorter::sort_strings(sorter_options, files);
|
2022-08-26 15:01:22 +00:00
|
|
|
for file in files.iter() {
|
2022-08-13 14:09:48 +00:00
|
|
|
output.push_str(&file.content);
|
|
|
|
|
output.push('\n');
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-26 13:20:17 +00:00
|
|
|
output
|
2022-08-13 14:09:48 +00:00
|
|
|
}
|