gio/auto/
file_enumerator.rs1use crate::{ffi, AsyncResult, Cancellable, File, FileInfo};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10 #[doc(alias = "GFileEnumerator")]
11 pub struct FileEnumerator(Object<ffi::GFileEnumerator, ffi::GFileEnumeratorClass>);
12
13 match fn {
14 type_ => || ffi::g_file_enumerator_get_type(),
15 }
16}
17
18impl FileEnumerator {
19 pub const NONE: Option<&'static FileEnumerator> = None;
20}
21
22pub trait FileEnumeratorExt: IsA<FileEnumerator> + 'static {
23 #[doc(alias = "g_file_enumerator_close_async")]
24 fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
25 &self,
26 io_priority: glib::Priority,
27 cancellable: Option<&impl IsA<Cancellable>>,
28 callback: P,
29 ) {
30 let main_context = glib::MainContext::ref_thread_default();
31 let is_main_context_owner = main_context.is_owner();
32 let has_acquired_main_context = (!is_main_context_owner)
33 .then(|| main_context.acquire().ok())
34 .flatten();
35 assert!(
36 is_main_context_owner || has_acquired_main_context.is_some(),
37 "Async operations only allowed if the thread is owning the MainContext"
38 );
39
40 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
41 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
42 unsafe extern "C" fn close_async_trampoline<
43 P: FnOnce(Result<(), glib::Error>) + 'static,
44 >(
45 _source_object: *mut glib::gobject_ffi::GObject,
46 res: *mut crate::ffi::GAsyncResult,
47 user_data: glib::ffi::gpointer,
48 ) {
49 let mut error = std::ptr::null_mut();
50 ffi::g_file_enumerator_close_finish(_source_object as *mut _, res, &mut error);
51 let result = if error.is_null() {
52 Ok(())
53 } else {
54 Err(from_glib_full(error))
55 };
56 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
57 Box_::from_raw(user_data as *mut _);
58 let callback: P = callback.into_inner();
59 callback(result);
60 }
61 let callback = close_async_trampoline::<P>;
62 unsafe {
63 ffi::g_file_enumerator_close_async(
64 self.as_ref().to_glib_none().0,
65 io_priority.into_glib(),
66 cancellable.map(|p| p.as_ref()).to_glib_none().0,
67 Some(callback),
68 Box_::into_raw(user_data) as *mut _,
69 );
70 }
71 }
72
73 fn close_future(
74 &self,
75 io_priority: glib::Priority,
76 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
77 Box_::pin(crate::GioFuture::new(
78 self,
79 move |obj, cancellable, send| {
80 obj.close_async(io_priority, Some(cancellable), move |res| {
81 send.resolve(res);
82 });
83 },
84 ))
85 }
86
87 #[doc(alias = "g_file_enumerator_get_child")]
88 #[doc(alias = "get_child")]
89 fn child(&self, info: &FileInfo) -> File {
90 unsafe {
91 from_glib_full(ffi::g_file_enumerator_get_child(
92 self.as_ref().to_glib_none().0,
93 info.to_glib_none().0,
94 ))
95 }
96 }
97
98 #[doc(alias = "g_file_enumerator_get_container")]
99 #[doc(alias = "get_container")]
100 fn container(&self) -> File {
101 unsafe {
102 from_glib_none(ffi::g_file_enumerator_get_container(
103 self.as_ref().to_glib_none().0,
104 ))
105 }
106 }
107
108 #[doc(alias = "g_file_enumerator_has_pending")]
109 fn has_pending(&self) -> bool {
110 unsafe {
111 from_glib(ffi::g_file_enumerator_has_pending(
112 self.as_ref().to_glib_none().0,
113 ))
114 }
115 }
116
117 #[doc(alias = "g_file_enumerator_is_closed")]
118 fn is_closed(&self) -> bool {
119 unsafe {
120 from_glib(ffi::g_file_enumerator_is_closed(
121 self.as_ref().to_glib_none().0,
122 ))
123 }
124 }
125
126 #[doc(alias = "g_file_enumerator_next_file")]
127 fn next_file(
128 &self,
129 cancellable: Option<&impl IsA<Cancellable>>,
130 ) -> Result<Option<FileInfo>, glib::Error> {
131 unsafe {
132 let mut error = std::ptr::null_mut();
133 let ret = ffi::g_file_enumerator_next_file(
134 self.as_ref().to_glib_none().0,
135 cancellable.map(|p| p.as_ref()).to_glib_none().0,
136 &mut error,
137 );
138 if error.is_null() {
139 Ok(from_glib_full(ret))
140 } else {
141 Err(from_glib_full(error))
142 }
143 }
144 }
145
146 #[doc(alias = "g_file_enumerator_next_files_async")]
147 fn next_files_async<P: FnOnce(Result<Vec<FileInfo>, glib::Error>) + 'static>(
148 &self,
149 num_files: i32,
150 io_priority: glib::Priority,
151 cancellable: Option<&impl IsA<Cancellable>>,
152 callback: P,
153 ) {
154 let main_context = glib::MainContext::ref_thread_default();
155 let is_main_context_owner = main_context.is_owner();
156 let has_acquired_main_context = (!is_main_context_owner)
157 .then(|| main_context.acquire().ok())
158 .flatten();
159 assert!(
160 is_main_context_owner || has_acquired_main_context.is_some(),
161 "Async operations only allowed if the thread is owning the MainContext"
162 );
163
164 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
165 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
166 unsafe extern "C" fn next_files_async_trampoline<
167 P: FnOnce(Result<Vec<FileInfo>, glib::Error>) + 'static,
168 >(
169 _source_object: *mut glib::gobject_ffi::GObject,
170 res: *mut crate::ffi::GAsyncResult,
171 user_data: glib::ffi::gpointer,
172 ) {
173 let mut error = std::ptr::null_mut();
174 let ret =
175 ffi::g_file_enumerator_next_files_finish(_source_object as *mut _, res, &mut error);
176 let result = if error.is_null() {
177 Ok(FromGlibPtrContainer::from_glib_full(ret))
178 } else {
179 Err(from_glib_full(error))
180 };
181 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
182 Box_::from_raw(user_data as *mut _);
183 let callback: P = callback.into_inner();
184 callback(result);
185 }
186 let callback = next_files_async_trampoline::<P>;
187 unsafe {
188 ffi::g_file_enumerator_next_files_async(
189 self.as_ref().to_glib_none().0,
190 num_files,
191 io_priority.into_glib(),
192 cancellable.map(|p| p.as_ref()).to_glib_none().0,
193 Some(callback),
194 Box_::into_raw(user_data) as *mut _,
195 );
196 }
197 }
198
199 fn next_files_future(
200 &self,
201 num_files: i32,
202 io_priority: glib::Priority,
203 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<FileInfo>, glib::Error>> + 'static>>
204 {
205 Box_::pin(crate::GioFuture::new(
206 self,
207 move |obj, cancellable, send| {
208 obj.next_files_async(num_files, io_priority, Some(cancellable), move |res| {
209 send.resolve(res);
210 });
211 },
212 ))
213 }
214
215 #[doc(alias = "g_file_enumerator_set_pending")]
216 fn set_pending(&self, pending: bool) {
217 unsafe {
218 ffi::g_file_enumerator_set_pending(self.as_ref().to_glib_none().0, pending.into_glib());
219 }
220 }
221}
222
223impl<O: IsA<FileEnumerator>> FileEnumeratorExt for O {}