Skip to main content

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