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