1use std::ffi::OsStr;
2use std::ffi::OsString;
3use std::marker::PhantomData;
4use std::path::Path;
5use std::path::PathBuf;
6use std::sync::OnceLock;
7
8use crate::raw;
9
10pub use raw::FileInfoType;
11pub use raw::RequestFlags;
12pub use raw::SortType;
13pub use raw::TargetMachine;
14
15pub mod error {
16 use super::RequestFlags;
17 use thiserror::Error as ThisError;
18
19 pub type Result<T> = std::result::Result<T, EverythingError>;
20
21 #[non_exhaustive]
22 #[derive(ThisError, Debug)]
23 pub enum EverythingError {
24 #[error("Failed to allocate memory for the search query.")]
25 Memory,
26 #[error("IPC is not available.")]
27 Ipc,
28 #[error("Failed to register the search query window class.")]
29 RegisterClassEx,
30 #[error("Failed to create the search query window.")]
31 CreateWindow,
32 #[error("Failed to create the search query thread.")]
33 CreateThread,
34 #[error("Invalid index. The index must be greater or equal to 0 and less than the number of visible results.")]
35 InvalidIndex,
36 #[error("Invalid call.")]
37 InvalidCall,
38 #[error("invalid request data, request data first.")]
39 InvalidRequest(#[from] InvalidRequestError),
40 #[error("bad parameter.")]
41 InvalidParameter,
42 #[error("not supported when using set_request_flags or set_sort to non-default value. (that is in query verison 2)")]
43 UnsupportedInQueryVersion2,
44 }
45
46 #[non_exhaustive]
47 #[derive(ThisError, Debug)]
48 pub enum InvalidRequestError {
49 #[error("should set the request flag {0:?}")]
50 RequestFlagsNotSet(RequestFlags),
51 }
52}
53
54pub use error::{EverythingError, InvalidRequestError, Result};
55
56use tracing::debug;
57use widestring::U16CStr;
58
59mod helper {
60 use super::*;
61
62 pub fn is_default_request_flags(request_flags: RequestFlags) -> bool {
63 request_flags == RequestFlags::default()
64 }
65
66 pub fn is_default_sort_type(sort_type: SortType) -> bool {
67 sort_type == SortType::default()
68 }
69
70 pub fn should_use_query_version_2(request_flags: RequestFlags, sort_type: SortType) -> bool {
72 !is_default_request_flags(request_flags) || !is_default_sort_type(sort_type)
73 }
74}
75
76#[cfg(not(feature = "async"))]
77pub fn global() -> &'static std::sync::Mutex<EverythingGlobal> {
78 static EVERYTHING_CELL: OnceLock<std::sync::Mutex<EverythingGlobal>> = OnceLock::new();
79 EVERYTHING_CELL.get_or_init(|| std::sync::Mutex::new(EverythingGlobal {}))
80}
81
82#[cfg(feature = "async")]
83pub fn global() -> &'static futures::lock::Mutex<EverythingGlobal> {
84 static EVERYTHING_CELL: OnceLock<futures::lock::Mutex<EverythingGlobal>> = OnceLock::new();
85 EVERYTHING_CELL.get_or_init(|| futures::lock::Mutex::new(EverythingGlobal {}))
86}
87
88#[non_exhaustive]
89#[derive(Debug)]
90pub struct EverythingGlobal {}
91
92impl Drop for EverythingGlobal {
93 fn drop(&mut self) {
95 raw::Everything_CleanUp();
99 unreachable!()
100 }
101}
102
103impl EverythingGlobal {
104 pub fn searcher<'a>(&'a mut self) -> EverythingSearcher<'a> {
108 EverythingSearcher {
109 _phantom: PhantomData::<&'a ()>,
110 }
111 }
112
113 pub fn version(&self) -> Result<(u32, u32, u32, u32, TargetMachine)> {
118 Ok((
119 self.get_major_version()?,
120 self.get_minor_version()?,
121 self.get_revision()?,
122 self.get_build_number()?,
123 self.get_target_machine()?,
124 ))
125 }
126
127 pub fn get_major_version(&self) -> Result<u32> {
128 raw::Everything_GetMajorVersion().ok_or(EverythingError::Ipc)
129 }
130
131 pub fn get_minor_version(&self) -> Result<u32> {
132 raw::Everything_GetMinorVersion().ok_or(EverythingError::Ipc)
133 }
134
135 pub fn get_revision(&self) -> Result<u32> {
136 raw::Everything_GetRevision().ok_or(EverythingError::Ipc)
137 }
138
139 pub fn get_build_number(&self) -> Result<u32> {
140 raw::Everything_GetBuildNumber().ok_or(EverythingError::Ipc)
141 }
142
143 pub fn get_target_machine(&self) -> Result<TargetMachine> {
144 raw::Everything_GetTargetMachine().ok_or(EverythingError::Ipc)
145 }
146
147 pub fn save_and_exit(&mut self) -> Result<bool> {
149 raw::Everything_Exit().ok_or(EverythingError::Ipc)
150 }
151
152 pub fn is_db_loaded(&self) -> Result<bool> {
157 raw::Everything_IsDBLoaded().ok_or(EverythingError::Ipc)
158 }
159
160 pub fn is_admin(&self) -> Result<bool> {
162 raw::Everything_IsAdmin().ok_or(EverythingError::Ipc)
163 }
164
165 pub fn is_appdata(&self) -> Result<bool> {
168 raw::Everything_IsAppData().ok_or(EverythingError::Ipc)
169 }
170
171 pub fn rebuild_db(&mut self) -> Result<bool> {
177 raw::Everything_RebuildDB().ok_or(EverythingError::Ipc)
179 }
180
181 pub fn update_all_folder_indexes(&mut self) -> Result<bool> {
185 raw::Everything_UpdateAllFolderIndexes().ok_or(EverythingError::Ipc)
187 }
188
189 pub fn save_db(&mut self) -> Result<bool> {
194 raw::Everything_SaveDB().ok_or(EverythingError::Ipc)
196 }
197
198 pub fn save_run_history(&mut self) -> Result<bool> {
206 raw::Everything_SaveRunHistory().ok_or(EverythingError::Ipc)
208 }
209
210 pub fn delete_run_history(&mut self) -> Result<bool> {
214 raw::Everything_DeleteRunHistory().ok_or(EverythingError::Ipc)
216 }
217
218 pub fn get_run_count(&self, filename: impl AsRef<Path>) -> Result<u32> {
220 raw::Everything_GetRunCountFromFileName(filename.as_ref()).ok_or(EverythingError::Ipc)
221 }
222
223 pub fn set_run_count(&mut self, filename: impl AsRef<Path>, run_count: u32) -> Result<()> {
225 if raw::Everything_SetRunCountFromFileName(filename.as_ref(), run_count) {
226 Ok(())
227 } else {
228 Err(EverythingError::Ipc)
229 }
230 }
231
232 pub fn inc_run_count(&mut self, filename: impl AsRef<Path>) -> Result<u32> {
234 raw::Everything_IncRunCountFromFileName(filename.as_ref())
235 .map(|n| n.get())
236 .ok_or(EverythingError::Ipc)
237 }
238
239 pub fn is_fast_sort(&self, sort_type: SortType) -> Result<bool> {
243 raw::Everything_IsFastSort(sort_type).ok_or(EverythingError::Ipc)
244 }
245
246 pub fn is_file_info_indexed(&self, file_info_type: FileInfoType) -> Result<bool> {
248 raw::Everything_IsFileInfoIndexed(file_info_type).ok_or(EverythingError::Ipc)
249 }
250}
251
252#[non_exhaustive]
253pub struct EverythingSearcher<'a> {
254 _phantom: PhantomData<&'a ()>,
255}
256
257impl Drop for EverythingSearcher<'_> {
258 fn drop(&mut self) {
259 raw::Everything_Reset(); debug!("[Drop] EverythingSearcher is dropped! (did Reset)");
261 }
262}
263
264impl<'a> EverythingSearcher<'a> {
265 pub fn set_search(&mut self, text: impl AsRef<OsStr>) -> &'_ mut EverythingSearcher<'a> {
268 raw::Everything_SetSearch(text);
269 self
270 }
271
272 pub fn set_match_path(&mut self, enable: bool) -> &'_ mut EverythingSearcher<'a> {
274 raw::Everything_SetMatchPath(enable);
275 self
276 }
277
278 pub fn set_match_case(&mut self, enable: bool) -> &'_ mut EverythingSearcher<'a> {
280 raw::Everything_SetMatchCase(enable);
281 self
282 }
283
284 pub fn set_match_whole_word(&mut self, enable: bool) -> &'_ mut EverythingSearcher<'a> {
286 raw::Everything_SetMatchWholeWord(enable);
287 self
288 }
289
290 pub fn set_regex(&mut self, enable: bool) -> &'_ mut EverythingSearcher<'a> {
292 raw::Everything_SetRegex(enable);
293 self
294 }
295
296 pub fn set_max(&mut self, max_results: u32) -> &'_ mut EverythingSearcher<'a> {
298 raw::Everything_SetMax(max_results);
299 self
300 }
301
302 pub fn set_offset(&mut self, offset: u32) -> &'_ mut EverythingSearcher<'a> {
304 raw::Everything_SetOffset(offset);
305 self
306 }
307
308 pub fn set_sort(&mut self, sort_type: SortType) -> &'_ mut EverythingSearcher<'a> {
310 raw::Everything_SetSort(sort_type);
311 self
312 }
313
314 pub fn set_request_flags(&mut self, flags: RequestFlags) -> &'_ mut EverythingSearcher<'a> {
316 raw::Everything_SetRequestFlags(flags);
317 self
318 }
319
320 pub fn get_search(&self) -> OsString {
322 raw::Everything_GetSearch()
323 }
324
325 pub fn get_match_path(&self) -> bool {
326 raw::Everything_GetMatchPath()
327 }
328
329 pub fn get_match_case(&self) -> bool {
330 raw::Everything_GetMatchCase()
331 }
332
333 pub fn get_match_whole_word(&self) -> bool {
334 raw::Everything_GetMatchWholeWord()
335 }
336
337 pub fn get_regex(&self) -> bool {
338 raw::Everything_GetRegex()
339 }
340
341 pub fn get_max(&self) -> u32 {
342 raw::Everything_GetMax()
343 }
344
345 pub fn get_offset(&self) -> u32 {
346 raw::Everything_GetOffset()
347 }
348
349 pub fn get_sort(&self) -> SortType {
350 raw::Everything_GetSort()
351 }
352
353 pub fn get_request_flags(&self) -> RequestFlags {
354 raw::Everything_GetRequestFlags()
355 }
356}
357
358impl<'a> EverythingSearcher<'a> {
359 #[cfg(not(feature = "async"))]
360 pub fn query<'b>(&'b mut self) -> EverythingResults<'b> {
365 raw::Everything_Query(true);
366 EverythingResults {
367 _phantom: PhantomData::<&'b ()>,
368 }
369 }
370
371 #[cfg(feature = "async")]
372 pub async fn query<'b>(&'b mut self) -> EverythingResults<'b> {
373 non_blocking::QueryFuture::<'b>::new().await
374 }
375
376 pub fn _query_and_sort_by_path<'b>(&'b mut self) -> EverythingResults<'b> {
380 raw::Everything_Query(true);
381 raw::Everything_SortResultsByPath();
384 EverythingResults {
385 _phantom: PhantomData::<&'b ()>,
386 }
387 }
388}
389
390#[cfg(feature = "async")]
391mod non_blocking {
392 use std::{
393 marker::PhantomData,
394 pin::Pin,
395 sync::{Arc, Mutex},
396 task::{Context, Poll, Waker},
397 thread,
398 };
399
400 use windows::{
401 core::w,
402 Win32::{
403 Foundation::{FALSE, HINSTANCE, HWND, LPARAM, LRESULT, WPARAM},
404 System::LibraryLoader::GetModuleHandleW,
405 UI::WindowsAndMessaging::{
406 CreateWindowExW, DefWindowProcW, DestroyWindow, GetClassInfoExW, PeekMessageW,
407 PostMessageW, RegisterClassExW, WaitMessage, HWND_MESSAGE, MSG, PM_NOREMOVE,
408 WINDOW_EX_STYLE, WM_COPYDATA, WM_USER, WNDCLASSEXW, WS_OVERLAPPED,
409 },
410 },
411 };
412
413 use tracing::debug;
414
415 use super::EverythingResults;
416 use crate::raw;
417
418 #[non_exhaustive]
419 pub struct QueryFuture<'a> {
420 shared_state: Arc<Mutex<SharedState>>,
422 _phantom: PhantomData<&'a ()>,
423 }
424
425 struct SharedState {
427 completed: bool,
429
430 waker: Option<Waker>,
435 }
436
437 impl<'a> std::future::Future for QueryFuture<'a> {
438 type Output = EverythingResults<'a>;
439 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
440 debug!("poll() called");
441 let mut shared_state = self.shared_state.lock().unwrap();
442 if shared_state.completed {
443 let results = EverythingResults {
444 _phantom: PhantomData::<&'a ()>,
445 };
446 debug!("Poll::Ready(_)!");
447 Poll::Ready(results)
448 } else {
449 shared_state.waker = Some(cx.waker().clone());
450 debug!("Poll::Pending");
451 Poll::Pending
452 }
453 }
454 }
455
456 impl<'a> QueryFuture<'a> {
457 pub fn new() -> Self {
458 debug!("QueryFuture::new() start");
459
460 let shared_state = Arc::new(Mutex::new(SharedState {
461 completed: false,
462 waker: None,
463 }));
464
465 let thread_shared_state = shared_state.clone();
467 thread::spawn(move || {
468 debug!("thread::spawn");
469 unsafe {
470 debug!("first time for init");
471 raw::Everything_SetReplyID(CUSTOM_REPLY_ID);
472 debug_assert_eq!(raw::Everything_GetReplyID(), CUSTOM_REPLY_ID);
473 let hwnd = create_window().unwrap();
474 raw::Everything_SetReplyWindow(hwnd);
475 debug_assert_eq!(raw::Everything_GetReplyWindow(), hwnd);
476
477 debug!("Execute Query with _FALSE_");
478 assert!(raw::Everything_Query(false));
479
480 let mut msg: MSG = MSG::default();
481 debug!("WaitMessage()...");
482 WaitMessage().unwrap(); debug!("WaitMessage() Done, One msg at least, then PeekMessageW()...");
484 if PeekMessageW(&mut msg, hwnd, 0, 0, PM_NOREMOVE) == FALSE {
485 panic!("There must be a message in the queue after WaitMessage().");
486 }
487 debug!("Gooooooot it! WM_{:#06x} ({})", msg.message, msg.message);
488 if msg.message != WM_USER_IS_QUERY_REPLY_DONE {
489 panic!("Must be only one type message set by us.");
490 }
491 debug!("Yes, we did it. (now we have results)");
492 DestroyWindow(hwnd).unwrap();
493 debug!("DestroyWindow() Done");
494
495 let mut shared_state = thread_shared_state.lock().unwrap();
496 shared_state.completed = true;
499 debug!("set .completed to true");
500 if let Some(waker) = shared_state.waker.take() {
501 debug!("waker.wake()");
502 waker.wake()
503 }
504 }
505 });
506
507 debug!("QueryFuture::new() end");
508 Self {
509 shared_state,
510 _phantom: PhantomData::<&'a ()>,
511 }
512 }
513 }
514
515 const WM_USER_IS_QUERY_REPLY_DONE: u32 = WM_USER + 42;
516 const CUSTOM_REPLY_ID: u32 = 9527;
517
518 extern "system" fn wndproc(
519 hwnd: HWND,
520 message: u32,
521 wparam: WPARAM,
522 lparam: LPARAM,
523 ) -> LRESULT {
524 unsafe {
525 match message {
526 WM_COPYDATA => {
527 if raw::Everything_IsQueryReply(message, wparam, lparam, CUSTOM_REPLY_ID) {
528 debug!("[wndproc] Everything_IsQueryReply() -> YEEEESSSSSS!! (So copy done and PostMessage(WM_USER_IS_QUERY_REPLY_DONE))");
529 PostMessageW(hwnd, WM_USER_IS_QUERY_REPLY_DONE, WPARAM(0), LPARAM(0))
530 .unwrap();
531 LRESULT(1)
532 } else {
533 panic!("!!!! Everything_IsQueryReply() -> NOOOO!!");
535 }
536 }
537 _ => {
538 debug!(
539 "[wndproc] DefWindowProcW( msg => WM_{:#06x} ({}) )",
540 message, message
541 );
542 DefWindowProcW(hwnd, message, wparam, lparam)
543 }
544 }
545 }
546 }
547
548 fn create_window() -> windows::core::Result<HWND> {
549 unsafe {
550 let instance: HINSTANCE = GetModuleHandleW(None)?.into();
551 assert!(!instance.is_invalid());
552
553 let window_class_name = w!("EVERYTHING_SDK_RUST");
554
555 let mut wc = WNDCLASSEXW {
556 cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32,
557 hInstance: instance,
558 lpszClassName: window_class_name,
559 lpfnWndProc: Some(wndproc),
560 ..Default::default()
561 };
562
563 if GetClassInfoExW(instance, window_class_name, &mut wc).is_err() {
564 let atom = RegisterClassExW(&wc);
565 assert!(atom != 0);
566 }
567
568 let hwnd = CreateWindowExW(
569 WINDOW_EX_STYLE::default(),
570 window_class_name,
571 w!("The window for async query in everything-sdk-rs crate"),
572 WS_OVERLAPPED,
573 0,
574 0,
575 0,
576 0,
577 HWND_MESSAGE,
579 None,
580 instance,
581 None,
582 );
583
584 assert_ne!(hwnd, HWND(0));
585
586 Ok(hwnd)
587 }
588 }
589}
590
591#[non_exhaustive]
592pub struct EverythingResults<'a> {
593 _phantom: PhantomData<&'a ()>,
594}
595
596impl<'a> Drop for EverythingResults<'a> {
597 fn drop(&mut self) {
598 debug!("[Drop] EverythingResults is dropped!");
601 }
602}
603
604impl<'a> EverythingResults<'a> {
605 pub fn len(&self) -> u32 {
607 self.num()
608 }
609
610 pub fn at(&self, index: u32) -> Option<EverythingItem<'a>> {
611 self.iter().nth(index as usize)
612 }
613
614 pub fn iter(&self) -> Iter<'a> {
615 Iter {
616 next_index: 0,
617 length: self.len(),
618 request_flags: self.request_flags(),
619 _phantom: PhantomData::<&'a ()>,
620 }
621 }
622
623 pub fn request_flags(&self) -> RequestFlags {
624 raw::Everything_GetResultListRequestFlags()
625 }
626
627 pub fn sort_type(&self) -> SortType {
628 raw::Everything_GetResultListSort()
629 }
630
631 fn is_query_version_2(&self) -> bool {
632 helper::should_use_query_version_2(self.request_flags(), self.sort_type())
633 }
634
635 pub fn num_files(&self) -> Result<u32> {
636 if self.is_query_version_2() {
637 Err(EverythingError::UnsupportedInQueryVersion2)
638 } else {
639 let num = raw::Everything_GetNumFileResults();
640 Ok(num) }
642 }
643
644 pub fn num_folders(&self) -> Result<u32> {
645 if self.is_query_version_2() {
646 Err(EverythingError::UnsupportedInQueryVersion2)
647 } else {
648 let num = raw::Everything_GetNumFolderResults();
649 Ok(num) }
651 }
652
653 pub fn num(&self) -> u32 {
655 let num = raw::Everything_GetNumResults();
656 num }
658
659 pub fn total_files(&self) -> Result<u32> {
660 if self.is_query_version_2() {
661 Err(EverythingError::UnsupportedInQueryVersion2)
662 } else {
663 let num = raw::Everything_GetTotFileResults();
664 Ok(num) }
666 }
667
668 pub fn total_folders(&self) -> Result<u32> {
669 if self.is_query_version_2() {
670 Err(EverythingError::UnsupportedInQueryVersion2)
671 } else {
672 let num = raw::Everything_GetTotFolderResults();
673 Ok(num) }
675 }
676
677 pub fn total(&self) -> u32 {
678 let total = raw::Everything_GetTotResults();
679 total }
681}
682
683#[non_exhaustive]
684pub struct EverythingItem<'a> {
685 index: u32,
686 request_flags: RequestFlags,
687 _phantom: PhantomData<&'a ()>,
688}
689
690#[non_exhaustive]
691pub struct Iter<'a> {
692 next_index: u32,
693 length: u32,
694 request_flags: RequestFlags,
695 _phantom: PhantomData<&'a ()>,
696}
697
698impl<'a> Iterator for Iter<'a> {
699 type Item = EverythingItem<'a>;
700 fn next(&mut self) -> Option<Self::Item> {
701 if self.next_index < self.length {
702 let index = self.next_index;
703 self.next_index += 1;
704 Some(EverythingItem {
705 index,
706 request_flags: self.request_flags,
707 _phantom: PhantomData::<&'a ()>,
708 })
709 } else {
710 None
711 }
712 }
713
714 fn size_hint(&self) -> (usize, Option<usize>) {
715 let rest = usize::try_from(self.length - self.next_index).unwrap();
716 (rest, Some(rest))
717 }
718
719 fn nth(&mut self, n: usize) -> Option<Self::Item> {
720 let index = self.next_index + u32::try_from(n).unwrap();
721 if index < self.length {
722 self.next_index = index + 1;
723 Some(EverythingItem {
724 index,
725 request_flags: self.request_flags,
726 _phantom: PhantomData::<&'a ()>,
727 })
728 } else {
729 self.next_index = self.length;
730 None
731 }
732 }
733}
734
735impl<'a> ExactSizeIterator for Iter<'a> {}
736
737impl<'a> IntoIterator for EverythingResults<'a> {
738 type Item = EverythingItem<'a>;
739 type IntoIter = Iter<'a>;
740 fn into_iter(self) -> Self::IntoIter {
741 Iter {
742 next_index: 0,
743 length: self.len(),
744 request_flags: self.request_flags(),
745 _phantom: PhantomData::<&'a ()>,
746 }
747 }
748}
749
750impl<'a> EverythingItem<'a> {
751 pub fn index(&self) -> u32 {
752 self.index
753 }
754
755 pub fn is_volume(&self) -> bool {
756 raw::Everything_IsVolumeResult(self.index)
757 }
758
759 pub fn is_folder(&self) -> bool {
760 raw::Everything_IsFolderResult(self.index)
761 }
762
763 pub fn is_file(&self) -> bool {
764 raw::Everything_IsFileResult(self.index)
765 }
766
767 pub fn filename(&self) -> Result<OsString> {
768 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_FILE_NAME)?;
769 Ok(raw::Everything_GetResultFileName(self.index).unwrap())
770 }
771
772 pub fn path(&self) -> Result<PathBuf> {
773 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_PATH)?;
774 Ok(raw::Everything_GetResultPath(self.index).unwrap().into())
775 }
776
777 pub fn filepath(&self) -> Result<PathBuf> {
783 self.need_flags_set(
785 RequestFlags::EVERYTHING_REQUEST_PATH | RequestFlags::EVERYTHING_REQUEST_FILE_NAME,
786 )?;
787 let buf_len = u32::from(raw::Everything_GetResultFullPathNameSizeHint(self.index).unwrap());
788 let mut buf = vec![0; buf_len as usize];
789 let n_wchar =
790 u32::from(raw::Everything_GetResultFullPathName(self.index, &mut buf).unwrap());
791 assert_eq!(buf_len, n_wchar + 1);
792 Ok(U16CStr::from_slice(&buf).unwrap().to_os_string().into())
793 }
794
795 pub fn full_path_name(&self, max_len: Option<u32>) -> Result<PathBuf> {
803 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME)?;
804 let size_hint =
805 u32::from(raw::Everything_GetResultFullPathNameSizeHint(self.index).unwrap());
806 let buf_len = std::cmp::min(size_hint, max_len.unwrap_or(u32::MAX)) as usize;
807 let mut buf = vec![0; buf_len];
808 let n_wchar =
809 u32::from(raw::Everything_GetResultFullPathName(self.index, &mut buf).unwrap());
810 assert_eq!(size_hint, n_wchar + 1);
811 Ok(U16CStr::from_slice(&buf).unwrap().to_os_string().into())
812 }
813
814 fn need_flags_set(&self, flags: RequestFlags) -> Result<()> {
816 if self.request_flags.contains(flags) {
817 Ok(())
818 } else {
819 Err(EverythingError::InvalidRequest(
820 InvalidRequestError::RequestFlagsNotSet(flags),
821 ))
822 }
823 }
824
825 pub fn extension(&self) -> Result<OsString> {
826 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_EXTENSION)?;
827 Ok(raw::Everything_GetResultExtension(self.index).unwrap())
828 }
829
830 pub fn size(&self) -> Result<u64> {
831 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_SIZE)?;
832 let file_size = raw::Everything_GetResultSize(self.index).unwrap();
833 u64::try_from(file_size).or_else(|_e| {
843 if raw::Everything_IsFolderResult(self.index) {
844 debug_assert_eq!(file_size, -1); Ok(0)
846 } else {
847 panic!(
848 "file size should not be a negative integer => {}",
849 file_size
850 )
851 }
852 })
853 }
854
855 pub fn date_created(&self) -> Result<u64> {
856 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_DATE_CREATED)?;
857 Ok(raw::Everything_GetResultDateCreated(self.index).unwrap())
858 }
859
860 pub fn date_modified(&self) -> Result<u64> {
861 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_DATE_MODIFIED)?;
862 Ok(raw::Everything_GetResultDateModified(self.index).unwrap())
863 }
864
865 pub fn date_accessed(&self) -> Result<u64> {
866 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_DATE_ACCESSED)?;
867 Ok(raw::Everything_GetResultDateAccessed(self.index).unwrap())
868 }
869
870 pub fn attributes(&self) -> Result<u32> {
871 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_ATTRIBUTES)?;
872 Ok(raw::Everything_GetResultAttributes(self.index).unwrap())
873 }
874
875 pub fn file_list_filename(&self) -> Result<OsString> {
876 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_FILE_LIST_FILE_NAME)?;
877 Ok(raw::Everything_GetResultFileListFileName(self.index).unwrap())
878 }
879
880 pub fn run_count(&self) -> Result<u32> {
881 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_RUN_COUNT)?;
882 Ok(raw::Everything_GetResultRunCount(self.index))
883 }
884
885 pub fn date_run(&self) -> Result<u64> {
886 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_DATE_RUN)?;
887 Ok(raw::Everything_GetResultDateRun(self.index).unwrap())
888 }
889
890 pub fn date_recently_changed(&self) -> Result<u64> {
891 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_DATE_RECENTLY_CHANGED)?;
892 Ok(raw::Everything_GetResultDateRecentlyChanged(self.index).unwrap())
893 }
894
895 pub fn highlighted_filename(&self) -> Result<OsString> {
896 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_HIGHLIGHTED_FILE_NAME)?;
897 Ok(raw::Everything_GetResultHighlightedFileName(self.index).unwrap())
898 }
899
900 pub fn highlighted_path(&self) -> Result<OsString> {
901 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_HIGHLIGHTED_PATH)?;
902 Ok(raw::Everything_GetResultHighlightedPath(self.index).unwrap())
903 }
904
905 pub fn highlighted_full_path_and_filename(&self) -> Result<OsString> {
906 self.need_flags_set(RequestFlags::EVERYTHING_REQUEST_HIGHLIGHTED_FULL_PATH_AND_FILE_NAME)?;
907 Ok(raw::Everything_GetResultHighlightedFullPathAndFileName(self.index).unwrap())
908 }
909}