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 {}