Everything SDK in Rust
Use Everything SDK in Rust way. Types and Lifetime prevent you from accidentally calling the IPC query functions by mistake.
No document proofing yet, but you could be able to try it out.
Usage
[dependencies]
everything-sdk = "0.0.2"
The Sample all you should know: readme.rs .
use everything_sdk::*;
fn main() {
let mut everything = global().try_lock().unwrap();
match everything.is_db_loaded() {
Ok(false) => panic!("The Everything database has not been fully loaded now."),
Err(EverythingError::Ipc) => panic!("Everything is required to run in the background."),
_ => {
let mut searcher = everything.searcher();
searcher.set_search("jpg");
searcher
.set_request_flags(
RequestFlags::EVERYTHING_REQUEST_FILE_NAME
| RequestFlags::EVERYTHING_REQUEST_PATH
| RequestFlags::EVERYTHING_REQUEST_SIZE
| RequestFlags::EVERYTHING_REQUEST_RUN_COUNT,
)
.set_max(5)
.set_sort(SortType::EVERYTHING_SORT_DATE_RECENTLY_CHANGED_ASCENDING);
assert_eq!(searcher.get_match_case(), false);
let results = searcher.query();
let visible_num_results = dbg!(results.num());
assert!(visible_num_results <= 5);
let total_num_results = dbg!(results.total());
assert!(total_num_results >= visible_num_results);
let is_attr_flag_set =
dbg!(results.request_flags()).contains(RequestFlags::EVERYTHING_REQUEST_ATTRIBUTES);
assert!(!is_attr_flag_set);
for item in results.iter() {
let full_path = item.path().unwrap().join(item.filename().unwrap());
println!(
"Item[{}]: {} ({} bytes)",
item.index(),
full_path.display(),
item.size().unwrap(),
);
}
let run_count = results
.at(2)
.expect("I'm pretty sure there are at least 3 results.")
.run_count()
.unwrap();
println!("Run Count for Item[2]: `{}`", run_count);
drop(results);
searcher.set_search("cargo");
let _results = searcher.query();
}
}
let (major, minor, patch, build, taget) = everything.version().unwrap();
println!("Everything.exe version is {major}.{minor}.{patch}.{build} ({taget})");
global().try_lock().expect_err("Prev lock is still held.");
drop(everything);
let _is_in_appdata = global()
.try_lock()
.expect("We could take the lock now, use it, and return it immediately.")
.is_appdata()
.unwrap();
}
The async feature
[dependencies]
everything-sdk = { version = "0.0.2", features = ["async"] }
There are only two differences in async code compared to synchronous code.
let mut everything = global().lock().await; let results = searcher.query().await;
The complete Sample in async mode with the same logic: readme_async.rs .
The raw feature
[dependencies]
everything-sdk = { version = "0.0.2", features = ["raw"] }
use everything_sdk::raw::*;
fn main() {
let (major, minor, patch, build, taget) = (
Everything_GetMajorVersion().unwrap(),
Everything_GetMinorVersion().unwrap(),
Everything_GetRevision().unwrap(),
Everything_GetBuildNumber().unwrap(),
Everything_GetTargetMachine().unwrap(),
);
println!("Everything.exe version is {major}.{minor}.{patch}.{build} ({taget})");
}
The complete Sample in raw mode with the same logic: readme_raw.rs .
So why do we need these tedious steps?
It looks no different from the ergonomic wrapper, why can't we just write the code like this?
Think about that:
For any Everything_* function as below, we insert another Everything_* function between
them, which will cause the modifications of the mutable global shared states (the underhood
we know they are just the global static variables in C code), because they all have access
to them. Finally it will cause everything to become messy, uncontrollable and unreliable.
All we can do is to line them up, in some certain order, and let them move forward one by one
to prevent confusion.
License
This project use the GPLv3 License.