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