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 [`FileEnumeratorExt::close()`][crate::prelude::FileEnumeratorExt::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    /// Releases all resources used by this enumerator, making the
67    /// enumerator return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed] on all calls.
68    ///
69    /// This will be automatically called when the last reference
70    /// is dropped, but you might want to call this function to make
71    /// sure resources are released as early as possible.
72    /// ## `cancellable`
73    /// optional #GCancellable object, [`None`] to ignore.
74    ///
75    /// # Returns
76    ///
77    /// #TRUE on success or #FALSE on error.
78    #[doc(alias = "g_file_enumerator_close")]
79    fn close(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
80        unsafe {
81            let mut error = std::ptr::null_mut();
82            let is_ok = ffi::g_file_enumerator_close(
83                self.as_ref().to_glib_none().0,
84                cancellable.map(|p| p.as_ref()).to_glib_none().0,
85                &mut error,
86            );
87            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
88            if error.is_null() {
89                Ok(())
90            } else {
91                Err(from_glib_full(error))
92            }
93        }
94    }
95
96    /// Asynchronously closes the file enumerator.
97    ///
98    /// If @cancellable is not [`None`], then the operation can be cancelled by
99    /// triggering the cancellable object from another thread. If the operation
100    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned in
101    /// g_file_enumerator_close_finish().
102    /// ## `io_priority`
103    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
104    /// ## `cancellable`
105    /// optional #GCancellable object, [`None`] to ignore.
106    /// ## `callback`
107    /// a #GAsyncReadyCallback
108    ///   to call when the request is satisfied
109    #[doc(alias = "g_file_enumerator_close_async")]
110    fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
111        &self,
112        io_priority: glib::Priority,
113        cancellable: Option<&impl IsA<Cancellable>>,
114        callback: P,
115    ) {
116        let main_context = glib::MainContext::ref_thread_default();
117        let is_main_context_owner = main_context.is_owner();
118        let has_acquired_main_context = (!is_main_context_owner)
119            .then(|| main_context.acquire().ok())
120            .flatten();
121        assert!(
122            is_main_context_owner || has_acquired_main_context.is_some(),
123            "Async operations only allowed if the thread is owning the MainContext"
124        );
125
126        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
127            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
128        unsafe extern "C" fn close_async_trampoline<
129            P: FnOnce(Result<(), glib::Error>) + 'static,
130        >(
131            _source_object: *mut glib::gobject_ffi::GObject,
132            res: *mut crate::ffi::GAsyncResult,
133            user_data: glib::ffi::gpointer,
134        ) {
135            let mut error = std::ptr::null_mut();
136            ffi::g_file_enumerator_close_finish(_source_object as *mut _, res, &mut error);
137            let result = if error.is_null() {
138                Ok(())
139            } else {
140                Err(from_glib_full(error))
141            };
142            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
143                Box_::from_raw(user_data as *mut _);
144            let callback: P = callback.into_inner();
145            callback(result);
146        }
147        let callback = close_async_trampoline::<P>;
148        unsafe {
149            ffi::g_file_enumerator_close_async(
150                self.as_ref().to_glib_none().0,
151                io_priority.into_glib(),
152                cancellable.map(|p| p.as_ref()).to_glib_none().0,
153                Some(callback),
154                Box_::into_raw(user_data) as *mut _,
155            );
156        }
157    }
158
159    fn close_future(
160        &self,
161        io_priority: glib::Priority,
162    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
163        Box_::pin(crate::GioFuture::new(
164            self,
165            move |obj, cancellable, send| {
166                obj.close_async(io_priority, Some(cancellable), move |res| {
167                    send.resolve(res);
168                });
169            },
170        ))
171    }
172
173    /// Return a new #GFile which refers to the file named by @info in the source
174    /// directory of @self.  This function is primarily intended to be used
175    /// inside loops with g_file_enumerator_next_file().
176    ///
177    /// To use this, [`FILE_ATTRIBUTE_STANDARD_NAME`][crate::FILE_ATTRIBUTE_STANDARD_NAME] must have been listed in the
178    /// attributes list used when creating the #GFileEnumerator.
179    ///
180    /// This is a convenience method that's equivalent to:
181    ///
182    ///
183    /// **⚠️ The following code is in C ⚠️**
184    ///
185    /// ```C
186    ///   gchar *name = g_file_info_get_name (info);
187    ///   GFile *child = g_file_get_child (g_file_enumerator_get_container (enumr),
188    ///                                    name);
189    /// ```
190    /// ## `info`
191    /// a #GFileInfo gotten from g_file_enumerator_next_file()
192    ///   or the async equivalents.
193    ///
194    /// # Returns
195    ///
196    /// a #GFile for the #GFileInfo passed it.
197    #[doc(alias = "g_file_enumerator_get_child")]
198    #[doc(alias = "get_child")]
199    fn child(&self, info: &FileInfo) -> File {
200        unsafe {
201            from_glib_full(ffi::g_file_enumerator_get_child(
202                self.as_ref().to_glib_none().0,
203                info.to_glib_none().0,
204            ))
205        }
206    }
207
208    /// Get the #GFile container which is being enumerated.
209    ///
210    /// # Returns
211    ///
212    /// the #GFile which is being enumerated.
213    #[doc(alias = "g_file_enumerator_get_container")]
214    #[doc(alias = "get_container")]
215    fn container(&self) -> File {
216        unsafe {
217            from_glib_none(ffi::g_file_enumerator_get_container(
218                self.as_ref().to_glib_none().0,
219            ))
220        }
221    }
222
223    /// Checks if the file enumerator has pending operations.
224    ///
225    /// # Returns
226    ///
227    /// [`true`] if the @self has pending operations.
228    #[doc(alias = "g_file_enumerator_has_pending")]
229    fn has_pending(&self) -> bool {
230        unsafe {
231            from_glib(ffi::g_file_enumerator_has_pending(
232                self.as_ref().to_glib_none().0,
233            ))
234        }
235    }
236
237    /// Checks if the file enumerator has been closed.
238    ///
239    /// # Returns
240    ///
241    /// [`true`] if the @self is closed.
242    #[doc(alias = "g_file_enumerator_is_closed")]
243    fn is_closed(&self) -> bool {
244        unsafe {
245            from_glib(ffi::g_file_enumerator_is_closed(
246                self.as_ref().to_glib_none().0,
247            ))
248        }
249    }
250
251    /// Returns information for the next file in the enumerated object.
252    /// Will block until the information is available. The #GFileInfo
253    /// returned from this function will contain attributes that match the
254    /// attribute string that was passed when the #GFileEnumerator was created.
255    ///
256    /// See the documentation of #GFileEnumerator for information about the
257    /// order of returned files.
258    ///
259    /// On error, returns [`None`] and sets @error to the error. If the
260    /// enumerator is at the end, [`None`] will be returned and @error will
261    /// be unset.
262    /// ## `cancellable`
263    /// optional #GCancellable object, [`None`] to ignore.
264    ///
265    /// # Returns
266    ///
267    /// A #GFileInfo or [`None`] on error
268    ///    or end of enumerator.  Free the returned object with
269    ///    g_object_unref() when no longer needed.
270    #[doc(alias = "g_file_enumerator_next_file")]
271    fn next_file(
272        &self,
273        cancellable: Option<&impl IsA<Cancellable>>,
274    ) -> Result<Option<FileInfo>, glib::Error> {
275        unsafe {
276            let mut error = std::ptr::null_mut();
277            let ret = ffi::g_file_enumerator_next_file(
278                self.as_ref().to_glib_none().0,
279                cancellable.map(|p| p.as_ref()).to_glib_none().0,
280                &mut error,
281            );
282            if error.is_null() {
283                Ok(from_glib_full(ret))
284            } else {
285                Err(from_glib_full(error))
286            }
287        }
288    }
289
290    /// Request information for a number of files from the enumerator asynchronously.
291    /// When all I/O for the operation is finished the @callback will be called with
292    /// the requested information.
293    ///
294    /// See the documentation of #GFileEnumerator for information about the
295    /// order of returned files.
296    ///
297    /// Once the end of the enumerator is reached, or if an error occurs, the
298    /// @callback will be called with an empty list. In this case, the previous call
299    /// to g_file_enumerator_next_files_async() will typically have returned fewer
300    /// than @num_files items.
301    ///
302    /// If a request is cancelled the callback will be called with
303    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
304    ///
305    /// This leads to the following pseudo-code usage:
306    ///
307    /// ```text
308    /// g_autoptr(GFile) dir = get_directory ();
309    /// g_autoptr(GFileEnumerator) enumerator = NULL;
310    /// g_autolist(GFileInfo) files = NULL;
311    /// g_autoptr(GError) local_error = NULL;
312    ///
313    /// enumerator = yield g_file_enumerate_children_async (dir,
314    ///                                                     G_FILE_ATTRIBUTE_STANDARD_NAME ","
315    ///                                                     G_FILE_ATTRIBUTE_STANDARD_TYPE,
316    ///                                                     G_FILE_QUERY_INFO_NONE,
317    ///                                                     G_PRIORITY_DEFAULT,
318    ///                                                     cancellable,
319    ///                                                     …,
320    ///                                                     &local_error);
321    /// if (enumerator == NULL)
322    ///   g_error ("Error enumerating: %s", local_error->message);
323    ///
324    /// // Loop until no files are returned, either because the end of the enumerator
325    /// // has been reached, or an error was returned.
326    /// do
327    ///   {
328    ///     files = yield g_file_enumerator_next_files_async (enumerator,
329    ///                                                       5,  // number of files to request
330    ///                                                       G_PRIORITY_DEFAULT,
331    ///                                                       cancellable,
332    ///                                                       …,
333    ///                                                       &local_error);
334    ///
335    ///     // Process the returned files, but don’t assume that exactly 5 were returned.
336    ///     for (GList *l = files; l != NULL; l = l->next)
337    ///       {
338    ///         GFileInfo *info = l->data;
339    ///         handle_file_info (info);
340    ///       }
341    ///   }
342    /// while (files != NULL);
343    ///
344    /// if (local_error != NULL &&
345    ///     !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
346    ///   g_error ("Error while enumerating: %s", local_error->message);
347    /// ```
348    ///
349    /// During an async request no other sync and async calls are allowed, and will
350    /// result in [`IOErrorEnum::Pending`][crate::IOErrorEnum::Pending] errors.
351    ///
352    /// Any outstanding I/O request with higher priority (lower numerical value) will
353    /// be executed before an outstanding request with lower priority. Default
354    /// priority is `G_PRIORITY_DEFAULT`.
355    /// ## `num_files`
356    /// the number of file info objects to request
357    /// ## `io_priority`
358    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
359    /// ## `cancellable`
360    /// optional #GCancellable object, [`None`] to ignore.
361    /// ## `callback`
362    /// a #GAsyncReadyCallback
363    ///   to call when the request is satisfied
364    #[doc(alias = "g_file_enumerator_next_files_async")]
365    fn next_files_async<P: FnOnce(Result<Vec<FileInfo>, glib::Error>) + 'static>(
366        &self,
367        num_files: i32,
368        io_priority: glib::Priority,
369        cancellable: Option<&impl IsA<Cancellable>>,
370        callback: P,
371    ) {
372        let main_context = glib::MainContext::ref_thread_default();
373        let is_main_context_owner = main_context.is_owner();
374        let has_acquired_main_context = (!is_main_context_owner)
375            .then(|| main_context.acquire().ok())
376            .flatten();
377        assert!(
378            is_main_context_owner || has_acquired_main_context.is_some(),
379            "Async operations only allowed if the thread is owning the MainContext"
380        );
381
382        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
383            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
384        unsafe extern "C" fn next_files_async_trampoline<
385            P: FnOnce(Result<Vec<FileInfo>, glib::Error>) + 'static,
386        >(
387            _source_object: *mut glib::gobject_ffi::GObject,
388            res: *mut crate::ffi::GAsyncResult,
389            user_data: glib::ffi::gpointer,
390        ) {
391            let mut error = std::ptr::null_mut();
392            let ret =
393                ffi::g_file_enumerator_next_files_finish(_source_object as *mut _, res, &mut error);
394            let result = if error.is_null() {
395                Ok(FromGlibPtrContainer::from_glib_full(ret))
396            } else {
397                Err(from_glib_full(error))
398            };
399            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
400                Box_::from_raw(user_data as *mut _);
401            let callback: P = callback.into_inner();
402            callback(result);
403        }
404        let callback = next_files_async_trampoline::<P>;
405        unsafe {
406            ffi::g_file_enumerator_next_files_async(
407                self.as_ref().to_glib_none().0,
408                num_files,
409                io_priority.into_glib(),
410                cancellable.map(|p| p.as_ref()).to_glib_none().0,
411                Some(callback),
412                Box_::into_raw(user_data) as *mut _,
413            );
414        }
415    }
416
417    fn next_files_future(
418        &self,
419        num_files: i32,
420        io_priority: glib::Priority,
421    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<FileInfo>, glib::Error>> + 'static>>
422    {
423        Box_::pin(crate::GioFuture::new(
424            self,
425            move |obj, cancellable, send| {
426                obj.next_files_async(num_files, io_priority, Some(cancellable), move |res| {
427                    send.resolve(res);
428                });
429            },
430        ))
431    }
432
433    /// Sets the file enumerator as having pending operations.
434    /// ## `pending`
435    /// a boolean value.
436    #[doc(alias = "g_file_enumerator_set_pending")]
437    fn set_pending(&self, pending: bool) {
438        unsafe {
439            ffi::g_file_enumerator_set_pending(self.as_ref().to_glib_none().0, pending.into_glib());
440        }
441    }
442}
443
444impl<O: IsA<FileEnumerator>> FileEnumeratorExt for O {}