gio/auto/file_enumerator.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, AsyncResult, Cancellable, File, FileInfo};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10 /// `GFileEnumerator` allows you to operate on a set of [`File`][crate::File] objects,
11 /// returning a [`FileInfo`][crate::FileInfo] structure for each file enumerated (e.g.
12 /// [`FileExt::enumerate_children()`][crate::prelude::FileExt::enumerate_children()] will return a `GFileEnumerator` for each
13 /// of the children within a directory).
14 ///
15 /// To get the next file's information from a `GFileEnumerator`, use
16 /// [`FileEnumeratorExt::next_file()`][crate::prelude::FileEnumeratorExt::next_file()] or its asynchronous version,
17 /// [`FileEnumeratorExt::next_files_async()`][crate::prelude::FileEnumeratorExt::next_files_async()]. Note that the asynchronous
18 /// version will return a list of [`FileInfo`][crate::FileInfo] objects, whereas the
19 /// synchronous will only return the next file in the enumerator.
20 ///
21 /// The ordering of returned files is unspecified for non-Unix
22 /// platforms; for more information, see `GLib::Dir::read_name()`. On Unix,
23 /// when operating on local files, returned files will be sorted by
24 /// inode number. Effectively you can assume that the ordering of
25 /// returned files will be stable between successive calls (and
26 /// applications) assuming the directory is unchanged.
27 ///
28 /// If your application needs a specific ordering, such as by name or
29 /// modification time, you will have to implement that in your
30 /// application code.
31 ///
32 /// To close a `GFileEnumerator`, use [`FileEnumeratorExtManual::close()`][crate::prelude::FileEnumeratorExtManual::close()], or
33 /// its asynchronous version, [`FileEnumeratorExt::close_async()`][crate::prelude::FileEnumeratorExt::close_async()]. Once
34 /// a `GFileEnumerator` is closed, no further actions may be performed
35 /// on it, and it should be freed with `GObject::Object::unref()`.
36 ///
37 /// ## Properties
38 ///
39 ///
40 /// #### `container`
41 /// The container that is being enumerated.
42 ///
43 /// Writeable | Construct Only
44 ///
45 /// # Implements
46 ///
47 /// [`FileEnumeratorExt`][trait@crate::prelude::FileEnumeratorExt], [`trait@glib::ObjectExt`], [`FileEnumeratorExtManual`][trait@crate::prelude::FileEnumeratorExtManual]
48 #[doc(alias = "GFileEnumerator")]
49 pub struct FileEnumerator(Object<ffi::GFileEnumerator, ffi::GFileEnumeratorClass>);
50
51 match fn {
52 type_ => || ffi::g_file_enumerator_get_type(),
53 }
54}
55
56impl FileEnumerator {
57 pub const NONE: Option<&'static FileEnumerator> = None;
58}
59
60/// Trait containing all [`struct@FileEnumerator`] methods.
61///
62/// # Implementors
63///
64/// [`FileEnumerator`][struct@crate::FileEnumerator]
65pub trait FileEnumeratorExt: IsA<FileEnumerator> + 'static {
66 /// Asynchronously closes the file enumerator.
67 ///
68 /// If @cancellable is not [`None`], then the operation can be cancelled by
69 /// triggering the cancellable object from another thread. If the operation
70 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned in
71 /// g_file_enumerator_close_finish().
72 /// ## `io_priority`
73 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
74 /// ## `cancellable`
75 /// optional #GCancellable object, [`None`] to ignore.
76 /// ## `callback`
77 /// a #GAsyncReadyCallback
78 /// to call when the request is satisfied
79 #[doc(alias = "g_file_enumerator_close_async")]
80 fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
81 &self,
82 io_priority: glib::Priority,
83 cancellable: Option<&impl IsA<Cancellable>>,
84 callback: P,
85 ) {
86 let main_context = glib::MainContext::ref_thread_default();
87 let is_main_context_owner = main_context.is_owner();
88 let has_acquired_main_context = (!is_main_context_owner)
89 .then(|| main_context.acquire().ok())
90 .flatten();
91 assert!(
92 is_main_context_owner || has_acquired_main_context.is_some(),
93 "Async operations only allowed if the thread is owning the MainContext"
94 );
95
96 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
97 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
98 unsafe extern "C" fn close_async_trampoline<
99 P: FnOnce(Result<(), glib::Error>) + 'static,
100 >(
101 _source_object: *mut glib::gobject_ffi::GObject,
102 res: *mut crate::ffi::GAsyncResult,
103 user_data: glib::ffi::gpointer,
104 ) {
105 let mut error = std::ptr::null_mut();
106 ffi::g_file_enumerator_close_finish(_source_object as *mut _, res, &mut error);
107 let result = if error.is_null() {
108 Ok(())
109 } else {
110 Err(from_glib_full(error))
111 };
112 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
113 Box_::from_raw(user_data as *mut _);
114 let callback: P = callback.into_inner();
115 callback(result);
116 }
117 let callback = close_async_trampoline::<P>;
118 unsafe {
119 ffi::g_file_enumerator_close_async(
120 self.as_ref().to_glib_none().0,
121 io_priority.into_glib(),
122 cancellable.map(|p| p.as_ref()).to_glib_none().0,
123 Some(callback),
124 Box_::into_raw(user_data) as *mut _,
125 );
126 }
127 }
128
129 fn close_future(
130 &self,
131 io_priority: glib::Priority,
132 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
133 Box_::pin(crate::GioFuture::new(
134 self,
135 move |obj, cancellable, send| {
136 obj.close_async(io_priority, Some(cancellable), move |res| {
137 send.resolve(res);
138 });
139 },
140 ))
141 }
142
143 /// Return a new #GFile which refers to the file named by @info in the source
144 /// directory of @self. This function is primarily intended to be used
145 /// inside loops with g_file_enumerator_next_file().
146 ///
147 /// To use this, [`FILE_ATTRIBUTE_STANDARD_NAME`][crate::FILE_ATTRIBUTE_STANDARD_NAME] must have been listed in the
148 /// attributes list used when creating the #GFileEnumerator.
149 ///
150 /// This is a convenience method that's equivalent to:
151 ///
152 ///
153 /// **⚠️ The following code is in C ⚠️**
154 ///
155 /// ```C
156 /// gchar *name = g_file_info_get_name (info);
157 /// GFile *child = g_file_get_child (g_file_enumerator_get_container (enumr),
158 /// name);
159 /// ```
160 /// ## `info`
161 /// a #GFileInfo gotten from g_file_enumerator_next_file()
162 /// or the async equivalents.
163 ///
164 /// # Returns
165 ///
166 /// a #GFile for the #GFileInfo passed it.
167 #[doc(alias = "g_file_enumerator_get_child")]
168 #[doc(alias = "get_child")]
169 fn child(&self, info: &FileInfo) -> File {
170 unsafe {
171 from_glib_full(ffi::g_file_enumerator_get_child(
172 self.as_ref().to_glib_none().0,
173 info.to_glib_none().0,
174 ))
175 }
176 }
177
178 /// Get the #GFile container which is being enumerated.
179 ///
180 /// # Returns
181 ///
182 /// the #GFile which is being enumerated.
183 #[doc(alias = "g_file_enumerator_get_container")]
184 #[doc(alias = "get_container")]
185 fn container(&self) -> File {
186 unsafe {
187 from_glib_none(ffi::g_file_enumerator_get_container(
188 self.as_ref().to_glib_none().0,
189 ))
190 }
191 }
192
193 /// Checks if the file enumerator has pending operations.
194 ///
195 /// # Returns
196 ///
197 /// [`true`] if the @self has pending operations.
198 #[doc(alias = "g_file_enumerator_has_pending")]
199 fn has_pending(&self) -> bool {
200 unsafe {
201 from_glib(ffi::g_file_enumerator_has_pending(
202 self.as_ref().to_glib_none().0,
203 ))
204 }
205 }
206
207 /// Checks if the file enumerator has been closed.
208 ///
209 /// # Returns
210 ///
211 /// [`true`] if the @self is closed.
212 #[doc(alias = "g_file_enumerator_is_closed")]
213 fn is_closed(&self) -> bool {
214 unsafe {
215 from_glib(ffi::g_file_enumerator_is_closed(
216 self.as_ref().to_glib_none().0,
217 ))
218 }
219 }
220
221 /// Returns information for the next file in the enumerated object.
222 /// Will block until the information is available. The #GFileInfo
223 /// returned from this function will contain attributes that match the
224 /// attribute string that was passed when the #GFileEnumerator was created.
225 ///
226 /// See the documentation of #GFileEnumerator for information about the
227 /// order of returned files.
228 ///
229 /// On error, returns [`None`] and sets @error to the error. If the
230 /// enumerator is at the end, [`None`] will be returned and @error will
231 /// be unset.
232 /// ## `cancellable`
233 /// optional #GCancellable object, [`None`] to ignore.
234 ///
235 /// # Returns
236 ///
237 /// A #GFileInfo or [`None`] on error
238 /// or end of enumerator. Free the returned object with
239 /// g_object_unref() when no longer needed.
240 #[doc(alias = "g_file_enumerator_next_file")]
241 fn next_file(
242 &self,
243 cancellable: Option<&impl IsA<Cancellable>>,
244 ) -> Result<Option<FileInfo>, glib::Error> {
245 unsafe {
246 let mut error = std::ptr::null_mut();
247 let ret = ffi::g_file_enumerator_next_file(
248 self.as_ref().to_glib_none().0,
249 cancellable.map(|p| p.as_ref()).to_glib_none().0,
250 &mut error,
251 );
252 if error.is_null() {
253 Ok(from_glib_full(ret))
254 } else {
255 Err(from_glib_full(error))
256 }
257 }
258 }
259
260 /// Request information for a number of files from the enumerator asynchronously.
261 /// When all I/O for the operation is finished the @callback will be called with
262 /// the requested information.
263 ///
264 /// See the documentation of #GFileEnumerator for information about the
265 /// order of returned files.
266 ///
267 /// Once the end of the enumerator is reached, or if an error occurs, the
268 /// @callback will be called with an empty list. In this case, the previous call
269 /// to g_file_enumerator_next_files_async() will typically have returned fewer
270 /// than @num_files items.
271 ///
272 /// If a request is cancelled the callback will be called with
273 /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
274 ///
275 /// This leads to the following pseudo-code usage:
276 ///
277 /// ```text
278 /// g_autoptr(GFile) dir = get_directory ();
279 /// g_autoptr(GFileEnumerator) enumerator = NULL;
280 /// g_autolist(GFileInfo) files = NULL;
281 /// g_autoptr(GError) local_error = NULL;
282 ///
283 /// enumerator = yield g_file_enumerate_children_async (dir,
284 /// G_FILE_ATTRIBUTE_STANDARD_NAME ","
285 /// G_FILE_ATTRIBUTE_STANDARD_TYPE,
286 /// G_FILE_QUERY_INFO_NONE,
287 /// G_PRIORITY_DEFAULT,
288 /// cancellable,
289 /// …,
290 /// &local_error);
291 /// if (enumerator == NULL)
292 /// g_error ("Error enumerating: %s", local_error->message);
293 ///
294 /// // Loop until no files are returned, either because the end of the enumerator
295 /// // has been reached, or an error was returned.
296 /// do
297 /// {
298 /// files = yield g_file_enumerator_next_files_async (enumerator,
299 /// 5, // number of files to request
300 /// G_PRIORITY_DEFAULT,
301 /// cancellable,
302 /// …,
303 /// &local_error);
304 ///
305 /// // Process the returned files, but don’t assume that exactly 5 were returned.
306 /// for (GList *l = files; l != NULL; l = l->next)
307 /// {
308 /// GFileInfo *info = l->data;
309 /// handle_file_info (info);
310 /// }
311 /// }
312 /// while (files != NULL);
313 ///
314 /// if (local_error != NULL &&
315 /// !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
316 /// g_error ("Error while enumerating: %s", local_error->message);
317 /// ```
318 ///
319 /// During an async request no other sync and async calls are allowed, and will
320 /// result in [`IOErrorEnum::Pending`][crate::IOErrorEnum::Pending] errors.
321 ///
322 /// Any outstanding I/O request with higher priority (lower numerical value) will
323 /// be executed before an outstanding request with lower priority. Default
324 /// priority is `G_PRIORITY_DEFAULT`.
325 /// ## `num_files`
326 /// the number of file info objects to request
327 /// ## `io_priority`
328 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
329 /// ## `cancellable`
330 /// optional #GCancellable object, [`None`] to ignore.
331 /// ## `callback`
332 /// a #GAsyncReadyCallback
333 /// to call when the request is satisfied
334 #[doc(alias = "g_file_enumerator_next_files_async")]
335 fn next_files_async<P: FnOnce(Result<Vec<FileInfo>, glib::Error>) + 'static>(
336 &self,
337 num_files: i32,
338 io_priority: glib::Priority,
339 cancellable: Option<&impl IsA<Cancellable>>,
340 callback: P,
341 ) {
342 let main_context = glib::MainContext::ref_thread_default();
343 let is_main_context_owner = main_context.is_owner();
344 let has_acquired_main_context = (!is_main_context_owner)
345 .then(|| main_context.acquire().ok())
346 .flatten();
347 assert!(
348 is_main_context_owner || has_acquired_main_context.is_some(),
349 "Async operations only allowed if the thread is owning the MainContext"
350 );
351
352 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
353 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
354 unsafe extern "C" fn next_files_async_trampoline<
355 P: FnOnce(Result<Vec<FileInfo>, glib::Error>) + 'static,
356 >(
357 _source_object: *mut glib::gobject_ffi::GObject,
358 res: *mut crate::ffi::GAsyncResult,
359 user_data: glib::ffi::gpointer,
360 ) {
361 let mut error = std::ptr::null_mut();
362 let ret =
363 ffi::g_file_enumerator_next_files_finish(_source_object as *mut _, res, &mut error);
364 let result = if error.is_null() {
365 Ok(FromGlibPtrContainer::from_glib_full(ret))
366 } else {
367 Err(from_glib_full(error))
368 };
369 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
370 Box_::from_raw(user_data as *mut _);
371 let callback: P = callback.into_inner();
372 callback(result);
373 }
374 let callback = next_files_async_trampoline::<P>;
375 unsafe {
376 ffi::g_file_enumerator_next_files_async(
377 self.as_ref().to_glib_none().0,
378 num_files,
379 io_priority.into_glib(),
380 cancellable.map(|p| p.as_ref()).to_glib_none().0,
381 Some(callback),
382 Box_::into_raw(user_data) as *mut _,
383 );
384 }
385 }
386
387 fn next_files_future(
388 &self,
389 num_files: i32,
390 io_priority: glib::Priority,
391 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<FileInfo>, glib::Error>> + 'static>>
392 {
393 Box_::pin(crate::GioFuture::new(
394 self,
395 move |obj, cancellable, send| {
396 obj.next_files_async(num_files, io_priority, Some(cancellable), move |res| {
397 send.resolve(res);
398 });
399 },
400 ))
401 }
402
403 /// Sets the file enumerator as having pending operations.
404 /// ## `pending`
405 /// a boolean value.
406 #[doc(alias = "g_file_enumerator_set_pending")]
407 fn set_pending(&self, pending: bool) {
408 unsafe {
409 ffi::g_file_enumerator_set_pending(self.as_ref().to_glib_none().0, pending.into_glib());
410 }
411 }
412}
413
414impl<O: IsA<FileEnumerator>> FileEnumeratorExt for O {}