Skip to main content

gio/auto/
file.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::{
6    AppInfo, AsyncResult, Cancellable, DriveStartFlags, FileAttributeInfoList, FileCopyFlags,
7    FileCreateFlags, FileEnumerator, FileIOStream, FileInfo, FileInputStream, FileMeasureFlags,
8    FileMonitor, FileMonitorFlags, FileOutputStream, FileQueryInfoFlags, FileType, Mount,
9    MountMountFlags, MountOperation, MountUnmountFlags, ffi,
10};
11use glib::{prelude::*, translate::*};
12use std::{boxed::Box as Box_, pin::Pin};
13
14glib::wrapper! {
15    /// `GFile` is a high level abstraction for manipulating files on a
16    /// virtual file system. `GFile`s are lightweight, immutable objects
17    /// that do no I/O upon creation. It is necessary to understand that
18    /// `GFile` objects do not represent files, merely an identifier for a
19    /// file. All file content I/O is implemented as streaming operations
20    /// (see [`InputStream`][crate::InputStream] and [`OutputStream`][crate::OutputStream]).
21    ///
22    /// To construct a `GFile`, you can use:
23    ///
24    /// - [`for_path()`][Self::for_path()] if you have a path.
25    /// - [`for_uri()`][Self::for_uri()] if you have a URI.
26    /// - [`for_commandline_arg()`][Self::for_commandline_arg()] or
27    ///   [`for_commandline_arg_and_cwd()`][Self::for_commandline_arg_and_cwd()] for a command line
28    ///   argument.
29    /// - [`new_tmp()`][Self::new_tmp()] to create a temporary file from a template.
30    /// - [`new_tmp_async()`][Self::new_tmp_async()] to asynchronously create a temporary file.
31    /// - [`new_tmp_dir_async()`][Self::new_tmp_dir_async()] to asynchronously create a temporary
32    ///   directory.
33    /// - [`for_parse_name()`][Self::for_parse_name()] from a UTF-8 string gotten from
34    ///   [`FileExt::parse_name()`][crate::prelude::FileExt::parse_name()].
35    /// - `Gio::File::new_build_filename()` or [`new_build_filenamev()`][Self::new_build_filenamev()]
36    ///   to create a file from path elements.
37    ///
38    /// One way to think of a `GFile` is as an abstraction of a pathname. For
39    /// normal files the system pathname is what is stored internally, but as
40    /// `GFile`s are extensible it could also be something else that corresponds
41    /// to a pathname in a userspace implementation of a filesystem.
42    ///
43    /// `GFile`s make up hierarchies of directories and files that correspond to
44    /// the files on a filesystem. You can move through the file system with
45    /// `GFile` using [`FileExt::parent()`][crate::prelude::FileExt::parent()] to get an identifier for the
46    /// parent directory, [`FileExt::child()`][crate::prelude::FileExt::child()] to get a child within a
47    /// directory, and [`FileExt::resolve_relative_path()`][crate::prelude::FileExt::resolve_relative_path()] to resolve a relative
48    /// path between two `GFile`s. There can be multiple hierarchies, so you may not
49    /// end up at the same root if you repeatedly call [`FileExt::parent()`][crate::prelude::FileExt::parent()]
50    /// on two different files.
51    ///
52    /// All `GFile`s have a basename (get with [`FileExt::basename()`][crate::prelude::FileExt::basename()]). These
53    /// names are byte strings that are used to identify the file on the filesystem
54    /// (relative to its parent directory) and there is no guarantees that they
55    /// have any particular charset encoding or even make any sense at all. If
56    /// you want to use filenames in a user interface you should use the display
57    /// name that you can get by requesting the
58    /// `G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME` attribute with
59    /// [`FileExt::query_info()`][crate::prelude::FileExt::query_info()]. This is guaranteed to be in UTF-8 and can be
60    /// used in a user interface. But always store the real basename or the `GFile`
61    /// to use to actually access the file, because there is no way to go from a
62    /// display name to the actual name.
63    ///
64    /// Using `GFile` as an identifier has the same weaknesses as using a path
65    /// in that there may be multiple aliases for the same file. For instance,
66    /// hard or soft links may cause two different `GFile`s to refer to the same
67    /// file. Other possible causes for aliases are: case insensitive filesystems,
68    /// short and long names on FAT/NTFS, or bind mounts in Linux. If you want to
69    /// check if two `GFile`s point to the same file you can query for the
70    /// `G_FILE_ATTRIBUTE_ID_FILE` attribute. Note that `GFile` does some trivial
71    /// canonicalization of pathnames passed in, so that trivial differences in
72    /// the path string used at creation (duplicated slashes, slash at end of
73    /// path, `.` or `..` path segments, etc) does not create different `GFile`s.
74    ///
75    /// Many `GFile` operations have both synchronous and asynchronous versions
76    /// to suit your application. Asynchronous versions of synchronous functions
77    /// simply have `_async()` appended to their function names. The asynchronous
78    /// I/O functions call a `callback::Gio::AsyncReadyCallback which is then used to
79    /// finalize the operation, producing a [`AsyncResult`][crate::AsyncResult] which is then
80    /// passed to the function’s matching `_finish()` operation.
81    ///
82    /// It is highly recommended to use asynchronous calls when running within a
83    /// shared main loop, such as in the main thread of an application. This avoids
84    /// I/O operations blocking other sources on the main loop from being dispatched.
85    /// Synchronous I/O operations should be performed from worker threads. See the
86    /// [introduction to asynchronous programming section](overview.html#asynchronous-programming)
87    /// for more.
88    ///
89    /// Some `GFile` operations almost always take a noticeable amount of time, and
90    /// so do not have synchronous analogs. Notable cases include:
91    ///
92    /// - [`FileExt::mount_mountable()`][crate::prelude::FileExt::mount_mountable()] to mount a mountable file.
93    /// - [`FileExt::unmount_mountable_with_operation()`][crate::prelude::FileExt::unmount_mountable_with_operation()] to unmount a mountable
94    ///   file.
95    /// - [`FileExt::eject_mountable_with_operation()`][crate::prelude::FileExt::eject_mountable_with_operation()] to eject a mountable file.
96    ///
97    /// ## Entity Tags
98    ///
99    /// One notable feature of `GFile`s are entity tags, or ‘etags’ for
100    /// short. Entity tags are somewhat like a more abstract version of the
101    /// traditional mtime, and can be used to quickly determine if the file
102    /// has been modified from the version on the file system. See the
103    /// description of HTTP ETags in
104    /// [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-etag).
105    /// `GFile` Entity Tags are a very similar concept.
106    ///
107    /// # Implements
108    ///
109    /// [`FileExt`][trait@crate::prelude::FileExt], [`FileExtManual`][trait@crate::prelude::FileExtManual]
110    #[doc(alias = "GFile")]
111    pub struct File(Interface<ffi::GFile, ffi::GFileIface>);
112
113    match fn {
114        type_ => || ffi::g_file_get_type(),
115    }
116}
117
118impl File {
119    pub const NONE: Option<&'static File> = None;
120
121    //#[doc(alias = "g_file_new_build_filename")]
122    //pub fn new_build_filename(first_element: impl AsRef<std::path::Path>, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> File {
123    //    unsafe { TODO: call ffi:g_file_new_build_filename() }
124    //}
125
126    /// Constructs a #GFile from a vector of elements using the correct
127    /// separator for filenames.
128    ///
129    /// Using this function is equivalent to calling g_build_filenamev(),
130    /// followed by g_file_new_for_path() on the result.
131    /// ## `args`
132    /// [`None`]-terminated
133    ///   array of strings containing the path elements.
134    ///
135    /// # Returns
136    ///
137    /// a new #GFile
138    #[cfg(feature = "v2_78")]
139    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
140    #[doc(alias = "g_file_new_build_filenamev")]
141    pub fn new_build_filenamev(args: &[&std::path::Path]) -> File {
142        unsafe { from_glib_full(ffi::g_file_new_build_filenamev(args.to_glib_none().0)) }
143    }
144
145    /// Creates a #GFile with the given argument from the command line.
146    /// The value of @arg can be either a URI, an absolute path or a
147    /// relative path resolved relative to the current working directory.
148    /// This operation never fails, but the returned object might not
149    /// support any I/O operation if @arg points to a malformed path.
150    ///
151    /// Note that on Windows, this function expects its argument to be in
152    /// UTF-8 -- not the system code page.  This means that you
153    /// should not use this function with string from argv as it is passed
154    /// to main().  g_win32_get_command_line() will return a UTF-8 version of
155    /// the commandline.  #GApplication also uses UTF-8 but
156    /// g_application_command_line_create_file_for_arg() may be more useful
157    /// for you there.  It is also always possible to use this function with
158    /// #GOptionContext arguments of type [`glib::OptionArg::Filename`][crate::glib::OptionArg::Filename].
159    /// ## `arg`
160    /// a command line string
161    ///
162    /// # Returns
163    ///
164    /// a new #GFile.
165    ///   Free the returned object with g_object_unref().
166    #[doc(alias = "g_file_new_for_commandline_arg")]
167    #[doc(alias = "new_for_commandline_arg")]
168    pub fn for_commandline_arg(arg: impl AsRef<std::ffi::OsStr>) -> File {
169        unsafe {
170            from_glib_full(ffi::g_file_new_for_commandline_arg(
171                arg.as_ref().to_glib_none().0,
172            ))
173        }
174    }
175
176    /// Creates a #GFile with the given argument from the command line.
177    ///
178    /// This function is similar to g_file_new_for_commandline_arg() except
179    /// that it allows for passing the current working directory as an
180    /// argument instead of using the current working directory of the
181    /// process.
182    ///
183    /// This is useful if the commandline argument was given in a context
184    /// other than the invocation of the current process.
185    ///
186    /// See also g_application_command_line_create_file_for_arg().
187    /// ## `arg`
188    /// a command line string
189    /// ## `cwd`
190    /// the current working directory of the commandline
191    ///
192    /// # Returns
193    ///
194    /// a new #GFile
195    #[doc(alias = "g_file_new_for_commandline_arg_and_cwd")]
196    #[doc(alias = "new_for_commandline_arg_and_cwd")]
197    pub fn for_commandline_arg_and_cwd(
198        arg: impl AsRef<std::ffi::OsStr>,
199        cwd: impl AsRef<std::path::Path>,
200    ) -> File {
201        unsafe {
202            from_glib_full(ffi::g_file_new_for_commandline_arg_and_cwd(
203                arg.as_ref().to_glib_none().0,
204                cwd.as_ref().to_glib_none().0,
205            ))
206        }
207    }
208
209    /// Constructs a #GFile for a given path. This operation never
210    /// fails, but the returned object might not support any I/O
211    /// operation if @path is malformed.
212    /// ## `path`
213    /// a string containing a relative or absolute path.
214    ///   The string must be encoded in the glib filename encoding.
215    ///
216    /// # Returns
217    ///
218    /// a new #GFile for the given @path.
219    ///   Free the returned object with g_object_unref().
220    #[doc(alias = "g_file_new_for_path")]
221    #[doc(alias = "new_for_path")]
222    pub fn for_path(path: impl AsRef<std::path::Path>) -> File {
223        unsafe { from_glib_full(ffi::g_file_new_for_path(path.as_ref().to_glib_none().0)) }
224    }
225
226    /// Constructs a #GFile for a given URI. This operation never
227    /// fails, but the returned object might not support any I/O
228    /// operation if @uri is malformed or if the uri type is
229    /// not supported.
230    /// ## `uri`
231    /// a UTF-8 string containing a URI
232    ///
233    /// # Returns
234    ///
235    /// a new #GFile for the given @uri.
236    ///   Free the returned object with g_object_unref().
237    #[doc(alias = "g_file_new_for_uri")]
238    #[doc(alias = "new_for_uri")]
239    pub fn for_uri(uri: &str) -> File {
240        unsafe { from_glib_full(ffi::g_file_new_for_uri(uri.to_glib_none().0)) }
241    }
242
243    /// Opens a file in the preferred directory for temporary files (as
244    /// returned by g_get_tmp_dir()) and returns a #GFile and
245    /// #GFileIOStream pointing to it.
246    ///
247    /// @tmpl should be a string in the GLib file name encoding
248    /// containing a sequence of six 'X' characters, and containing no
249    /// directory components. If it is [`None`], a default template is used.
250    ///
251    /// Unlike the other #GFile constructors, this will return [`None`] if
252    /// a temporary file could not be created.
253    /// ## `tmpl`
254    /// Template for the file
255    ///   name, as in g_file_open_tmp(), or [`None`] for a default template
256    ///
257    /// # Returns
258    ///
259    /// a new #GFile.
260    ///   Free the returned object with g_object_unref().
261    ///
262    /// ## `iostream`
263    /// on return, a #GFileIOStream for the created file
264    #[doc(alias = "g_file_new_tmp")]
265    pub fn new_tmp(
266        tmpl: Option<impl AsRef<std::path::Path>>,
267    ) -> Result<(File, FileIOStream), glib::Error> {
268        unsafe {
269            let mut iostream = std::ptr::null_mut();
270            let mut error = std::ptr::null_mut();
271            let ret = ffi::g_file_new_tmp(
272                tmpl.as_ref().map(|p| p.as_ref()).to_glib_none().0,
273                &mut iostream,
274                &mut error,
275            );
276            if error.is_null() {
277                Ok((from_glib_full(ret), from_glib_full(iostream)))
278            } else {
279                Err(from_glib_full(error))
280            }
281        }
282    }
283
284    /// Constructs a #GFile with the given @parse_name (i.e. something
285    /// given by g_file_get_parse_name()). This operation never fails,
286    /// but the returned object might not support any I/O operation if
287    /// the @parse_name cannot be parsed.
288    /// ## `parse_name`
289    /// a file name or path to be parsed
290    ///
291    /// # Returns
292    ///
293    /// a new #GFile.
294    #[doc(alias = "g_file_parse_name")]
295    #[doc(alias = "parse_name")]
296    pub fn for_parse_name(parse_name: &str) -> File {
297        unsafe { from_glib_full(ffi::g_file_parse_name(parse_name.to_glib_none().0)) }
298    }
299}
300
301unsafe impl Send for File {}
302unsafe impl Sync for File {}
303
304/// Trait containing all [`struct@File`] methods.
305///
306/// # Implementors
307///
308/// [`File`][struct@crate::File]
309pub trait FileExt: IsA<File> + 'static {
310    /// Gets an output stream for appending data to the file.
311    /// If the file doesn't already exist it is created.
312    ///
313    /// By default files created are generally readable by everyone,
314    /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
315    /// will be made readable only to the current user, to the level that
316    /// is supported on the target filesystem.
317    ///
318    /// If @cancellable is not [`None`], then the operation can be cancelled
319    /// by triggering the cancellable object from another thread. If the
320    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
321    /// returned.
322    ///
323    /// Some file systems don't allow all file names, and may return an
324    /// [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename] error. If the file is a directory the
325    /// [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory] error will be returned. Other errors are
326    /// possible too, and depend on what kind of filesystem the file is on.
327    /// ## `flags`
328    /// a set of #GFileCreateFlags
329    /// ## `cancellable`
330    /// optional #GCancellable object,
331    ///   [`None`] to ignore
332    ///
333    /// # Returns
334    ///
335    /// a #GFileOutputStream, or [`None`] on error.
336    ///   Free the returned object with g_object_unref().
337    #[doc(alias = "g_file_append_to")]
338    fn append_to(
339        &self,
340        flags: FileCreateFlags,
341        cancellable: Option<&impl IsA<Cancellable>>,
342    ) -> Result<FileOutputStream, glib::Error> {
343        unsafe {
344            let mut error = std::ptr::null_mut();
345            let ret = ffi::g_file_append_to(
346                self.as_ref().to_glib_none().0,
347                flags.into_glib(),
348                cancellable.map(|p| p.as_ref()).to_glib_none().0,
349                &mut error,
350            );
351            if error.is_null() {
352                Ok(from_glib_full(ret))
353            } else {
354                Err(from_glib_full(error))
355            }
356        }
357    }
358
359    /// Asynchronously opens @self for appending.
360    ///
361    /// For more details, see g_file_append_to() which is
362    /// the synchronous version of this call.
363    ///
364    /// When the operation is finished, @callback will be called.
365    /// You can then call g_file_append_to_finish() to get the result
366    /// of the operation.
367    /// ## `flags`
368    /// a set of #GFileCreateFlags
369    /// ## `io_priority`
370    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
371    /// ## `cancellable`
372    /// optional #GCancellable object,
373    ///   [`None`] to ignore
374    /// ## `callback`
375    /// a #GAsyncReadyCallback
376    ///   to call when the request is satisfied
377    #[doc(alias = "g_file_append_to_async")]
378    fn append_to_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
379        &self,
380        flags: FileCreateFlags,
381        io_priority: glib::Priority,
382        cancellable: Option<&impl IsA<Cancellable>>,
383        callback: P,
384    ) {
385        let main_context = glib::MainContext::ref_thread_default();
386        let is_main_context_owner = main_context.is_owner();
387        let has_acquired_main_context = (!is_main_context_owner)
388            .then(|| main_context.acquire().ok())
389            .flatten();
390        assert!(
391            is_main_context_owner || has_acquired_main_context.is_some(),
392            "Async operations only allowed if the thread is owning the MainContext"
393        );
394
395        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
396            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
397        unsafe extern "C" fn append_to_async_trampoline<
398            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
399        >(
400            _source_object: *mut glib::gobject_ffi::GObject,
401            res: *mut crate::ffi::GAsyncResult,
402            user_data: glib::ffi::gpointer,
403        ) {
404            unsafe {
405                let mut error = std::ptr::null_mut();
406                let ret = ffi::g_file_append_to_finish(_source_object as *mut _, res, &mut error);
407                let result = if error.is_null() {
408                    Ok(from_glib_full(ret))
409                } else {
410                    Err(from_glib_full(error))
411                };
412                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
413                    Box_::from_raw(user_data as *mut _);
414                let callback: P = callback.into_inner();
415                callback(result);
416            }
417        }
418        let callback = append_to_async_trampoline::<P>;
419        unsafe {
420            ffi::g_file_append_to_async(
421                self.as_ref().to_glib_none().0,
422                flags.into_glib(),
423                io_priority.into_glib(),
424                cancellable.map(|p| p.as_ref()).to_glib_none().0,
425                Some(callback),
426                Box_::into_raw(user_data) as *mut _,
427            );
428        }
429    }
430
431    fn append_to_future(
432        &self,
433        flags: FileCreateFlags,
434        io_priority: glib::Priority,
435    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
436    {
437        Box_::pin(crate::GioFuture::new(
438            self,
439            move |obj, cancellable, send| {
440                obj.append_to_async(flags, io_priority, Some(cancellable), move |res| {
441                    send.resolve(res);
442                });
443            },
444        ))
445    }
446
447    #[cfg(feature = "v2_68")]
448    #[cfg_attr(docsrs, doc(cfg(feature = "v2_68")))]
449    #[doc(alias = "g_file_build_attribute_list_for_copy")]
450    fn build_attribute_list_for_copy(
451        &self,
452        flags: FileCopyFlags,
453        cancellable: Option<&impl IsA<Cancellable>>,
454    ) -> Result<glib::GString, glib::Error> {
455        unsafe {
456            let mut error = std::ptr::null_mut();
457            let ret = ffi::g_file_build_attribute_list_for_copy(
458                self.as_ref().to_glib_none().0,
459                flags.into_glib(),
460                cancellable.map(|p| p.as_ref()).to_glib_none().0,
461                &mut error,
462            );
463            if error.is_null() {
464                Ok(from_glib_full(ret))
465            } else {
466                Err(from_glib_full(error))
467            }
468        }
469    }
470
471    #[doc(alias = "g_file_copy")]
472    fn copy(
473        &self,
474        destination: &impl IsA<File>,
475        flags: FileCopyFlags,
476        cancellable: Option<&impl IsA<Cancellable>>,
477        progress_callback: Option<&mut dyn FnMut(i64, i64)>,
478    ) -> Result<(), glib::Error> {
479        let mut progress_callback_data: Option<&mut dyn FnMut(i64, i64)> = progress_callback;
480        unsafe extern "C" fn progress_callback_func(
481            current_num_bytes: i64,
482            total_num_bytes: i64,
483            data: glib::ffi::gpointer,
484        ) {
485            unsafe {
486                let callback = data as *mut Option<&mut dyn FnMut(i64, i64)>;
487                if let Some(ref mut callback) = *callback {
488                    callback(current_num_bytes, total_num_bytes)
489                } else {
490                    panic!("cannot get closure...")
491                }
492            }
493        }
494        let progress_callback = if progress_callback_data.is_some() {
495            Some(progress_callback_func as _)
496        } else {
497            None
498        };
499        let super_callback0: &mut Option<&mut dyn FnMut(i64, i64)> = &mut progress_callback_data;
500        unsafe {
501            let mut error = std::ptr::null_mut();
502            let is_ok = ffi::g_file_copy(
503                self.as_ref().to_glib_none().0,
504                destination.as_ref().to_glib_none().0,
505                flags.into_glib(),
506                cancellable.map(|p| p.as_ref()).to_glib_none().0,
507                progress_callback,
508                super_callback0 as *mut _ as *mut _,
509                &mut error,
510            );
511            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
512            if error.is_null() {
513                Ok(())
514            } else {
515                Err(from_glib_full(error))
516            }
517        }
518    }
519
520    /// Copies the file attributes from @self to @destination.
521    ///
522    /// Normally only a subset of the file attributes are copied,
523    /// those that are copies in a normal file copy operation
524    /// (which for instance does not include e.g. owner). However
525    /// if [`FileCopyFlags::ALL_METADATA`][crate::FileCopyFlags::ALL_METADATA] is specified in @flags, then
526    /// all the metadata that is possible to copy is copied. This
527    /// is useful when implementing move by copy + delete source.
528    /// ## `destination`
529    /// a #GFile to copy attributes to
530    /// ## `flags`
531    /// a set of #GFileCopyFlags
532    /// ## `cancellable`
533    /// optional #GCancellable object,
534    ///   [`None`] to ignore
535    ///
536    /// # Returns
537    ///
538    /// [`true`] if the attributes were copied successfully,
539    ///   [`false`] otherwise.
540    #[doc(alias = "g_file_copy_attributes")]
541    fn copy_attributes(
542        &self,
543        destination: &impl IsA<File>,
544        flags: FileCopyFlags,
545        cancellable: Option<&impl IsA<Cancellable>>,
546    ) -> Result<(), glib::Error> {
547        unsafe {
548            let mut error = std::ptr::null_mut();
549            let is_ok = ffi::g_file_copy_attributes(
550                self.as_ref().to_glib_none().0,
551                destination.as_ref().to_glib_none().0,
552                flags.into_glib(),
553                cancellable.map(|p| p.as_ref()).to_glib_none().0,
554                &mut error,
555            );
556            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
557            if error.is_null() {
558                Ok(())
559            } else {
560                Err(from_glib_full(error))
561            }
562        }
563    }
564
565    /// Creates a new file and returns an output stream for writing to it.
566    /// The file must not already exist.
567    ///
568    /// By default files created are generally readable by everyone,
569    /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
570    /// will be made readable only to the current user, to the level
571    /// that is supported on the target filesystem.
572    ///
573    /// If @cancellable is not [`None`], then the operation can be cancelled
574    /// by triggering the cancellable object from another thread. If the
575    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
576    /// returned.
577    ///
578    /// If a file or directory with this name already exists the
579    /// [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] error will be returned. Some file systems don't
580    /// allow all file names, and may return an [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename]
581    /// error, and if the name is to long [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong] will
582    /// be returned. Other errors are possible too, and depend on what kind
583    /// of filesystem the file is on.
584    /// ## `flags`
585    /// a set of #GFileCreateFlags
586    /// ## `cancellable`
587    /// optional #GCancellable object,
588    ///   [`None`] to ignore
589    ///
590    /// # Returns
591    ///
592    /// a #GFileOutputStream for the newly created
593    ///   file, or [`None`] on error.
594    ///   Free the returned object with g_object_unref().
595    #[doc(alias = "g_file_create")]
596    fn create(
597        &self,
598        flags: FileCreateFlags,
599        cancellable: Option<&impl IsA<Cancellable>>,
600    ) -> Result<FileOutputStream, glib::Error> {
601        unsafe {
602            let mut error = std::ptr::null_mut();
603            let ret = ffi::g_file_create(
604                self.as_ref().to_glib_none().0,
605                flags.into_glib(),
606                cancellable.map(|p| p.as_ref()).to_glib_none().0,
607                &mut error,
608            );
609            if error.is_null() {
610                Ok(from_glib_full(ret))
611            } else {
612                Err(from_glib_full(error))
613            }
614        }
615    }
616
617    /// Asynchronously creates a new file and returns an output stream
618    /// for writing to it. The file must not already exist.
619    ///
620    /// For more details, see g_file_create() which is
621    /// the synchronous version of this call.
622    ///
623    /// When the operation is finished, @callback will be called.
624    /// You can then call g_file_create_finish() to get the result
625    /// of the operation.
626    /// ## `flags`
627    /// a set of #GFileCreateFlags
628    /// ## `io_priority`
629    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
630    /// ## `cancellable`
631    /// optional #GCancellable object,
632    ///   [`None`] to ignore
633    /// ## `callback`
634    /// a #GAsyncReadyCallback
635    ///   to call when the request is satisfied
636    #[doc(alias = "g_file_create_async")]
637    fn create_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
638        &self,
639        flags: FileCreateFlags,
640        io_priority: glib::Priority,
641        cancellable: Option<&impl IsA<Cancellable>>,
642        callback: P,
643    ) {
644        let main_context = glib::MainContext::ref_thread_default();
645        let is_main_context_owner = main_context.is_owner();
646        let has_acquired_main_context = (!is_main_context_owner)
647            .then(|| main_context.acquire().ok())
648            .flatten();
649        assert!(
650            is_main_context_owner || has_acquired_main_context.is_some(),
651            "Async operations only allowed if the thread is owning the MainContext"
652        );
653
654        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
655            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
656        unsafe extern "C" fn create_async_trampoline<
657            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
658        >(
659            _source_object: *mut glib::gobject_ffi::GObject,
660            res: *mut crate::ffi::GAsyncResult,
661            user_data: glib::ffi::gpointer,
662        ) {
663            unsafe {
664                let mut error = std::ptr::null_mut();
665                let ret = ffi::g_file_create_finish(_source_object as *mut _, res, &mut error);
666                let result = if error.is_null() {
667                    Ok(from_glib_full(ret))
668                } else {
669                    Err(from_glib_full(error))
670                };
671                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
672                    Box_::from_raw(user_data as *mut _);
673                let callback: P = callback.into_inner();
674                callback(result);
675            }
676        }
677        let callback = create_async_trampoline::<P>;
678        unsafe {
679            ffi::g_file_create_async(
680                self.as_ref().to_glib_none().0,
681                flags.into_glib(),
682                io_priority.into_glib(),
683                cancellable.map(|p| p.as_ref()).to_glib_none().0,
684                Some(callback),
685                Box_::into_raw(user_data) as *mut _,
686            );
687        }
688    }
689
690    fn create_future(
691        &self,
692        flags: FileCreateFlags,
693        io_priority: glib::Priority,
694    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
695    {
696        Box_::pin(crate::GioFuture::new(
697            self,
698            move |obj, cancellable, send| {
699                obj.create_async(flags, io_priority, Some(cancellable), move |res| {
700                    send.resolve(res);
701                });
702            },
703        ))
704    }
705
706    /// Creates a new file and returns a stream for reading and
707    /// writing to it. The file must not already exist.
708    ///
709    /// By default files created are generally readable by everyone,
710    /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
711    /// will be made readable only to the current user, to the level
712    /// that is supported on the target filesystem.
713    ///
714    /// If @cancellable is not [`None`], then the operation can be cancelled
715    /// by triggering the cancellable object from another thread. If the
716    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
717    /// returned.
718    ///
719    /// If a file or directory with this name already exists, the
720    /// [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] error will be returned. Some file systems don't
721    /// allow all file names, and may return an [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename]
722    /// error, and if the name is too long, [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong]
723    /// will be returned. Other errors are possible too, and depend on what
724    /// kind of filesystem the file is on.
725    ///
726    /// Note that in many non-local file cases read and write streams are
727    /// not supported, so make sure you really need to do read and write
728    /// streaming, rather than just opening for reading or writing.
729    /// ## `flags`
730    /// a set of #GFileCreateFlags
731    /// ## `cancellable`
732    /// optional #GCancellable object,
733    ///   [`None`] to ignore
734    ///
735    /// # Returns
736    ///
737    /// a #GFileIOStream for the newly created
738    ///   file, or [`None`] on error.
739    ///   Free the returned object with g_object_unref().
740    #[doc(alias = "g_file_create_readwrite")]
741    fn create_readwrite(
742        &self,
743        flags: FileCreateFlags,
744        cancellable: Option<&impl IsA<Cancellable>>,
745    ) -> Result<FileIOStream, glib::Error> {
746        unsafe {
747            let mut error = std::ptr::null_mut();
748            let ret = ffi::g_file_create_readwrite(
749                self.as_ref().to_glib_none().0,
750                flags.into_glib(),
751                cancellable.map(|p| p.as_ref()).to_glib_none().0,
752                &mut error,
753            );
754            if error.is_null() {
755                Ok(from_glib_full(ret))
756            } else {
757                Err(from_glib_full(error))
758            }
759        }
760    }
761
762    /// Asynchronously creates a new file and returns a stream
763    /// for reading and writing to it. The file must not already exist.
764    ///
765    /// For more details, see g_file_create_readwrite() which is
766    /// the synchronous version of this call.
767    ///
768    /// When the operation is finished, @callback will be called.
769    /// You can then call g_file_create_readwrite_finish() to get
770    /// the result of the operation.
771    /// ## `flags`
772    /// a set of #GFileCreateFlags
773    /// ## `io_priority`
774    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
775    /// ## `cancellable`
776    /// optional #GCancellable object,
777    ///   [`None`] to ignore
778    /// ## `callback`
779    /// a #GAsyncReadyCallback
780    ///   to call when the request is satisfied
781    #[doc(alias = "g_file_create_readwrite_async")]
782    fn create_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
783        &self,
784        flags: FileCreateFlags,
785        io_priority: glib::Priority,
786        cancellable: Option<&impl IsA<Cancellable>>,
787        callback: P,
788    ) {
789        let main_context = glib::MainContext::ref_thread_default();
790        let is_main_context_owner = main_context.is_owner();
791        let has_acquired_main_context = (!is_main_context_owner)
792            .then(|| main_context.acquire().ok())
793            .flatten();
794        assert!(
795            is_main_context_owner || has_acquired_main_context.is_some(),
796            "Async operations only allowed if the thread is owning the MainContext"
797        );
798
799        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
800            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
801        unsafe extern "C" fn create_readwrite_async_trampoline<
802            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
803        >(
804            _source_object: *mut glib::gobject_ffi::GObject,
805            res: *mut crate::ffi::GAsyncResult,
806            user_data: glib::ffi::gpointer,
807        ) {
808            unsafe {
809                let mut error = std::ptr::null_mut();
810                let ret =
811                    ffi::g_file_create_readwrite_finish(_source_object as *mut _, res, &mut error);
812                let result = if error.is_null() {
813                    Ok(from_glib_full(ret))
814                } else {
815                    Err(from_glib_full(error))
816                };
817                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
818                    Box_::from_raw(user_data as *mut _);
819                let callback: P = callback.into_inner();
820                callback(result);
821            }
822        }
823        let callback = create_readwrite_async_trampoline::<P>;
824        unsafe {
825            ffi::g_file_create_readwrite_async(
826                self.as_ref().to_glib_none().0,
827                flags.into_glib(),
828                io_priority.into_glib(),
829                cancellable.map(|p| p.as_ref()).to_glib_none().0,
830                Some(callback),
831                Box_::into_raw(user_data) as *mut _,
832            );
833        }
834    }
835
836    fn create_readwrite_future(
837        &self,
838        flags: FileCreateFlags,
839        io_priority: glib::Priority,
840    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
841    {
842        Box_::pin(crate::GioFuture::new(
843            self,
844            move |obj, cancellable, send| {
845                obj.create_readwrite_async(flags, io_priority, Some(cancellable), move |res| {
846                    send.resolve(res);
847                });
848            },
849        ))
850    }
851
852    /// Deletes a file. If the @self is a directory, it will only be
853    /// deleted if it is empty. This has the same semantics as g_unlink().
854    ///
855    /// If @self doesn’t exist, [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] will be returned. This allows
856    /// for deletion to be implemented avoiding
857    /// [time-of-check to time-of-use races](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use):
858    ///
859    /// ```text
860    /// g_autoptr(GError) local_error = NULL;
861    /// if (!g_file_delete (my_file, my_cancellable, &local_error) &&
862    ///     !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
863    ///   {
864    ///     // deletion failed for some reason other than the file not existing:
865    ///     // so report the error
866    ///     g_warning ("Failed to delete %s: %s",
867    ///                g_file_peek_path (my_file), local_error->message);
868    ///   }
869    /// ```
870    ///
871    /// If @cancellable is not [`None`], then the operation can be cancelled by
872    /// triggering the cancellable object from another thread. If the operation
873    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
874    /// ## `cancellable`
875    /// optional #GCancellable object,
876    ///   [`None`] to ignore
877    ///
878    /// # Returns
879    ///
880    /// [`true`] if the file was deleted. [`false`] otherwise.
881    #[doc(alias = "g_file_delete")]
882    fn delete(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
883        unsafe {
884            let mut error = std::ptr::null_mut();
885            let is_ok = ffi::g_file_delete(
886                self.as_ref().to_glib_none().0,
887                cancellable.map(|p| p.as_ref()).to_glib_none().0,
888                &mut error,
889            );
890            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
891            if error.is_null() {
892                Ok(())
893            } else {
894                Err(from_glib_full(error))
895            }
896        }
897    }
898
899    /// Asynchronously delete a file. If the @self is a directory, it will
900    /// only be deleted if it is empty.  This has the same semantics as
901    /// g_unlink().
902    /// ## `io_priority`
903    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
904    /// ## `cancellable`
905    /// optional #GCancellable object,
906    ///   [`None`] to ignore
907    /// ## `callback`
908    /// a #GAsyncReadyCallback to call
909    ///   when the request is satisfied
910    #[doc(alias = "g_file_delete_async")]
911    fn delete_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
912        &self,
913        io_priority: glib::Priority,
914        cancellable: Option<&impl IsA<Cancellable>>,
915        callback: P,
916    ) {
917        let main_context = glib::MainContext::ref_thread_default();
918        let is_main_context_owner = main_context.is_owner();
919        let has_acquired_main_context = (!is_main_context_owner)
920            .then(|| main_context.acquire().ok())
921            .flatten();
922        assert!(
923            is_main_context_owner || has_acquired_main_context.is_some(),
924            "Async operations only allowed if the thread is owning the MainContext"
925        );
926
927        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
928            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
929        unsafe extern "C" fn delete_async_trampoline<
930            P: FnOnce(Result<(), glib::Error>) + 'static,
931        >(
932            _source_object: *mut glib::gobject_ffi::GObject,
933            res: *mut crate::ffi::GAsyncResult,
934            user_data: glib::ffi::gpointer,
935        ) {
936            unsafe {
937                let mut error = std::ptr::null_mut();
938                ffi::g_file_delete_finish(_source_object as *mut _, res, &mut error);
939                let result = if error.is_null() {
940                    Ok(())
941                } else {
942                    Err(from_glib_full(error))
943                };
944                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
945                    Box_::from_raw(user_data as *mut _);
946                let callback: P = callback.into_inner();
947                callback(result);
948            }
949        }
950        let callback = delete_async_trampoline::<P>;
951        unsafe {
952            ffi::g_file_delete_async(
953                self.as_ref().to_glib_none().0,
954                io_priority.into_glib(),
955                cancellable.map(|p| p.as_ref()).to_glib_none().0,
956                Some(callback),
957                Box_::into_raw(user_data) as *mut _,
958            );
959        }
960    }
961
962    fn delete_future(
963        &self,
964        io_priority: glib::Priority,
965    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
966        Box_::pin(crate::GioFuture::new(
967            self,
968            move |obj, cancellable, send| {
969                obj.delete_async(io_priority, Some(cancellable), move |res| {
970                    send.resolve(res);
971                });
972            },
973        ))
974    }
975
976    /// Duplicates a #GFile handle. This operation does not duplicate
977    /// the actual file or directory represented by the #GFile; see
978    /// g_file_copy() if attempting to copy a file.
979    ///
980    /// g_file_dup() is useful when a second handle is needed to the same underlying
981    /// file, for use in a separate thread (#GFile is not thread-safe). For use
982    /// within the same thread, use g_object_ref() to increment the existing object’s
983    /// reference count.
984    ///
985    /// This call does no blocking I/O.
986    ///
987    /// # Returns
988    ///
989    /// a new #GFile that is a duplicate
990    ///   of the given #GFile.
991    #[doc(alias = "g_file_dup")]
992    #[must_use]
993    fn dup(&self) -> File {
994        unsafe { from_glib_full(ffi::g_file_dup(self.as_ref().to_glib_none().0)) }
995    }
996
997    /// Starts an asynchronous eject on a mountable.
998    /// When this operation has completed, @callback will be called with
999    /// @user_user data, and the operation can be finalized with
1000    /// g_file_eject_mountable_with_operation_finish().
1001    ///
1002    /// If @cancellable is not [`None`], then the operation can be cancelled by
1003    /// triggering the cancellable object from another thread. If the operation
1004    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1005    /// ## `flags`
1006    /// flags affecting the operation
1007    /// ## `mount_operation`
1008    /// a #GMountOperation,
1009    ///   or [`None`] to avoid user interaction
1010    /// ## `cancellable`
1011    /// optional #GCancellable object,
1012    ///   [`None`] to ignore
1013    /// ## `callback`
1014    /// a #GAsyncReadyCallback
1015    ///   to call when the request is satisfied
1016    #[doc(alias = "g_file_eject_mountable_with_operation")]
1017    fn eject_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
1018        &self,
1019        flags: MountUnmountFlags,
1020        mount_operation: Option<&impl IsA<MountOperation>>,
1021        cancellable: Option<&impl IsA<Cancellable>>,
1022        callback: P,
1023    ) {
1024        let main_context = glib::MainContext::ref_thread_default();
1025        let is_main_context_owner = main_context.is_owner();
1026        let has_acquired_main_context = (!is_main_context_owner)
1027            .then(|| main_context.acquire().ok())
1028            .flatten();
1029        assert!(
1030            is_main_context_owner || has_acquired_main_context.is_some(),
1031            "Async operations only allowed if the thread is owning the MainContext"
1032        );
1033
1034        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1035            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1036        unsafe extern "C" fn eject_mountable_with_operation_trampoline<
1037            P: FnOnce(Result<(), glib::Error>) + 'static,
1038        >(
1039            _source_object: *mut glib::gobject_ffi::GObject,
1040            res: *mut crate::ffi::GAsyncResult,
1041            user_data: glib::ffi::gpointer,
1042        ) {
1043            unsafe {
1044                let mut error = std::ptr::null_mut();
1045                ffi::g_file_eject_mountable_with_operation_finish(
1046                    _source_object as *mut _,
1047                    res,
1048                    &mut error,
1049                );
1050                let result = if error.is_null() {
1051                    Ok(())
1052                } else {
1053                    Err(from_glib_full(error))
1054                };
1055                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1056                    Box_::from_raw(user_data as *mut _);
1057                let callback: P = callback.into_inner();
1058                callback(result);
1059            }
1060        }
1061        let callback = eject_mountable_with_operation_trampoline::<P>;
1062        unsafe {
1063            ffi::g_file_eject_mountable_with_operation(
1064                self.as_ref().to_glib_none().0,
1065                flags.into_glib(),
1066                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
1067                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1068                Some(callback),
1069                Box_::into_raw(user_data) as *mut _,
1070            );
1071        }
1072    }
1073
1074    fn eject_mountable_with_operation_future(
1075        &self,
1076        flags: MountUnmountFlags,
1077        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
1078    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1079        let mount_operation = mount_operation.map(ToOwned::to_owned);
1080        Box_::pin(crate::GioFuture::new(
1081            self,
1082            move |obj, cancellable, send| {
1083                obj.eject_mountable_with_operation(
1084                    flags,
1085                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
1086                    Some(cancellable),
1087                    move |res| {
1088                        send.resolve(res);
1089                    },
1090                );
1091            },
1092        ))
1093    }
1094
1095    /// Gets the requested information about the files in a directory.
1096    /// The result is a #GFileEnumerator object that will give out
1097    /// #GFileInfo objects for all the files in the directory.
1098    ///
1099    /// The @attributes value is a string that specifies the file
1100    /// attributes that should be gathered. It is not an error if
1101    /// it's not possible to read a particular requested attribute
1102    /// from a file - it just won't be set. @attributes should
1103    /// be a comma-separated list of attributes or attribute wildcards.
1104    /// The wildcard "*" means all attributes, and a wildcard like
1105    /// "standard::*" means all attributes in the standard namespace.
1106    /// An example attribute query be "standard::*,owner::user".
1107    /// The standard attributes are available as defines, like
1108    /// [`FILE_ATTRIBUTE_STANDARD_NAME`][crate::FILE_ATTRIBUTE_STANDARD_NAME]. [`FILE_ATTRIBUTE_STANDARD_NAME`][crate::FILE_ATTRIBUTE_STANDARD_NAME] should
1109    /// always be specified if you plan to call g_file_enumerator_get_child() or
1110    /// g_file_enumerator_iterate() on the returned enumerator.
1111    ///
1112    /// If @cancellable is not [`None`], then the operation can be cancelled
1113    /// by triggering the cancellable object from another thread. If the
1114    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
1115    /// returned.
1116    ///
1117    /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will
1118    /// be returned. If the file is not a directory, the [`IOErrorEnum::NotDirectory`][crate::IOErrorEnum::NotDirectory]
1119    /// error will be returned. Other errors are possible too.
1120    /// ## `attributes`
1121    /// an attribute query string
1122    /// ## `flags`
1123    /// a set of #GFileQueryInfoFlags
1124    /// ## `cancellable`
1125    /// optional #GCancellable object,
1126    ///   [`None`] to ignore
1127    ///
1128    /// # Returns
1129    ///
1130    /// A #GFileEnumerator if successful,
1131    ///   [`None`] on error. Free the returned object with g_object_unref().
1132    #[doc(alias = "g_file_enumerate_children")]
1133    fn enumerate_children(
1134        &self,
1135        attributes: &str,
1136        flags: FileQueryInfoFlags,
1137        cancellable: Option<&impl IsA<Cancellable>>,
1138    ) -> Result<FileEnumerator, glib::Error> {
1139        unsafe {
1140            let mut error = std::ptr::null_mut();
1141            let ret = ffi::g_file_enumerate_children(
1142                self.as_ref().to_glib_none().0,
1143                attributes.to_glib_none().0,
1144                flags.into_glib(),
1145                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1146                &mut error,
1147            );
1148            if error.is_null() {
1149                Ok(from_glib_full(ret))
1150            } else {
1151                Err(from_glib_full(error))
1152            }
1153        }
1154    }
1155
1156    #[doc(alias = "g_file_equal")]
1157    fn equal(&self, file2: &impl IsA<File>) -> bool {
1158        unsafe {
1159            from_glib(ffi::g_file_equal(
1160                self.as_ref().to_glib_none().0,
1161                file2.as_ref().to_glib_none().0,
1162            ))
1163        }
1164    }
1165
1166    /// Gets a #GMount for the #GFile.
1167    ///
1168    /// #GMount is returned only for user interesting locations, see
1169    /// #GVolumeMonitor. If the #GFileIface for @self does not have a #mount,
1170    /// @error will be set to [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] and [`None`] #will be returned.
1171    ///
1172    /// If @cancellable is not [`None`], then the operation can be cancelled by
1173    /// triggering the cancellable object from another thread. If the operation
1174    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1175    /// ## `cancellable`
1176    /// optional #GCancellable object,
1177    ///   [`None`] to ignore
1178    ///
1179    /// # Returns
1180    ///
1181    /// a #GMount where the @self is located
1182    ///   or [`None`] on error.
1183    ///   Free the returned object with g_object_unref().
1184    #[doc(alias = "g_file_find_enclosing_mount")]
1185    fn find_enclosing_mount(
1186        &self,
1187        cancellable: Option<&impl IsA<Cancellable>>,
1188    ) -> Result<Mount, glib::Error> {
1189        unsafe {
1190            let mut error = std::ptr::null_mut();
1191            let ret = ffi::g_file_find_enclosing_mount(
1192                self.as_ref().to_glib_none().0,
1193                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1194                &mut error,
1195            );
1196            if error.is_null() {
1197                Ok(from_glib_full(ret))
1198            } else {
1199                Err(from_glib_full(error))
1200            }
1201        }
1202    }
1203
1204    /// Gets the base name (the last component of the path) for a given #GFile.
1205    ///
1206    /// If called for the top level of a system (such as the filesystem root
1207    /// or a uri like sftp://host/) it will return a single directory separator
1208    /// (and on Windows, possibly a drive letter).
1209    ///
1210    /// The base name is a byte string (not UTF-8). It has no defined encoding
1211    /// or rules other than it may not contain zero bytes.  If you want to use
1212    /// filenames in a user interface you should use the display name that you
1213    /// can get by requesting the [`FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME`][crate::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME]
1214    /// attribute with g_file_query_info().
1215    ///
1216    /// This call does no blocking I/O.
1217    ///
1218    /// # Returns
1219    ///
1220    /// string containing the #GFile's
1221    ///   base name, or [`None`] if given #GFile is invalid. The returned string
1222    ///   should be freed with g_free() when no longer needed.
1223    #[doc(alias = "g_file_get_basename")]
1224    #[doc(alias = "get_basename")]
1225    fn basename(&self) -> Option<std::path::PathBuf> {
1226        unsafe { from_glib_full(ffi::g_file_get_basename(self.as_ref().to_glib_none().0)) }
1227    }
1228
1229    /// Gets a child of @self with basename equal to @name.
1230    ///
1231    /// Note that the file with that specific name might not exist, but
1232    /// you can still have a #GFile that points to it. You can use this
1233    /// for instance to create that file.
1234    ///
1235    /// This call does no blocking I/O.
1236    /// ## `name`
1237    /// string containing the child's basename
1238    ///
1239    /// # Returns
1240    ///
1241    /// a #GFile to a child specified by @name.
1242    ///   Free the returned object with g_object_unref().
1243    #[doc(alias = "g_file_get_child")]
1244    #[doc(alias = "get_child")]
1245    #[must_use]
1246    fn child(&self, name: impl AsRef<std::path::Path>) -> File {
1247        unsafe {
1248            from_glib_full(ffi::g_file_get_child(
1249                self.as_ref().to_glib_none().0,
1250                name.as_ref().to_glib_none().0,
1251            ))
1252        }
1253    }
1254
1255    /// Gets the child of @self for a given @display_name (i.e. a UTF-8
1256    /// version of the name). If this function fails, it returns [`None`]
1257    /// and @error will be set. This is very useful when constructing a
1258    /// #GFile for a new file and the user entered the filename in the
1259    /// user interface, for instance when you select a directory and
1260    /// type a filename in the file selector.
1261    ///
1262    /// This call does no blocking I/O.
1263    /// ## `display_name`
1264    /// string to a possible child
1265    ///
1266    /// # Returns
1267    ///
1268    /// a #GFile to the specified child, or
1269    ///   [`None`] if the display name couldn't be converted.
1270    ///   Free the returned object with g_object_unref().
1271    #[doc(alias = "g_file_get_child_for_display_name")]
1272    #[doc(alias = "get_child_for_display_name")]
1273    fn child_for_display_name(&self, display_name: &str) -> Result<File, glib::Error> {
1274        unsafe {
1275            let mut error = std::ptr::null_mut();
1276            let ret = ffi::g_file_get_child_for_display_name(
1277                self.as_ref().to_glib_none().0,
1278                display_name.to_glib_none().0,
1279                &mut error,
1280            );
1281            if error.is_null() {
1282                Ok(from_glib_full(ret))
1283            } else {
1284                Err(from_glib_full(error))
1285            }
1286        }
1287    }
1288
1289    /// Gets the parent directory for the @self.
1290    /// If the @self represents the root directory of the
1291    /// file system, then [`None`] will be returned.
1292    ///
1293    /// This call does no blocking I/O.
1294    ///
1295    /// # Returns
1296    ///
1297    /// a #GFile structure to the
1298    ///   parent of the given #GFile or [`None`] if there is no parent. Free
1299    ///   the returned object with g_object_unref().
1300    #[doc(alias = "g_file_get_parent")]
1301    #[doc(alias = "get_parent")]
1302    #[must_use]
1303    fn parent(&self) -> Option<File> {
1304        unsafe { from_glib_full(ffi::g_file_get_parent(self.as_ref().to_glib_none().0)) }
1305    }
1306
1307    /// Gets the parse name of the @self.
1308    /// A parse name is a UTF-8 string that describes the
1309    /// file such that one can get the #GFile back using
1310    /// g_file_parse_name().
1311    ///
1312    /// This is generally used to show the #GFile as a nice
1313    /// full-pathname kind of string in a user interface,
1314    /// like in a location entry.
1315    ///
1316    /// For local files with names that can safely be converted
1317    /// to UTF-8 the pathname is used, otherwise the IRI is used
1318    /// (a form of URI that allows UTF-8 characters unescaped).
1319    ///
1320    /// This call does no blocking I/O.
1321    ///
1322    /// # Returns
1323    ///
1324    /// a string containing the #GFile's parse name.
1325    ///   The returned string should be freed with g_free()
1326    ///   when no longer needed.
1327    #[doc(alias = "g_file_get_parse_name")]
1328    #[doc(alias = "get_parse_name")]
1329    fn parse_name(&self) -> glib::GString {
1330        unsafe { from_glib_full(ffi::g_file_get_parse_name(self.as_ref().to_glib_none().0)) }
1331    }
1332
1333    /// Gets the local pathname for #GFile, if one exists. If non-[`None`], this is
1334    /// guaranteed to be an absolute, canonical path. It might contain symlinks.
1335    ///
1336    /// This call does no blocking I/O.
1337    ///
1338    /// # Returns
1339    ///
1340    /// string containing the #GFile's path,
1341    ///   or [`None`] if no such path exists. The returned string should be freed
1342    ///   with g_free() when no longer needed.
1343    #[doc(alias = "g_file_get_path")]
1344    #[doc(alias = "get_path")]
1345    fn path(&self) -> Option<std::path::PathBuf> {
1346        unsafe { from_glib_full(ffi::g_file_get_path(self.as_ref().to_glib_none().0)) }
1347    }
1348
1349    /// Gets the path for @descendant relative to @self.
1350    ///
1351    /// This call does no blocking I/O.
1352    /// ## `descendant`
1353    /// input #GFile
1354    ///
1355    /// # Returns
1356    ///
1357    /// string with the relative path from
1358    ///   @descendant to @self, or [`None`] if @descendant doesn't have @self as
1359    ///   prefix. The returned string should be freed with g_free() when
1360    ///   no longer needed.
1361    #[doc(alias = "g_file_get_relative_path")]
1362    #[doc(alias = "get_relative_path")]
1363    fn relative_path(&self, descendant: &impl IsA<File>) -> Option<std::path::PathBuf> {
1364        unsafe {
1365            from_glib_full(ffi::g_file_get_relative_path(
1366                self.as_ref().to_glib_none().0,
1367                descendant.as_ref().to_glib_none().0,
1368            ))
1369        }
1370    }
1371
1372    /// Gets the URI for the @self.
1373    ///
1374    /// This call does no blocking I/O.
1375    ///
1376    /// # Returns
1377    ///
1378    /// a string containing the #GFile's URI. If the #GFile was constructed
1379    ///   with an invalid URI, an invalid URI is returned.
1380    ///   The returned string should be freed with g_free()
1381    ///   when no longer needed.
1382    #[doc(alias = "g_file_get_uri")]
1383    #[doc(alias = "get_uri")]
1384    fn uri(&self) -> glib::GString {
1385        unsafe { from_glib_full(ffi::g_file_get_uri(self.as_ref().to_glib_none().0)) }
1386    }
1387
1388    /// Gets the URI scheme for a #GFile.
1389    /// RFC 3986 decodes the scheme as:
1390    ///
1391    /// ```text
1392    /// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
1393    /// ```
1394    /// Common schemes include "file", "http", "ftp", etc.
1395    ///
1396    /// The scheme can be different from the one used to construct the #GFile,
1397    /// in that it might be replaced with one that is logically equivalent to the #GFile.
1398    ///
1399    /// This call does no blocking I/O.
1400    ///
1401    /// # Returns
1402    ///
1403    /// a string containing the URI scheme for the given
1404    ///   #GFile or [`None`] if the #GFile was constructed with an invalid URI. The
1405    ///   returned string should be freed with g_free() when no longer needed.
1406    #[doc(alias = "g_file_get_uri_scheme")]
1407    #[doc(alias = "get_uri_scheme")]
1408    fn uri_scheme(&self) -> Option<glib::GString> {
1409        unsafe { from_glib_full(ffi::g_file_get_uri_scheme(self.as_ref().to_glib_none().0)) }
1410    }
1411
1412    /// Checks if @self has a parent, and optionally, if it is @parent.
1413    ///
1414    /// If @parent is [`None`] then this function returns [`true`] if @self has any
1415    /// parent at all.  If @parent is non-[`None`] then [`true`] is only returned
1416    /// if @self is an immediate child of @parent.
1417    /// ## `parent`
1418    /// the parent to check for, or [`None`]
1419    ///
1420    /// # Returns
1421    ///
1422    /// [`true`] if @self is an immediate child of @parent (or any parent in
1423    ///   the case that @parent is [`None`]).
1424    #[doc(alias = "g_file_has_parent")]
1425    fn has_parent(&self, parent: Option<&impl IsA<File>>) -> bool {
1426        unsafe {
1427            from_glib(ffi::g_file_has_parent(
1428                self.as_ref().to_glib_none().0,
1429                parent.map(|p| p.as_ref()).to_glib_none().0,
1430            ))
1431        }
1432    }
1433
1434    /// Checks whether @self has the prefix specified by @prefix.
1435    ///
1436    /// In other words, if the names of initial elements of @self's
1437    /// pathname match @prefix. Only full pathname elements are matched,
1438    /// so a path like /foo is not considered a prefix of /foobar, only
1439    /// of /foo/bar.
1440    ///
1441    /// A #GFile is not a prefix of itself. If you want to check for
1442    /// equality, use g_file_equal().
1443    ///
1444    /// This call does no I/O, as it works purely on names. As such it can
1445    /// sometimes return [`false`] even if @self is inside a @prefix (from a
1446    /// filesystem point of view), because the prefix of @self is an alias
1447    /// of @prefix.
1448    /// ## `prefix`
1449    /// input #GFile
1450    ///
1451    /// # Returns
1452    ///
1453    /// [`true`] if the @self's parent, grandparent, etc is @prefix,
1454    ///   [`false`] otherwise.
1455    #[doc(alias = "g_file_has_prefix")]
1456    fn has_prefix(&self, prefix: &impl IsA<File>) -> bool {
1457        unsafe {
1458            from_glib(ffi::g_file_has_prefix(
1459                self.as_ref().to_glib_none().0,
1460                prefix.as_ref().to_glib_none().0,
1461            ))
1462        }
1463    }
1464
1465    /// Checks to see if a #GFile has a given URI scheme.
1466    ///
1467    /// This call does no blocking I/O.
1468    /// ## `uri_scheme`
1469    /// a string containing a URI scheme
1470    ///
1471    /// # Returns
1472    ///
1473    /// [`true`] if #GFile's backend supports the
1474    ///   given URI scheme, [`false`] if URI scheme is [`None`],
1475    ///   not supported, or #GFile is invalid.
1476    #[doc(alias = "g_file_has_uri_scheme")]
1477    fn has_uri_scheme(&self, uri_scheme: &str) -> bool {
1478        unsafe {
1479            from_glib(ffi::g_file_has_uri_scheme(
1480                self.as_ref().to_glib_none().0,
1481                uri_scheme.to_glib_none().0,
1482            ))
1483        }
1484    }
1485
1486    /// Checks to see if a file is native to the platform.
1487    ///
1488    /// A native file is one expressed in the platform-native filename format,
1489    /// e.g. "C:\Windows" or "/usr/bin/". This does not mean the file is local,
1490    /// as it might be on a locally mounted remote filesystem.
1491    ///
1492    /// On some systems non-native files may be available using the native
1493    /// filesystem via a userspace filesystem (FUSE), in these cases this call
1494    /// will return [`false`], but g_file_get_path() will still return a native path.
1495    ///
1496    /// This call does no blocking I/O.
1497    ///
1498    /// # Returns
1499    ///
1500    /// [`true`] if @self is native
1501    #[doc(alias = "g_file_is_native")]
1502    fn is_native(&self) -> bool {
1503        unsafe { from_glib(ffi::g_file_is_native(self.as_ref().to_glib_none().0)) }
1504    }
1505
1506    /// Loads the contents of @self and returns it as #GBytes.
1507    ///
1508    /// If @self is a resource:// based URI, the resulting bytes will reference the
1509    /// embedded resource instead of a copy. Otherwise, this is equivalent to calling
1510    /// g_file_load_contents() and g_bytes_new_take().
1511    ///
1512    /// For resources, @etag_out will be set to [`None`].
1513    ///
1514    /// The data contained in the resulting #GBytes is always zero-terminated, but
1515    /// this is not included in the #GBytes length. The resulting #GBytes should be
1516    /// freed with g_bytes_unref() when no longer in use.
1517    /// ## `cancellable`
1518    /// a #GCancellable or [`None`]
1519    ///
1520    /// # Returns
1521    ///
1522    /// a #GBytes or [`None`] and @error is set
1523    ///
1524    /// ## `etag_out`
1525    /// a location to place the current
1526    ///   entity tag for the file, or [`None`] if the entity tag is not needed
1527    #[doc(alias = "g_file_load_bytes")]
1528    fn load_bytes(
1529        &self,
1530        cancellable: Option<&impl IsA<Cancellable>>,
1531    ) -> Result<(glib::Bytes, Option<glib::GString>), glib::Error> {
1532        unsafe {
1533            let mut etag_out = std::ptr::null_mut();
1534            let mut error = std::ptr::null_mut();
1535            let ret = ffi::g_file_load_bytes(
1536                self.as_ref().to_glib_none().0,
1537                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1538                &mut etag_out,
1539                &mut error,
1540            );
1541            if error.is_null() {
1542                Ok((from_glib_full(ret), from_glib_full(etag_out)))
1543            } else {
1544                Err(from_glib_full(error))
1545            }
1546        }
1547    }
1548
1549    /// Asynchronously loads the contents of @self as #GBytes.
1550    ///
1551    /// If @self is a resource:// based URI, the resulting bytes will reference the
1552    /// embedded resource instead of a copy. Otherwise, this is equivalent to calling
1553    /// g_file_load_contents_async() and g_bytes_new_take().
1554    ///
1555    /// @callback should call g_file_load_bytes_finish() to get the result of this
1556    /// asynchronous operation.
1557    ///
1558    /// See g_file_load_bytes() for more information.
1559    /// ## `cancellable`
1560    /// a #GCancellable or [`None`]
1561    /// ## `callback`
1562    /// a #GAsyncReadyCallback
1563    ///   to call when the request is satisfied
1564    #[doc(alias = "g_file_load_bytes_async")]
1565    fn load_bytes_async<
1566        P: FnOnce(Result<(glib::Bytes, Option<glib::GString>), glib::Error>) + 'static,
1567    >(
1568        &self,
1569        cancellable: Option<&impl IsA<Cancellable>>,
1570        callback: P,
1571    ) {
1572        let main_context = glib::MainContext::ref_thread_default();
1573        let is_main_context_owner = main_context.is_owner();
1574        let has_acquired_main_context = (!is_main_context_owner)
1575            .then(|| main_context.acquire().ok())
1576            .flatten();
1577        assert!(
1578            is_main_context_owner || has_acquired_main_context.is_some(),
1579            "Async operations only allowed if the thread is owning the MainContext"
1580        );
1581
1582        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1583            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1584        unsafe extern "C" fn load_bytes_async_trampoline<
1585            P: FnOnce(Result<(glib::Bytes, Option<glib::GString>), glib::Error>) + 'static,
1586        >(
1587            _source_object: *mut glib::gobject_ffi::GObject,
1588            res: *mut crate::ffi::GAsyncResult,
1589            user_data: glib::ffi::gpointer,
1590        ) {
1591            unsafe {
1592                let mut error = std::ptr::null_mut();
1593                let mut etag_out = std::ptr::null_mut();
1594                let ret = ffi::g_file_load_bytes_finish(
1595                    _source_object as *mut _,
1596                    res,
1597                    &mut etag_out,
1598                    &mut error,
1599                );
1600                let result = if error.is_null() {
1601                    Ok((from_glib_full(ret), from_glib_full(etag_out)))
1602                } else {
1603                    Err(from_glib_full(error))
1604                };
1605                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1606                    Box_::from_raw(user_data as *mut _);
1607                let callback: P = callback.into_inner();
1608                callback(result);
1609            }
1610        }
1611        let callback = load_bytes_async_trampoline::<P>;
1612        unsafe {
1613            ffi::g_file_load_bytes_async(
1614                self.as_ref().to_glib_none().0,
1615                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1616                Some(callback),
1617                Box_::into_raw(user_data) as *mut _,
1618            );
1619        }
1620    }
1621
1622    fn load_bytes_future(
1623        &self,
1624    ) -> Pin<
1625        Box_<
1626            dyn std::future::Future<
1627                    Output = Result<(glib::Bytes, Option<glib::GString>), glib::Error>,
1628                > + 'static,
1629        >,
1630    > {
1631        Box_::pin(crate::GioFuture::new(
1632            self,
1633            move |obj, cancellable, send| {
1634                obj.load_bytes_async(Some(cancellable), move |res| {
1635                    send.resolve(res);
1636                });
1637            },
1638        ))
1639    }
1640
1641    /// Creates a directory.
1642    ///
1643    /// Note that this will only create a child directory
1644    /// of the immediate parent directory of the path or URI given by the #GFile.
1645    /// To recursively create directories, see g_file_make_directory_with_parents().
1646    ///
1647    /// This function will fail if the parent directory does not exist, setting
1648    /// @error to [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound]. If the file system doesn't support
1649    /// creating directories, this function will fail, setting @error to
1650    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported]. If the directory already exists,
1651    /// [error@Gio.IOErrorEnum.EXISTS] will be returned.
1652    ///
1653    /// For a local #GFile the newly created directory will have the default
1654    /// (current) ownership and permissions of the current process.
1655    ///
1656    /// If @cancellable is not [`None`], then the operation can be cancelled by
1657    /// triggering the cancellable object from another thread. If the operation
1658    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1659    /// ## `cancellable`
1660    /// optional #GCancellable object,
1661    ///   [`None`] to ignore
1662    ///
1663    /// # Returns
1664    ///
1665    /// [`true`] on successful creation, [`false`] otherwise.
1666    #[doc(alias = "g_file_make_directory")]
1667    fn make_directory(
1668        &self,
1669        cancellable: Option<&impl IsA<Cancellable>>,
1670    ) -> Result<(), glib::Error> {
1671        unsafe {
1672            let mut error = std::ptr::null_mut();
1673            let is_ok = ffi::g_file_make_directory(
1674                self.as_ref().to_glib_none().0,
1675                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1676                &mut error,
1677            );
1678            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1679            if error.is_null() {
1680                Ok(())
1681            } else {
1682                Err(from_glib_full(error))
1683            }
1684        }
1685    }
1686
1687    /// Asynchronously creates a directory.
1688    /// ## `io_priority`
1689    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
1690    /// ## `cancellable`
1691    /// optional #GCancellable object,
1692    ///   [`None`] to ignore
1693    /// ## `callback`
1694    /// a #GAsyncReadyCallback to call
1695    ///   when the request is satisfied
1696    #[doc(alias = "g_file_make_directory_async")]
1697    fn make_directory_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
1698        &self,
1699        io_priority: glib::Priority,
1700        cancellable: Option<&impl IsA<Cancellable>>,
1701        callback: P,
1702    ) {
1703        let main_context = glib::MainContext::ref_thread_default();
1704        let is_main_context_owner = main_context.is_owner();
1705        let has_acquired_main_context = (!is_main_context_owner)
1706            .then(|| main_context.acquire().ok())
1707            .flatten();
1708        assert!(
1709            is_main_context_owner || has_acquired_main_context.is_some(),
1710            "Async operations only allowed if the thread is owning the MainContext"
1711        );
1712
1713        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1714            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1715        unsafe extern "C" fn make_directory_async_trampoline<
1716            P: FnOnce(Result<(), glib::Error>) + 'static,
1717        >(
1718            _source_object: *mut glib::gobject_ffi::GObject,
1719            res: *mut crate::ffi::GAsyncResult,
1720            user_data: glib::ffi::gpointer,
1721        ) {
1722            unsafe {
1723                let mut error = std::ptr::null_mut();
1724                ffi::g_file_make_directory_finish(_source_object as *mut _, res, &mut error);
1725                let result = if error.is_null() {
1726                    Ok(())
1727                } else {
1728                    Err(from_glib_full(error))
1729                };
1730                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1731                    Box_::from_raw(user_data as *mut _);
1732                let callback: P = callback.into_inner();
1733                callback(result);
1734            }
1735        }
1736        let callback = make_directory_async_trampoline::<P>;
1737        unsafe {
1738            ffi::g_file_make_directory_async(
1739                self.as_ref().to_glib_none().0,
1740                io_priority.into_glib(),
1741                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1742                Some(callback),
1743                Box_::into_raw(user_data) as *mut _,
1744            );
1745        }
1746    }
1747
1748    fn make_directory_future(
1749        &self,
1750        io_priority: glib::Priority,
1751    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1752        Box_::pin(crate::GioFuture::new(
1753            self,
1754            move |obj, cancellable, send| {
1755                obj.make_directory_async(io_priority, Some(cancellable), move |res| {
1756                    send.resolve(res);
1757                });
1758            },
1759        ))
1760    }
1761
1762    /// Creates a directory and any parent directories that may not
1763    /// exist similar to 'mkdir -p'. If the file system does not support
1764    /// creating directories, this function will fail, setting @error to
1765    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported]. If the directory itself already exists,
1766    /// this function will fail setting @error to [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists], unlike
1767    /// the similar g_mkdir_with_parents().
1768    ///
1769    /// For a local #GFile the newly created directories will have the default
1770    /// (current) ownership and permissions of the current process.
1771    ///
1772    /// If @cancellable is not [`None`], then the operation can be cancelled by
1773    /// triggering the cancellable object from another thread. If the operation
1774    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1775    /// ## `cancellable`
1776    /// optional #GCancellable object,
1777    ///   [`None`] to ignore
1778    ///
1779    /// # Returns
1780    ///
1781    /// [`true`] if all directories have been successfully created, [`false`]
1782    /// otherwise.
1783    #[doc(alias = "g_file_make_directory_with_parents")]
1784    fn make_directory_with_parents(
1785        &self,
1786        cancellable: Option<&impl IsA<Cancellable>>,
1787    ) -> Result<(), glib::Error> {
1788        unsafe {
1789            let mut error = std::ptr::null_mut();
1790            let is_ok = ffi::g_file_make_directory_with_parents(
1791                self.as_ref().to_glib_none().0,
1792                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1793                &mut error,
1794            );
1795            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1796            if error.is_null() {
1797                Ok(())
1798            } else {
1799                Err(from_glib_full(error))
1800            }
1801        }
1802    }
1803
1804    /// Creates a symbolic link named @self which contains the string
1805    /// @symlink_value.
1806    ///
1807    /// If @cancellable is not [`None`], then the operation can be cancelled by
1808    /// triggering the cancellable object from another thread. If the operation
1809    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1810    /// ## `symlink_value`
1811    /// a string with the path for the target
1812    ///   of the new symlink
1813    /// ## `cancellable`
1814    /// optional #GCancellable object,
1815    ///   [`None`] to ignore
1816    ///
1817    /// # Returns
1818    ///
1819    /// [`true`] on the creation of a new symlink, [`false`] otherwise.
1820    #[doc(alias = "g_file_make_symbolic_link")]
1821    fn make_symbolic_link(
1822        &self,
1823        symlink_value: impl AsRef<std::path::Path>,
1824        cancellable: Option<&impl IsA<Cancellable>>,
1825    ) -> Result<(), glib::Error> {
1826        unsafe {
1827            let mut error = std::ptr::null_mut();
1828            let is_ok = ffi::g_file_make_symbolic_link(
1829                self.as_ref().to_glib_none().0,
1830                symlink_value.as_ref().to_glib_none().0,
1831                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1832                &mut error,
1833            );
1834            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1835            if error.is_null() {
1836                Ok(())
1837            } else {
1838                Err(from_glib_full(error))
1839            }
1840        }
1841    }
1842
1843    /// Recursively measures the disk usage of @self.
1844    ///
1845    /// This is essentially an analog of the 'du' command, but it also
1846    /// reports the number of directories and non-directory files encountered
1847    /// (including things like symbolic links).
1848    ///
1849    /// By default, errors are only reported against the toplevel file
1850    /// itself.  Errors found while recursing are silently ignored, unless
1851    /// [`FileMeasureFlags::REPORT_ANY_ERROR`][crate::FileMeasureFlags::REPORT_ANY_ERROR] is given in @flags.
1852    ///
1853    /// The returned size, @disk_usage, is in bytes and should be formatted
1854    /// with g_format_size() in order to get something reasonable for showing
1855    /// in a user interface.
1856    ///
1857    /// @progress_callback and @progress_data can be given to request
1858    /// periodic progress updates while scanning.  See the documentation for
1859    /// #GFileMeasureProgressCallback for information about when and how the
1860    /// callback will be invoked.
1861    /// ## `flags`
1862    /// #GFileMeasureFlags
1863    /// ## `cancellable`
1864    /// optional #GCancellable
1865    /// ## `progress_callback`
1866    /// a #GFileMeasureProgressCallback
1867    /// ## `progress_data`
1868    /// user_data for @progress_callback
1869    ///
1870    /// # Returns
1871    ///
1872    /// [`true`] if successful, with the out parameters set.
1873    ///   [`false`] otherwise, with @error set.
1874    ///
1875    /// ## `disk_usage`
1876    /// the number of bytes of disk space used
1877    ///
1878    /// ## `num_dirs`
1879    /// the number of directories encountered
1880    ///
1881    /// ## `num_files`
1882    /// the number of non-directories encountered
1883    #[doc(alias = "g_file_measure_disk_usage")]
1884    fn measure_disk_usage(
1885        &self,
1886        flags: FileMeasureFlags,
1887        cancellable: Option<&impl IsA<Cancellable>>,
1888        progress_callback: Option<&mut dyn FnMut(bool, u64, u64, u64)>,
1889    ) -> Result<(u64, u64, u64), glib::Error> {
1890        let mut progress_callback_data: Option<&mut dyn FnMut(bool, u64, u64, u64)> =
1891            progress_callback;
1892        unsafe extern "C" fn progress_callback_func(
1893            reporting: glib::ffi::gboolean,
1894            current_size: u64,
1895            num_dirs: u64,
1896            num_files: u64,
1897            data: glib::ffi::gpointer,
1898        ) {
1899            unsafe {
1900                let reporting = from_glib(reporting);
1901                let callback = data as *mut Option<&mut dyn FnMut(bool, u64, u64, u64)>;
1902                if let Some(ref mut callback) = *callback {
1903                    callback(reporting, current_size, num_dirs, num_files)
1904                } else {
1905                    panic!("cannot get closure...")
1906                }
1907            }
1908        }
1909        let progress_callback = if progress_callback_data.is_some() {
1910            Some(progress_callback_func as _)
1911        } else {
1912            None
1913        };
1914        let super_callback0: &mut Option<&mut dyn FnMut(bool, u64, u64, u64)> =
1915            &mut progress_callback_data;
1916        unsafe {
1917            let mut disk_usage = std::mem::MaybeUninit::uninit();
1918            let mut num_dirs = std::mem::MaybeUninit::uninit();
1919            let mut num_files = std::mem::MaybeUninit::uninit();
1920            let mut error = std::ptr::null_mut();
1921            let is_ok = ffi::g_file_measure_disk_usage(
1922                self.as_ref().to_glib_none().0,
1923                flags.into_glib(),
1924                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1925                progress_callback,
1926                super_callback0 as *mut _ as *mut _,
1927                disk_usage.as_mut_ptr(),
1928                num_dirs.as_mut_ptr(),
1929                num_files.as_mut_ptr(),
1930                &mut error,
1931            );
1932            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1933            if error.is_null() {
1934                Ok((
1935                    disk_usage.assume_init(),
1936                    num_dirs.assume_init(),
1937                    num_files.assume_init(),
1938                ))
1939            } else {
1940                Err(from_glib_full(error))
1941            }
1942        }
1943    }
1944
1945    /// Obtains a file or directory monitor for the given file,
1946    /// depending on the type of the file.
1947    ///
1948    /// If @cancellable is not [`None`], then the operation can be cancelled by
1949    /// triggering the cancellable object from another thread. If the operation
1950    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1951    /// ## `flags`
1952    /// a set of #GFileMonitorFlags
1953    /// ## `cancellable`
1954    /// optional #GCancellable object,
1955    ///   [`None`] to ignore
1956    ///
1957    /// # Returns
1958    ///
1959    /// a #GFileMonitor for the given @self,
1960    ///   or [`None`] on error.
1961    ///   Free the returned object with g_object_unref().
1962    #[doc(alias = "g_file_monitor")]
1963    fn monitor(
1964        &self,
1965        flags: FileMonitorFlags,
1966        cancellable: Option<&impl IsA<Cancellable>>,
1967    ) -> Result<FileMonitor, glib::Error> {
1968        unsafe {
1969            let mut error = std::ptr::null_mut();
1970            let ret = ffi::g_file_monitor(
1971                self.as_ref().to_glib_none().0,
1972                flags.into_glib(),
1973                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1974                &mut error,
1975            );
1976            if error.is_null() {
1977                Ok(from_glib_full(ret))
1978            } else {
1979                Err(from_glib_full(error))
1980            }
1981        }
1982    }
1983
1984    /// Obtains a directory monitor for the given file.
1985    /// This may fail if directory monitoring is not supported.
1986    ///
1987    /// If @cancellable is not [`None`], then the operation can be cancelled by
1988    /// triggering the cancellable object from another thread. If the operation
1989    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1990    ///
1991    /// It does not make sense for @flags to contain
1992    /// [`FileMonitorFlags::WATCH_HARD_LINKS`][crate::FileMonitorFlags::WATCH_HARD_LINKS], since hard links can not be made to
1993    /// directories.  It is not possible to monitor all the files in a
1994    /// directory for changes made via hard links; if you want to do this then
1995    /// you must register individual watches with g_file_monitor().
1996    /// ## `flags`
1997    /// a set of #GFileMonitorFlags
1998    /// ## `cancellable`
1999    /// optional #GCancellable object,
2000    ///   [`None`] to ignore
2001    ///
2002    /// # Returns
2003    ///
2004    /// a #GFileMonitor for the given @self,
2005    ///   or [`None`] on error. Free the returned object with g_object_unref().
2006    #[doc(alias = "g_file_monitor_directory")]
2007    fn monitor_directory(
2008        &self,
2009        flags: FileMonitorFlags,
2010        cancellable: Option<&impl IsA<Cancellable>>,
2011    ) -> Result<FileMonitor, glib::Error> {
2012        unsafe {
2013            let mut error = std::ptr::null_mut();
2014            let ret = ffi::g_file_monitor_directory(
2015                self.as_ref().to_glib_none().0,
2016                flags.into_glib(),
2017                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2018                &mut error,
2019            );
2020            if error.is_null() {
2021                Ok(from_glib_full(ret))
2022            } else {
2023                Err(from_glib_full(error))
2024            }
2025        }
2026    }
2027
2028    /// Obtains a file monitor for the given file. If no file notification
2029    /// mechanism exists, then regular polling of the file is used.
2030    ///
2031    /// If @cancellable is not [`None`], then the operation can be cancelled by
2032    /// triggering the cancellable object from another thread. If the operation
2033    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2034    ///
2035    /// If @flags contains [`FileMonitorFlags::WATCH_HARD_LINKS`][crate::FileMonitorFlags::WATCH_HARD_LINKS] then the monitor
2036    /// will also attempt to report changes made to the file via another
2037    /// filename (ie, a hard link). Without this flag, you can only rely on
2038    /// changes made through the filename contained in @self to be
2039    /// reported. Using this flag may result in an increase in resource
2040    /// usage, and may not have any effect depending on the #GFileMonitor
2041    /// backend and/or filesystem type.
2042    /// ## `flags`
2043    /// a set of #GFileMonitorFlags
2044    /// ## `cancellable`
2045    /// optional #GCancellable object,
2046    ///   [`None`] to ignore
2047    ///
2048    /// # Returns
2049    ///
2050    /// a #GFileMonitor for the given @self,
2051    ///   or [`None`] on error.
2052    ///   Free the returned object with g_object_unref().
2053    #[doc(alias = "g_file_monitor_file")]
2054    fn monitor_file(
2055        &self,
2056        flags: FileMonitorFlags,
2057        cancellable: Option<&impl IsA<Cancellable>>,
2058    ) -> Result<FileMonitor, glib::Error> {
2059        unsafe {
2060            let mut error = std::ptr::null_mut();
2061            let ret = ffi::g_file_monitor_file(
2062                self.as_ref().to_glib_none().0,
2063                flags.into_glib(),
2064                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2065                &mut error,
2066            );
2067            if error.is_null() {
2068                Ok(from_glib_full(ret))
2069            } else {
2070                Err(from_glib_full(error))
2071            }
2072        }
2073    }
2074
2075    /// Starts a @mount_operation, mounting the volume that contains
2076    /// the file @self.
2077    ///
2078    /// When this operation has completed, @callback will be called with
2079    /// @user_user data, and the operation can be finalized with
2080    /// g_file_mount_enclosing_volume_finish().
2081    ///
2082    /// If @cancellable is not [`None`], then the operation can be cancelled by
2083    /// triggering the cancellable object from another thread. If the operation
2084    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2085    /// ## `flags`
2086    /// flags affecting the operation
2087    /// ## `mount_operation`
2088    /// a #GMountOperation
2089    ///   or [`None`] to avoid user interaction
2090    /// ## `cancellable`
2091    /// optional #GCancellable object,
2092    ///   [`None`] to ignore
2093    /// ## `callback`
2094    /// a #GAsyncReadyCallback to call
2095    ///   when the request is satisfied, or [`None`]
2096    #[doc(alias = "g_file_mount_enclosing_volume")]
2097    fn mount_enclosing_volume<P: FnOnce(Result<(), glib::Error>) + 'static>(
2098        &self,
2099        flags: MountMountFlags,
2100        mount_operation: Option<&impl IsA<MountOperation>>,
2101        cancellable: Option<&impl IsA<Cancellable>>,
2102        callback: P,
2103    ) {
2104        let main_context = glib::MainContext::ref_thread_default();
2105        let is_main_context_owner = main_context.is_owner();
2106        let has_acquired_main_context = (!is_main_context_owner)
2107            .then(|| main_context.acquire().ok())
2108            .flatten();
2109        assert!(
2110            is_main_context_owner || has_acquired_main_context.is_some(),
2111            "Async operations only allowed if the thread is owning the MainContext"
2112        );
2113
2114        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2115            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2116        unsafe extern "C" fn mount_enclosing_volume_trampoline<
2117            P: FnOnce(Result<(), glib::Error>) + 'static,
2118        >(
2119            _source_object: *mut glib::gobject_ffi::GObject,
2120            res: *mut crate::ffi::GAsyncResult,
2121            user_data: glib::ffi::gpointer,
2122        ) {
2123            unsafe {
2124                let mut error = std::ptr::null_mut();
2125                ffi::g_file_mount_enclosing_volume_finish(
2126                    _source_object as *mut _,
2127                    res,
2128                    &mut error,
2129                );
2130                let result = if error.is_null() {
2131                    Ok(())
2132                } else {
2133                    Err(from_glib_full(error))
2134                };
2135                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2136                    Box_::from_raw(user_data as *mut _);
2137                let callback: P = callback.into_inner();
2138                callback(result);
2139            }
2140        }
2141        let callback = mount_enclosing_volume_trampoline::<P>;
2142        unsafe {
2143            ffi::g_file_mount_enclosing_volume(
2144                self.as_ref().to_glib_none().0,
2145                flags.into_glib(),
2146                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
2147                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2148                Some(callback),
2149                Box_::into_raw(user_data) as *mut _,
2150            );
2151        }
2152    }
2153
2154    fn mount_enclosing_volume_future(
2155        &self,
2156        flags: MountMountFlags,
2157        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
2158    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
2159        let mount_operation = mount_operation.map(ToOwned::to_owned);
2160        Box_::pin(crate::GioFuture::new(
2161            self,
2162            move |obj, cancellable, send| {
2163                obj.mount_enclosing_volume(
2164                    flags,
2165                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
2166                    Some(cancellable),
2167                    move |res| {
2168                        send.resolve(res);
2169                    },
2170                );
2171            },
2172        ))
2173    }
2174
2175    /// Mounts a file of type G_FILE_TYPE_MOUNTABLE.
2176    /// Using @mount_operation, you can request callbacks when, for instance,
2177    /// passwords are needed during authentication.
2178    ///
2179    /// If @cancellable is not [`None`], then the operation can be cancelled by
2180    /// triggering the cancellable object from another thread. If the operation
2181    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2182    ///
2183    /// When the operation is finished, @callback will be called.
2184    /// You can then call g_file_mount_mountable_finish() to get
2185    /// the result of the operation.
2186    /// ## `flags`
2187    /// flags affecting the operation
2188    /// ## `mount_operation`
2189    /// a #GMountOperation,
2190    ///   or [`None`] to avoid user interaction
2191    /// ## `cancellable`
2192    /// optional #GCancellable object,
2193    ///   [`None`] to ignore
2194    /// ## `callback`
2195    /// a #GAsyncReadyCallback
2196    ///   to call when the request is satisfied
2197    #[doc(alias = "g_file_mount_mountable")]
2198    fn mount_mountable<P: FnOnce(Result<File, glib::Error>) + 'static>(
2199        &self,
2200        flags: MountMountFlags,
2201        mount_operation: Option<&impl IsA<MountOperation>>,
2202        cancellable: Option<&impl IsA<Cancellable>>,
2203        callback: P,
2204    ) {
2205        let main_context = glib::MainContext::ref_thread_default();
2206        let is_main_context_owner = main_context.is_owner();
2207        let has_acquired_main_context = (!is_main_context_owner)
2208            .then(|| main_context.acquire().ok())
2209            .flatten();
2210        assert!(
2211            is_main_context_owner || has_acquired_main_context.is_some(),
2212            "Async operations only allowed if the thread is owning the MainContext"
2213        );
2214
2215        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2216            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2217        unsafe extern "C" fn mount_mountable_trampoline<
2218            P: FnOnce(Result<File, glib::Error>) + 'static,
2219        >(
2220            _source_object: *mut glib::gobject_ffi::GObject,
2221            res: *mut crate::ffi::GAsyncResult,
2222            user_data: glib::ffi::gpointer,
2223        ) {
2224            unsafe {
2225                let mut error = std::ptr::null_mut();
2226                let ret =
2227                    ffi::g_file_mount_mountable_finish(_source_object as *mut _, res, &mut error);
2228                let result = if error.is_null() {
2229                    Ok(from_glib_full(ret))
2230                } else {
2231                    Err(from_glib_full(error))
2232                };
2233                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2234                    Box_::from_raw(user_data as *mut _);
2235                let callback: P = callback.into_inner();
2236                callback(result);
2237            }
2238        }
2239        let callback = mount_mountable_trampoline::<P>;
2240        unsafe {
2241            ffi::g_file_mount_mountable(
2242                self.as_ref().to_glib_none().0,
2243                flags.into_glib(),
2244                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
2245                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2246                Some(callback),
2247                Box_::into_raw(user_data) as *mut _,
2248            );
2249        }
2250    }
2251
2252    fn mount_mountable_future(
2253        &self,
2254        flags: MountMountFlags,
2255        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
2256    ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
2257        let mount_operation = mount_operation.map(ToOwned::to_owned);
2258        Box_::pin(crate::GioFuture::new(
2259            self,
2260            move |obj, cancellable, send| {
2261                obj.mount_mountable(
2262                    flags,
2263                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
2264                    Some(cancellable),
2265                    move |res| {
2266                        send.resolve(res);
2267                    },
2268                );
2269            },
2270        ))
2271    }
2272
2273    /// Tries to move the file or directory @self to the location specified
2274    /// by @destination. If native move operations are supported then this is
2275    /// used, otherwise a copy + delete fallback is used. The native
2276    /// implementation may support moving directories (for instance on moves
2277    /// inside the same filesystem), but the fallback code does not.
2278    ///
2279    /// If the flag [`FileCopyFlags::OVERWRITE`][crate::FileCopyFlags::OVERWRITE] is specified an already
2280    /// existing @destination file is overwritten.
2281    ///
2282    /// If @cancellable is not [`None`], then the operation can be cancelled by
2283    /// triggering the cancellable object from another thread. If the operation
2284    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2285    ///
2286    /// If @progress_callback is not [`None`], then the operation can be monitored
2287    /// by setting this to a #GFileProgressCallback function.
2288    /// @progress_callback_data will be passed to this function. It is
2289    /// guaranteed that this callback will be called after all data has been
2290    /// transferred with the total number of bytes copied during the operation.
2291    ///
2292    /// If the @self file does not exist, then the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound]
2293    /// error is returned, independent on the status of the @destination.
2294    ///
2295    /// If [`FileCopyFlags::OVERWRITE`][crate::FileCopyFlags::OVERWRITE] is not specified and the target exists,
2296    /// then the error [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] is returned.
2297    ///
2298    /// If trying to overwrite a file over a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
2299    /// error is returned. If trying to overwrite a directory with a directory the
2300    /// [`IOErrorEnum::WouldMerge`][crate::IOErrorEnum::WouldMerge] error is returned.
2301    ///
2302    /// If the source is a directory and the target does not exist, or
2303    /// [`FileCopyFlags::OVERWRITE`][crate::FileCopyFlags::OVERWRITE] is specified and the target is a file, then
2304    /// the [`IOErrorEnum::WouldRecurse`][crate::IOErrorEnum::WouldRecurse] error may be returned (if the native
2305    /// move operation isn't available).
2306    /// ## `destination`
2307    /// #GFile pointing to the destination location
2308    /// ## `flags`
2309    /// set of #GFileCopyFlags
2310    /// ## `cancellable`
2311    /// optional #GCancellable object,
2312    ///   [`None`] to ignore
2313    /// ## `progress_callback`
2314    /// #GFileProgressCallback
2315    ///   function for updates
2316    /// ## `progress_callback_data`
2317    /// gpointer to user data for
2318    ///   the callback function
2319    ///
2320    /// # Returns
2321    ///
2322    /// [`true`] on successful move, [`false`] otherwise.
2323    #[doc(alias = "g_file_move")]
2324    #[doc(alias = "move")]
2325    fn move_(
2326        &self,
2327        destination: &impl IsA<File>,
2328        flags: FileCopyFlags,
2329        cancellable: Option<&impl IsA<Cancellable>>,
2330        progress_callback: Option<&mut dyn FnMut(i64, i64)>,
2331    ) -> Result<(), glib::Error> {
2332        let mut progress_callback_data: Option<&mut dyn FnMut(i64, i64)> = progress_callback;
2333        unsafe extern "C" fn progress_callback_func(
2334            current_num_bytes: i64,
2335            total_num_bytes: i64,
2336            data: glib::ffi::gpointer,
2337        ) {
2338            unsafe {
2339                let callback = data as *mut Option<&mut dyn FnMut(i64, i64)>;
2340                if let Some(ref mut callback) = *callback {
2341                    callback(current_num_bytes, total_num_bytes)
2342                } else {
2343                    panic!("cannot get closure...")
2344                }
2345            }
2346        }
2347        let progress_callback = if progress_callback_data.is_some() {
2348            Some(progress_callback_func as _)
2349        } else {
2350            None
2351        };
2352        let super_callback0: &mut Option<&mut dyn FnMut(i64, i64)> = &mut progress_callback_data;
2353        unsafe {
2354            let mut error = std::ptr::null_mut();
2355            let is_ok = ffi::g_file_move(
2356                self.as_ref().to_glib_none().0,
2357                destination.as_ref().to_glib_none().0,
2358                flags.into_glib(),
2359                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2360                progress_callback,
2361                super_callback0 as *mut _ as *mut _,
2362                &mut error,
2363            );
2364            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
2365            if error.is_null() {
2366                Ok(())
2367            } else {
2368                Err(from_glib_full(error))
2369            }
2370        }
2371    }
2372
2373    /// Opens an existing file for reading and writing. The result is
2374    /// a #GFileIOStream that can be used to read and write the contents
2375    /// of the file.
2376    ///
2377    /// If @cancellable is not [`None`], then the operation can be cancelled
2378    /// by triggering the cancellable object from another thread. If the
2379    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
2380    /// returned.
2381    ///
2382    /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will
2383    /// be returned. If the file is a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
2384    /// error will be returned. Other errors are possible too, and depend on
2385    /// what kind of filesystem the file is on. Note that in many non-local
2386    /// file cases read and write streams are not supported, so make sure you
2387    /// really need to do read and write streaming, rather than just opening
2388    /// for reading or writing.
2389    /// ## `cancellable`
2390    /// a #GCancellable
2391    ///
2392    /// # Returns
2393    ///
2394    /// #GFileIOStream or [`None`] on error.
2395    ///   Free the returned object with g_object_unref().
2396    #[doc(alias = "g_file_open_readwrite")]
2397    fn open_readwrite(
2398        &self,
2399        cancellable: Option<&impl IsA<Cancellable>>,
2400    ) -> Result<FileIOStream, glib::Error> {
2401        unsafe {
2402            let mut error = std::ptr::null_mut();
2403            let ret = ffi::g_file_open_readwrite(
2404                self.as_ref().to_glib_none().0,
2405                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2406                &mut error,
2407            );
2408            if error.is_null() {
2409                Ok(from_glib_full(ret))
2410            } else {
2411                Err(from_glib_full(error))
2412            }
2413        }
2414    }
2415
2416    /// Asynchronously opens @self for reading and writing.
2417    ///
2418    /// For more details, see g_file_open_readwrite() which is
2419    /// the synchronous version of this call.
2420    ///
2421    /// When the operation is finished, @callback will be called.
2422    /// You can then call g_file_open_readwrite_finish() to get
2423    /// the result of the operation.
2424    /// ## `io_priority`
2425    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2426    /// ## `cancellable`
2427    /// optional #GCancellable object,
2428    ///   [`None`] to ignore
2429    /// ## `callback`
2430    /// a #GAsyncReadyCallback
2431    ///   to call when the request is satisfied
2432    #[doc(alias = "g_file_open_readwrite_async")]
2433    fn open_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
2434        &self,
2435        io_priority: glib::Priority,
2436        cancellable: Option<&impl IsA<Cancellable>>,
2437        callback: P,
2438    ) {
2439        let main_context = glib::MainContext::ref_thread_default();
2440        let is_main_context_owner = main_context.is_owner();
2441        let has_acquired_main_context = (!is_main_context_owner)
2442            .then(|| main_context.acquire().ok())
2443            .flatten();
2444        assert!(
2445            is_main_context_owner || has_acquired_main_context.is_some(),
2446            "Async operations only allowed if the thread is owning the MainContext"
2447        );
2448
2449        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2450            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2451        unsafe extern "C" fn open_readwrite_async_trampoline<
2452            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
2453        >(
2454            _source_object: *mut glib::gobject_ffi::GObject,
2455            res: *mut crate::ffi::GAsyncResult,
2456            user_data: glib::ffi::gpointer,
2457        ) {
2458            unsafe {
2459                let mut error = std::ptr::null_mut();
2460                let ret =
2461                    ffi::g_file_open_readwrite_finish(_source_object as *mut _, res, &mut error);
2462                let result = if error.is_null() {
2463                    Ok(from_glib_full(ret))
2464                } else {
2465                    Err(from_glib_full(error))
2466                };
2467                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2468                    Box_::from_raw(user_data as *mut _);
2469                let callback: P = callback.into_inner();
2470                callback(result);
2471            }
2472        }
2473        let callback = open_readwrite_async_trampoline::<P>;
2474        unsafe {
2475            ffi::g_file_open_readwrite_async(
2476                self.as_ref().to_glib_none().0,
2477                io_priority.into_glib(),
2478                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2479                Some(callback),
2480                Box_::into_raw(user_data) as *mut _,
2481            );
2482        }
2483    }
2484
2485    fn open_readwrite_future(
2486        &self,
2487        io_priority: glib::Priority,
2488    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
2489    {
2490        Box_::pin(crate::GioFuture::new(
2491            self,
2492            move |obj, cancellable, send| {
2493                obj.open_readwrite_async(io_priority, Some(cancellable), move |res| {
2494                    send.resolve(res);
2495                });
2496            },
2497        ))
2498    }
2499
2500    /// Exactly like g_file_get_path(), but caches the result via
2501    /// g_object_set_qdata_full().  This is useful for example in C
2502    /// applications which mix `g_file_*` APIs with native ones.  It
2503    /// also avoids an extra duplicated string when possible, so will be
2504    /// generally more efficient.
2505    ///
2506    /// This call does no blocking I/O.
2507    ///
2508    /// # Returns
2509    ///
2510    /// string containing the #GFile's path,
2511    ///   or [`None`] if no such path exists. The returned string is owned by @self.
2512    #[doc(alias = "g_file_peek_path")]
2513    fn peek_path(&self) -> Option<std::path::PathBuf> {
2514        unsafe { from_glib_none(ffi::g_file_peek_path(self.as_ref().to_glib_none().0)) }
2515    }
2516
2517    /// Polls a file of type [`FileType::Mountable`][crate::FileType::Mountable].
2518    ///
2519    /// If @cancellable is not [`None`], then the operation can be cancelled by
2520    /// triggering the cancellable object from another thread. If the operation
2521    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2522    ///
2523    /// When the operation is finished, @callback will be called.
2524    /// You can then call g_file_mount_mountable_finish() to get
2525    /// the result of the operation.
2526    /// ## `cancellable`
2527    /// optional #GCancellable object, [`None`] to ignore
2528    /// ## `callback`
2529    /// a #GAsyncReadyCallback to call
2530    ///   when the request is satisfied, or [`None`]
2531    #[doc(alias = "g_file_poll_mountable")]
2532    fn poll_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
2533        &self,
2534        cancellable: Option<&impl IsA<Cancellable>>,
2535        callback: P,
2536    ) {
2537        let main_context = glib::MainContext::ref_thread_default();
2538        let is_main_context_owner = main_context.is_owner();
2539        let has_acquired_main_context = (!is_main_context_owner)
2540            .then(|| main_context.acquire().ok())
2541            .flatten();
2542        assert!(
2543            is_main_context_owner || has_acquired_main_context.is_some(),
2544            "Async operations only allowed if the thread is owning the MainContext"
2545        );
2546
2547        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2548            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2549        unsafe extern "C" fn poll_mountable_trampoline<
2550            P: FnOnce(Result<(), glib::Error>) + 'static,
2551        >(
2552            _source_object: *mut glib::gobject_ffi::GObject,
2553            res: *mut crate::ffi::GAsyncResult,
2554            user_data: glib::ffi::gpointer,
2555        ) {
2556            unsafe {
2557                let mut error = std::ptr::null_mut();
2558                ffi::g_file_poll_mountable_finish(_source_object as *mut _, res, &mut error);
2559                let result = if error.is_null() {
2560                    Ok(())
2561                } else {
2562                    Err(from_glib_full(error))
2563                };
2564                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2565                    Box_::from_raw(user_data as *mut _);
2566                let callback: P = callback.into_inner();
2567                callback(result);
2568            }
2569        }
2570        let callback = poll_mountable_trampoline::<P>;
2571        unsafe {
2572            ffi::g_file_poll_mountable(
2573                self.as_ref().to_glib_none().0,
2574                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2575                Some(callback),
2576                Box_::into_raw(user_data) as *mut _,
2577            );
2578        }
2579    }
2580
2581    fn poll_mountable_future(
2582        &self,
2583    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
2584        Box_::pin(crate::GioFuture::new(
2585            self,
2586            move |obj, cancellable, send| {
2587                obj.poll_mountable(Some(cancellable), move |res| {
2588                    send.resolve(res);
2589                });
2590            },
2591        ))
2592    }
2593
2594    /// Returns the #GAppInfo that is registered as the default
2595    /// application to handle the file specified by @self.
2596    ///
2597    /// If @cancellable is not [`None`], then the operation can be cancelled by
2598    /// triggering the cancellable object from another thread. If the operation
2599    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2600    /// ## `cancellable`
2601    /// optional #GCancellable object, [`None`] to ignore
2602    ///
2603    /// # Returns
2604    ///
2605    /// a #GAppInfo if the handle was found,
2606    ///   [`None`] if there were errors.
2607    ///   When you are done with it, release it with g_object_unref()
2608    #[doc(alias = "g_file_query_default_handler")]
2609    fn query_default_handler(
2610        &self,
2611        cancellable: Option<&impl IsA<Cancellable>>,
2612    ) -> Result<AppInfo, glib::Error> {
2613        unsafe {
2614            let mut error = std::ptr::null_mut();
2615            let ret = ffi::g_file_query_default_handler(
2616                self.as_ref().to_glib_none().0,
2617                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2618                &mut error,
2619            );
2620            if error.is_null() {
2621                Ok(from_glib_full(ret))
2622            } else {
2623                Err(from_glib_full(error))
2624            }
2625        }
2626    }
2627
2628    /// Async version of g_file_query_default_handler().
2629    /// ## `io_priority`
2630    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2631    /// ## `cancellable`
2632    /// optional #GCancellable object, [`None`] to ignore
2633    /// ## `callback`
2634    /// a #GAsyncReadyCallback to call when the request is done
2635    #[cfg(feature = "v2_60")]
2636    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
2637    #[doc(alias = "g_file_query_default_handler_async")]
2638    fn query_default_handler_async<P: FnOnce(Result<AppInfo, glib::Error>) + 'static>(
2639        &self,
2640        io_priority: glib::Priority,
2641        cancellable: Option<&impl IsA<Cancellable>>,
2642        callback: P,
2643    ) {
2644        let main_context = glib::MainContext::ref_thread_default();
2645        let is_main_context_owner = main_context.is_owner();
2646        let has_acquired_main_context = (!is_main_context_owner)
2647            .then(|| main_context.acquire().ok())
2648            .flatten();
2649        assert!(
2650            is_main_context_owner || has_acquired_main_context.is_some(),
2651            "Async operations only allowed if the thread is owning the MainContext"
2652        );
2653
2654        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2655            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2656        unsafe extern "C" fn query_default_handler_async_trampoline<
2657            P: FnOnce(Result<AppInfo, glib::Error>) + 'static,
2658        >(
2659            _source_object: *mut glib::gobject_ffi::GObject,
2660            res: *mut crate::ffi::GAsyncResult,
2661            user_data: glib::ffi::gpointer,
2662        ) {
2663            unsafe {
2664                let mut error = std::ptr::null_mut();
2665                let ret = ffi::g_file_query_default_handler_finish(
2666                    _source_object as *mut _,
2667                    res,
2668                    &mut error,
2669                );
2670                let result = if error.is_null() {
2671                    Ok(from_glib_full(ret))
2672                } else {
2673                    Err(from_glib_full(error))
2674                };
2675                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2676                    Box_::from_raw(user_data as *mut _);
2677                let callback: P = callback.into_inner();
2678                callback(result);
2679            }
2680        }
2681        let callback = query_default_handler_async_trampoline::<P>;
2682        unsafe {
2683            ffi::g_file_query_default_handler_async(
2684                self.as_ref().to_glib_none().0,
2685                io_priority.into_glib(),
2686                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2687                Some(callback),
2688                Box_::into_raw(user_data) as *mut _,
2689            );
2690        }
2691    }
2692
2693    #[cfg(feature = "v2_60")]
2694    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
2695    fn query_default_handler_future(
2696        &self,
2697        io_priority: glib::Priority,
2698    ) -> Pin<Box_<dyn std::future::Future<Output = Result<AppInfo, glib::Error>> + 'static>> {
2699        Box_::pin(crate::GioFuture::new(
2700            self,
2701            move |obj, cancellable, send| {
2702                obj.query_default_handler_async(io_priority, Some(cancellable), move |res| {
2703                    send.resolve(res);
2704                });
2705            },
2706        ))
2707    }
2708
2709    /// Utility function to check if a particular file exists.
2710    ///
2711    /// The fallback implementation of this API is using [`query_info()`][Self::query_info()]
2712    /// and therefore may do blocking I/O. To asynchronously query the existence
2713    /// of a file, use [`query_info_async()`][Self::query_info_async()].
2714    ///
2715    /// Note that in many cases it is [racy to first check for file existence](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use)
2716    /// and then execute something based on the outcome of that, because the
2717    /// file might have been created or removed in between the operations. The
2718    /// general approach to handling that is to not check, but just do the
2719    /// operation and handle the errors as they come.
2720    ///
2721    /// As an example of race-free checking, take the case of reading a file,
2722    /// and if it doesn't exist, creating it. There are two racy versions: read
2723    /// it, and on error create it; and: check if it exists, if not create it.
2724    /// These can both result in two processes creating the file (with perhaps
2725    /// a partially written file as the result). The correct approach is to
2726    /// always try to create the file with g_file_create() which will either
2727    /// atomically create the file or fail with a [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] error.
2728    ///
2729    /// However, in many cases an existence check is useful in a user interface,
2730    /// for instance to make a menu item sensitive/insensitive, so that you don't
2731    /// have to fool users that something is possible and then just show an error
2732    /// dialog. If you do this, you should make sure to also handle the errors
2733    /// that can happen due to races when you execute the operation.
2734    /// ## `cancellable`
2735    /// optional #GCancellable object,
2736    ///   [`None`] to ignore
2737    ///
2738    /// # Returns
2739    ///
2740    /// [`true`] if the file exists (and can be detected without error),
2741    ///   [`false`] otherwise (or if cancelled).
2742    #[doc(alias = "g_file_query_exists")]
2743    fn query_exists(&self, cancellable: Option<&impl IsA<Cancellable>>) -> bool {
2744        unsafe {
2745            from_glib(ffi::g_file_query_exists(
2746                self.as_ref().to_glib_none().0,
2747                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2748            ))
2749        }
2750    }
2751
2752    /// Utility function to inspect the #GFileType of a file. This is
2753    /// implemented using g_file_query_info() and as such does blocking I/O.
2754    ///
2755    /// The primary use case of this method is to check if a file is
2756    /// a regular file, directory, or symlink.
2757    /// ## `flags`
2758    /// a set of #GFileQueryInfoFlags passed to g_file_query_info()
2759    /// ## `cancellable`
2760    /// optional #GCancellable object,
2761    ///   [`None`] to ignore
2762    ///
2763    /// # Returns
2764    ///
2765    /// The #GFileType of the file and [`FileType::Unknown`][crate::FileType::Unknown]
2766    ///   if the file does not exist
2767    #[doc(alias = "g_file_query_file_type")]
2768    fn query_file_type(
2769        &self,
2770        flags: FileQueryInfoFlags,
2771        cancellable: Option<&impl IsA<Cancellable>>,
2772    ) -> FileType {
2773        unsafe {
2774            from_glib(ffi::g_file_query_file_type(
2775                self.as_ref().to_glib_none().0,
2776                flags.into_glib(),
2777                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2778            ))
2779        }
2780    }
2781
2782    /// Similar to g_file_query_info(), but obtains information
2783    /// about the filesystem the @self is on, rather than the file itself.
2784    /// For instance the amount of space available and the type of
2785    /// the filesystem.
2786    ///
2787    /// The @attributes value is a string that specifies the attributes
2788    /// that should be gathered. It is not an error if it's not possible
2789    /// to read a particular requested attribute from a file - it just
2790    /// won't be set. @attributes should be a comma-separated list of
2791    /// attributes or attribute wildcards. The wildcard "*" means all
2792    /// attributes, and a wildcard like "filesystem::*" means all attributes
2793    /// in the filesystem namespace. The standard namespace for filesystem
2794    /// attributes is "filesystem". Common attributes of interest are
2795    /// [`FILE_ATTRIBUTE_FILESYSTEM_SIZE`][crate::FILE_ATTRIBUTE_FILESYSTEM_SIZE] (the total size of the filesystem
2796    /// in bytes), [`FILE_ATTRIBUTE_FILESYSTEM_FREE`][crate::FILE_ATTRIBUTE_FILESYSTEM_FREE] (number of bytes available),
2797    /// and [`FILE_ATTRIBUTE_FILESYSTEM_TYPE`][crate::FILE_ATTRIBUTE_FILESYSTEM_TYPE] (type of the filesystem).
2798    ///
2799    /// If @cancellable is not [`None`], then the operation can be cancelled
2800    /// by triggering the cancellable object from another thread. If the
2801    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
2802    /// returned.
2803    ///
2804    /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will
2805    /// be returned. Other errors are possible too, and depend on what
2806    /// kind of filesystem the file is on.
2807    /// ## `attributes`
2808    /// an attribute query string
2809    /// ## `cancellable`
2810    /// optional #GCancellable object,
2811    ///   [`None`] to ignore
2812    ///
2813    /// # Returns
2814    ///
2815    /// a #GFileInfo or [`None`] if there was an error.
2816    ///   Free the returned object with g_object_unref().
2817    #[doc(alias = "g_file_query_filesystem_info")]
2818    fn query_filesystem_info(
2819        &self,
2820        attributes: &str,
2821        cancellable: Option<&impl IsA<Cancellable>>,
2822    ) -> Result<FileInfo, glib::Error> {
2823        unsafe {
2824            let mut error = std::ptr::null_mut();
2825            let ret = ffi::g_file_query_filesystem_info(
2826                self.as_ref().to_glib_none().0,
2827                attributes.to_glib_none().0,
2828                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2829                &mut error,
2830            );
2831            if error.is_null() {
2832                Ok(from_glib_full(ret))
2833            } else {
2834                Err(from_glib_full(error))
2835            }
2836        }
2837    }
2838
2839    /// Asynchronously gets the requested information about the filesystem
2840    /// that the specified @self is on. The result is a #GFileInfo object
2841    /// that contains key-value attributes (such as type or size for the
2842    /// file).
2843    ///
2844    /// For more details, see g_file_query_filesystem_info() which is the
2845    /// synchronous version of this call.
2846    ///
2847    /// When the operation is finished, @callback will be called. You can
2848    /// then call g_file_query_info_finish() to get the result of the
2849    /// operation.
2850    /// ## `attributes`
2851    /// an attribute query string
2852    /// ## `io_priority`
2853    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2854    /// ## `cancellable`
2855    /// optional #GCancellable object,
2856    ///   [`None`] to ignore
2857    /// ## `callback`
2858    /// a #GAsyncReadyCallback
2859    ///   to call when the request is satisfied
2860    #[doc(alias = "g_file_query_filesystem_info_async")]
2861    fn query_filesystem_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
2862        &self,
2863        attributes: &str,
2864        io_priority: glib::Priority,
2865        cancellable: Option<&impl IsA<Cancellable>>,
2866        callback: P,
2867    ) {
2868        let main_context = glib::MainContext::ref_thread_default();
2869        let is_main_context_owner = main_context.is_owner();
2870        let has_acquired_main_context = (!is_main_context_owner)
2871            .then(|| main_context.acquire().ok())
2872            .flatten();
2873        assert!(
2874            is_main_context_owner || has_acquired_main_context.is_some(),
2875            "Async operations only allowed if the thread is owning the MainContext"
2876        );
2877
2878        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2879            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2880        unsafe extern "C" fn query_filesystem_info_async_trampoline<
2881            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
2882        >(
2883            _source_object: *mut glib::gobject_ffi::GObject,
2884            res: *mut crate::ffi::GAsyncResult,
2885            user_data: glib::ffi::gpointer,
2886        ) {
2887            unsafe {
2888                let mut error = std::ptr::null_mut();
2889                let ret = ffi::g_file_query_filesystem_info_finish(
2890                    _source_object as *mut _,
2891                    res,
2892                    &mut error,
2893                );
2894                let result = if error.is_null() {
2895                    Ok(from_glib_full(ret))
2896                } else {
2897                    Err(from_glib_full(error))
2898                };
2899                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2900                    Box_::from_raw(user_data as *mut _);
2901                let callback: P = callback.into_inner();
2902                callback(result);
2903            }
2904        }
2905        let callback = query_filesystem_info_async_trampoline::<P>;
2906        unsafe {
2907            ffi::g_file_query_filesystem_info_async(
2908                self.as_ref().to_glib_none().0,
2909                attributes.to_glib_none().0,
2910                io_priority.into_glib(),
2911                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2912                Some(callback),
2913                Box_::into_raw(user_data) as *mut _,
2914            );
2915        }
2916    }
2917
2918    fn query_filesystem_info_future(
2919        &self,
2920        attributes: &str,
2921        io_priority: glib::Priority,
2922    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
2923        let attributes = String::from(attributes);
2924        Box_::pin(crate::GioFuture::new(
2925            self,
2926            move |obj, cancellable, send| {
2927                obj.query_filesystem_info_async(
2928                    &attributes,
2929                    io_priority,
2930                    Some(cancellable),
2931                    move |res| {
2932                        send.resolve(res);
2933                    },
2934                );
2935            },
2936        ))
2937    }
2938
2939    /// Gets the requested information about specified @self.
2940    ///
2941    /// The result is a [`FileInfo`][crate::FileInfo] object that contains key-value
2942    /// attributes (such as the type or size of the file).
2943    ///
2944    /// The @attributes value is a string that specifies the file
2945    /// attributes that should be gathered. It is not an error if
2946    /// it’s not possible to read a particular requested attribute
2947    /// from a file — it just won't be set. In particular this means that if a file
2948    /// is inaccessible (due to being in a folder with restrictive permissions), for
2949    /// example, you can expect the returned [`FileInfo`][crate::FileInfo] to have very few
2950    /// attributes set. You should check whether an attribute is set using
2951    /// [`FileInfo::has_attribute()`][crate::FileInfo::has_attribute()] before trying to retrieve its value.
2952    ///
2953    /// It is guaranteed that if any of the following attributes are listed in
2954    /// @attributes, they will always be set in the returned [`FileInfo`][crate::FileInfo],
2955    /// even if the user doesn’t have permissions to access the file:
2956    ///
2957    ///  - `Gio::FILE_ATTRIBUTE_STANDARD_NAME`
2958    ///  - `Gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME`
2959    ///
2960    /// @attributes should be a comma-separated list of attributes or attribute
2961    /// wildcards. The wildcard `"*"` means all attributes, and a wildcard like
2962    /// `"standard::*"` means all attributes in the standard namespace.
2963    /// An example attribute query might be `"standard::*,owner::user"`.
2964    /// The standard attributes are available as defines, like
2965    /// `Gio::FILE_ATTRIBUTE_STANDARD_NAME`.
2966    ///
2967    /// If @cancellable is not `NULL`, then the operation can be cancelled
2968    /// by triggering the cancellable object from another thread. If the
2969    /// operation was cancelled, the error [error@Gio.IOErrorEnum.CANCELLED] will be
2970    /// returned.
2971    ///
2972    /// For symlinks, normally the information about the target of the
2973    /// symlink is returned, rather than information about the symlink
2974    /// itself. However if you pass [flags@Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS]
2975    /// in @flags the information about the symlink itself will be returned.
2976    /// Also, for symlinks that point to non-existing files the information
2977    /// about the symlink itself will be returned.
2978    ///
2979    /// If the file does not exist, the [error@Gio.IOErrorEnum.NOT_FOUND] error will be
2980    /// returned. Other errors are possible too, and depend on what kind of
2981    /// file system the file is on.
2982    /// ## `attributes`
2983    /// an attribute query string
2984    /// ## `flags`
2985    /// flags to affect the query operation
2986    /// ## `cancellable`
2987    /// optional cancellable object
2988    ///
2989    /// # Returns
2990    ///
2991    /// a [`FileInfo`][crate::FileInfo] for the given @self
2992    #[doc(alias = "g_file_query_info")]
2993    fn query_info(
2994        &self,
2995        attributes: &str,
2996        flags: FileQueryInfoFlags,
2997        cancellable: Option<&impl IsA<Cancellable>>,
2998    ) -> Result<FileInfo, glib::Error> {
2999        unsafe {
3000            let mut error = std::ptr::null_mut();
3001            let ret = ffi::g_file_query_info(
3002                self.as_ref().to_glib_none().0,
3003                attributes.to_glib_none().0,
3004                flags.into_glib(),
3005                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3006                &mut error,
3007            );
3008            if error.is_null() {
3009                Ok(from_glib_full(ret))
3010            } else {
3011                Err(from_glib_full(error))
3012            }
3013        }
3014    }
3015
3016    /// Asynchronously gets the requested information about specified @self.
3017    /// The result is a #GFileInfo object that contains key-value attributes
3018    /// (such as type or size for the file).
3019    ///
3020    /// For more details, see g_file_query_info() which is the synchronous
3021    /// version of this call.
3022    ///
3023    /// When the operation is finished, @callback will be called. You can
3024    /// then call g_file_query_info_finish() to get the result of the operation.
3025    /// ## `attributes`
3026    /// an attribute query string
3027    /// ## `flags`
3028    /// a set of #GFileQueryInfoFlags
3029    /// ## `io_priority`
3030    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3031    /// ## `cancellable`
3032    /// optional #GCancellable object,
3033    ///   [`None`] to ignore
3034    /// ## `callback`
3035    /// a #GAsyncReadyCallback
3036    ///   to call when the request is satisfied
3037    #[doc(alias = "g_file_query_info_async")]
3038    fn query_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
3039        &self,
3040        attributes: &str,
3041        flags: FileQueryInfoFlags,
3042        io_priority: glib::Priority,
3043        cancellable: Option<&impl IsA<Cancellable>>,
3044        callback: P,
3045    ) {
3046        let main_context = glib::MainContext::ref_thread_default();
3047        let is_main_context_owner = main_context.is_owner();
3048        let has_acquired_main_context = (!is_main_context_owner)
3049            .then(|| main_context.acquire().ok())
3050            .flatten();
3051        assert!(
3052            is_main_context_owner || has_acquired_main_context.is_some(),
3053            "Async operations only allowed if the thread is owning the MainContext"
3054        );
3055
3056        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3057            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3058        unsafe extern "C" fn query_info_async_trampoline<
3059            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
3060        >(
3061            _source_object: *mut glib::gobject_ffi::GObject,
3062            res: *mut crate::ffi::GAsyncResult,
3063            user_data: glib::ffi::gpointer,
3064        ) {
3065            unsafe {
3066                let mut error = std::ptr::null_mut();
3067                let ret = ffi::g_file_query_info_finish(_source_object as *mut _, res, &mut error);
3068                let result = if error.is_null() {
3069                    Ok(from_glib_full(ret))
3070                } else {
3071                    Err(from_glib_full(error))
3072                };
3073                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3074                    Box_::from_raw(user_data as *mut _);
3075                let callback: P = callback.into_inner();
3076                callback(result);
3077            }
3078        }
3079        let callback = query_info_async_trampoline::<P>;
3080        unsafe {
3081            ffi::g_file_query_info_async(
3082                self.as_ref().to_glib_none().0,
3083                attributes.to_glib_none().0,
3084                flags.into_glib(),
3085                io_priority.into_glib(),
3086                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3087                Some(callback),
3088                Box_::into_raw(user_data) as *mut _,
3089            );
3090        }
3091    }
3092
3093    fn query_info_future(
3094        &self,
3095        attributes: &str,
3096        flags: FileQueryInfoFlags,
3097        io_priority: glib::Priority,
3098    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
3099        let attributes = String::from(attributes);
3100        Box_::pin(crate::GioFuture::new(
3101            self,
3102            move |obj, cancellable, send| {
3103                obj.query_info_async(
3104                    &attributes,
3105                    flags,
3106                    io_priority,
3107                    Some(cancellable),
3108                    move |res| {
3109                        send.resolve(res);
3110                    },
3111                );
3112            },
3113        ))
3114    }
3115
3116    /// Obtain the list of settable attributes for the file.
3117    ///
3118    /// Returns the type and full attribute name of all the attributes
3119    /// that can be set on this file. This doesn't mean setting it will
3120    /// always succeed though, you might get an access failure, or some
3121    /// specific file may not support a specific attribute.
3122    ///
3123    /// If @cancellable is not [`None`], then the operation can be cancelled by
3124    /// triggering the cancellable object from another thread. If the operation
3125    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3126    /// ## `cancellable`
3127    /// optional #GCancellable object,
3128    ///   [`None`] to ignore
3129    ///
3130    /// # Returns
3131    ///
3132    /// a #GFileAttributeInfoList describing the settable attributes.
3133    ///   When you are done with it, release it with
3134    ///   g_file_attribute_info_list_unref()
3135    #[doc(alias = "g_file_query_settable_attributes")]
3136    fn query_settable_attributes(
3137        &self,
3138        cancellable: Option<&impl IsA<Cancellable>>,
3139    ) -> Result<FileAttributeInfoList, glib::Error> {
3140        unsafe {
3141            let mut error = std::ptr::null_mut();
3142            let ret = ffi::g_file_query_settable_attributes(
3143                self.as_ref().to_glib_none().0,
3144                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3145                &mut error,
3146            );
3147            if error.is_null() {
3148                Ok(from_glib_full(ret))
3149            } else {
3150                Err(from_glib_full(error))
3151            }
3152        }
3153    }
3154
3155    /// Obtain the list of attribute namespaces where new attributes
3156    /// can be created by a user. An example of this is extended
3157    /// attributes (in the "xattr" namespace).
3158    ///
3159    /// If @cancellable is not [`None`], then the operation can be cancelled by
3160    /// triggering the cancellable object from another thread. If the operation
3161    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3162    /// ## `cancellable`
3163    /// optional #GCancellable object,
3164    ///   [`None`] to ignore
3165    ///
3166    /// # Returns
3167    ///
3168    /// a #GFileAttributeInfoList describing the writable namespaces.
3169    ///   When you are done with it, release it with
3170    ///   g_file_attribute_info_list_unref()
3171    #[doc(alias = "g_file_query_writable_namespaces")]
3172    fn query_writable_namespaces(
3173        &self,
3174        cancellable: Option<&impl IsA<Cancellable>>,
3175    ) -> Result<FileAttributeInfoList, glib::Error> {
3176        unsafe {
3177            let mut error = std::ptr::null_mut();
3178            let ret = ffi::g_file_query_writable_namespaces(
3179                self.as_ref().to_glib_none().0,
3180                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3181                &mut error,
3182            );
3183            if error.is_null() {
3184                Ok(from_glib_full(ret))
3185            } else {
3186                Err(from_glib_full(error))
3187            }
3188        }
3189    }
3190
3191    /// Opens a file for reading. The result is a #GFileInputStream that
3192    /// can be used to read the contents of the file.
3193    ///
3194    /// If @cancellable is not [`None`], then the operation can be cancelled by
3195    /// triggering the cancellable object from another thread. If the operation
3196    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3197    ///
3198    /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will be
3199    /// returned. If the file is a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
3200    /// error will be returned. Other errors are possible too, and depend
3201    /// on what kind of filesystem the file is on.
3202    /// ## `cancellable`
3203    /// a #GCancellable
3204    ///
3205    /// # Returns
3206    ///
3207    /// #GFileInputStream or [`None`] on error.
3208    ///   Free the returned object with g_object_unref().
3209    #[doc(alias = "g_file_read")]
3210    fn read(
3211        &self,
3212        cancellable: Option<&impl IsA<Cancellable>>,
3213    ) -> Result<FileInputStream, glib::Error> {
3214        unsafe {
3215            let mut error = std::ptr::null_mut();
3216            let ret = ffi::g_file_read(
3217                self.as_ref().to_glib_none().0,
3218                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3219                &mut error,
3220            );
3221            if error.is_null() {
3222                Ok(from_glib_full(ret))
3223            } else {
3224                Err(from_glib_full(error))
3225            }
3226        }
3227    }
3228
3229    /// Asynchronously opens @self for reading.
3230    ///
3231    /// For more details, see g_file_read() which is
3232    /// the synchronous version of this call.
3233    ///
3234    /// When the operation is finished, @callback will be called.
3235    /// You can then call g_file_read_finish() to get the result
3236    /// of the operation.
3237    /// ## `io_priority`
3238    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3239    /// ## `cancellable`
3240    /// optional #GCancellable object,
3241    ///   [`None`] to ignore
3242    /// ## `callback`
3243    /// a #GAsyncReadyCallback
3244    ///   to call when the request is satisfied
3245    #[doc(alias = "g_file_read_async")]
3246    fn read_async<P: FnOnce(Result<FileInputStream, glib::Error>) + 'static>(
3247        &self,
3248        io_priority: glib::Priority,
3249        cancellable: Option<&impl IsA<Cancellable>>,
3250        callback: P,
3251    ) {
3252        let main_context = glib::MainContext::ref_thread_default();
3253        let is_main_context_owner = main_context.is_owner();
3254        let has_acquired_main_context = (!is_main_context_owner)
3255            .then(|| main_context.acquire().ok())
3256            .flatten();
3257        assert!(
3258            is_main_context_owner || has_acquired_main_context.is_some(),
3259            "Async operations only allowed if the thread is owning the MainContext"
3260        );
3261
3262        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3263            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3264        unsafe extern "C" fn read_async_trampoline<
3265            P: FnOnce(Result<FileInputStream, glib::Error>) + 'static,
3266        >(
3267            _source_object: *mut glib::gobject_ffi::GObject,
3268            res: *mut crate::ffi::GAsyncResult,
3269            user_data: glib::ffi::gpointer,
3270        ) {
3271            unsafe {
3272                let mut error = std::ptr::null_mut();
3273                let ret = ffi::g_file_read_finish(_source_object as *mut _, res, &mut error);
3274                let result = if error.is_null() {
3275                    Ok(from_glib_full(ret))
3276                } else {
3277                    Err(from_glib_full(error))
3278                };
3279                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3280                    Box_::from_raw(user_data as *mut _);
3281                let callback: P = callback.into_inner();
3282                callback(result);
3283            }
3284        }
3285        let callback = read_async_trampoline::<P>;
3286        unsafe {
3287            ffi::g_file_read_async(
3288                self.as_ref().to_glib_none().0,
3289                io_priority.into_glib(),
3290                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3291                Some(callback),
3292                Box_::into_raw(user_data) as *mut _,
3293            );
3294        }
3295    }
3296
3297    fn read_future(
3298        &self,
3299        io_priority: glib::Priority,
3300    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInputStream, glib::Error>> + 'static>>
3301    {
3302        Box_::pin(crate::GioFuture::new(
3303            self,
3304            move |obj, cancellable, send| {
3305                obj.read_async(io_priority, Some(cancellable), move |res| {
3306                    send.resolve(res);
3307                });
3308            },
3309        ))
3310    }
3311
3312    /// Returns an output stream for overwriting the file, possibly
3313    /// creating a backup copy of the file first. If the file doesn't exist,
3314    /// it will be created.
3315    ///
3316    /// This will try to replace the file in the safest way possible so
3317    /// that any errors during the writing will not affect an already
3318    /// existing copy of the file. For instance, for local files it
3319    /// may write to a temporary file and then atomically rename over
3320    /// the destination when the stream is closed.
3321    ///
3322    /// By default files created are generally readable by everyone,
3323    /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
3324    /// will be made readable only to the current user, to the level that
3325    /// is supported on the target filesystem.
3326    ///
3327    /// If @cancellable is not [`None`], then the operation can be cancelled
3328    /// by triggering the cancellable object from another thread. If the
3329    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
3330    /// returned.
3331    ///
3332    /// If you pass in a non-[`None`] @etag value and @self already exists, then
3333    /// this value is compared to the current entity tag of the file, and if
3334    /// they differ an [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] error is returned. This
3335    /// generally means that the file has been changed since you last read
3336    /// it. You can get the new etag from g_file_output_stream_get_etag()
3337    /// after you've finished writing and closed the #GFileOutputStream. When
3338    /// you load a new file you can use g_file_input_stream_query_info() to
3339    /// get the etag of the file.
3340    ///
3341    /// If @make_backup is [`true`], this function will attempt to make a
3342    /// backup of the current file before overwriting it. If this fails
3343    /// a [`IOErrorEnum::CantCreateBackup`][crate::IOErrorEnum::CantCreateBackup] error will be returned. If you
3344    /// want to replace anyway, try again with @make_backup set to [`false`].
3345    ///
3346    /// If the file is a directory the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory] error will
3347    /// be returned, and if the file is some other form of non-regular file
3348    /// then a [`IOErrorEnum::NotRegularFile`][crate::IOErrorEnum::NotRegularFile] error will be returned. Some
3349    /// file systems don't allow all file names, and may return an
3350    /// [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename] error, and if the name is to long
3351    /// [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong] will be returned. Other errors are
3352    /// possible too, and depend on what kind of filesystem the file is on.
3353    /// ## `etag`
3354    /// an optional [entity tag](#entity-tags)
3355    ///   for the current #GFile, or #NULL to ignore
3356    /// ## `make_backup`
3357    /// [`true`] if a backup should be created
3358    /// ## `flags`
3359    /// a set of #GFileCreateFlags
3360    /// ## `cancellable`
3361    /// optional #GCancellable object,
3362    ///   [`None`] to ignore
3363    ///
3364    /// # Returns
3365    ///
3366    /// a #GFileOutputStream or [`None`] on error.
3367    ///   Free the returned object with g_object_unref().
3368    #[doc(alias = "g_file_replace")]
3369    fn replace(
3370        &self,
3371        etag: Option<&str>,
3372        make_backup: bool,
3373        flags: FileCreateFlags,
3374        cancellable: Option<&impl IsA<Cancellable>>,
3375    ) -> Result<FileOutputStream, glib::Error> {
3376        unsafe {
3377            let mut error = std::ptr::null_mut();
3378            let ret = ffi::g_file_replace(
3379                self.as_ref().to_glib_none().0,
3380                etag.to_glib_none().0,
3381                make_backup.into_glib(),
3382                flags.into_glib(),
3383                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3384                &mut error,
3385            );
3386            if error.is_null() {
3387                Ok(from_glib_full(ret))
3388            } else {
3389                Err(from_glib_full(error))
3390            }
3391        }
3392    }
3393
3394    /// Asynchronously overwrites the file, replacing the contents,
3395    /// possibly creating a backup copy of the file first.
3396    ///
3397    /// For more details, see g_file_replace() which is
3398    /// the synchronous version of this call.
3399    ///
3400    /// When the operation is finished, @callback will be called.
3401    /// You can then call g_file_replace_finish() to get the result
3402    /// of the operation.
3403    /// ## `etag`
3404    /// an [entity tag](#entity-tags) for the current #GFile,
3405    ///   or [`None`] to ignore
3406    /// ## `make_backup`
3407    /// [`true`] if a backup should be created
3408    /// ## `flags`
3409    /// a set of #GFileCreateFlags
3410    /// ## `io_priority`
3411    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3412    /// ## `cancellable`
3413    /// optional #GCancellable object,
3414    ///   [`None`] to ignore
3415    /// ## `callback`
3416    /// a #GAsyncReadyCallback
3417    ///   to call when the request is satisfied
3418    #[doc(alias = "g_file_replace_async")]
3419    fn replace_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
3420        &self,
3421        etag: Option<&str>,
3422        make_backup: bool,
3423        flags: FileCreateFlags,
3424        io_priority: glib::Priority,
3425        cancellable: Option<&impl IsA<Cancellable>>,
3426        callback: P,
3427    ) {
3428        let main_context = glib::MainContext::ref_thread_default();
3429        let is_main_context_owner = main_context.is_owner();
3430        let has_acquired_main_context = (!is_main_context_owner)
3431            .then(|| main_context.acquire().ok())
3432            .flatten();
3433        assert!(
3434            is_main_context_owner || has_acquired_main_context.is_some(),
3435            "Async operations only allowed if the thread is owning the MainContext"
3436        );
3437
3438        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3439            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3440        unsafe extern "C" fn replace_async_trampoline<
3441            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
3442        >(
3443            _source_object: *mut glib::gobject_ffi::GObject,
3444            res: *mut crate::ffi::GAsyncResult,
3445            user_data: glib::ffi::gpointer,
3446        ) {
3447            unsafe {
3448                let mut error = std::ptr::null_mut();
3449                let ret = ffi::g_file_replace_finish(_source_object as *mut _, res, &mut error);
3450                let result = if error.is_null() {
3451                    Ok(from_glib_full(ret))
3452                } else {
3453                    Err(from_glib_full(error))
3454                };
3455                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3456                    Box_::from_raw(user_data as *mut _);
3457                let callback: P = callback.into_inner();
3458                callback(result);
3459            }
3460        }
3461        let callback = replace_async_trampoline::<P>;
3462        unsafe {
3463            ffi::g_file_replace_async(
3464                self.as_ref().to_glib_none().0,
3465                etag.to_glib_none().0,
3466                make_backup.into_glib(),
3467                flags.into_glib(),
3468                io_priority.into_glib(),
3469                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3470                Some(callback),
3471                Box_::into_raw(user_data) as *mut _,
3472            );
3473        }
3474    }
3475
3476    fn replace_future(
3477        &self,
3478        etag: Option<&str>,
3479        make_backup: bool,
3480        flags: FileCreateFlags,
3481        io_priority: glib::Priority,
3482    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
3483    {
3484        let etag = etag.map(ToOwned::to_owned);
3485        Box_::pin(crate::GioFuture::new(
3486            self,
3487            move |obj, cancellable, send| {
3488                obj.replace_async(
3489                    etag.as_ref().map(::std::borrow::Borrow::borrow),
3490                    make_backup,
3491                    flags,
3492                    io_priority,
3493                    Some(cancellable),
3494                    move |res| {
3495                        send.resolve(res);
3496                    },
3497                );
3498            },
3499        ))
3500    }
3501
3502    /// Replaces the contents of @self with @contents of @length bytes.
3503    ///
3504    /// If @etag is specified (not [`None`]), any existing file must have that etag,
3505    /// or the error [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] will be returned.
3506    ///
3507    /// If @make_backup is [`true`], this function will attempt to make a backup
3508    /// of @self. Internally, it uses g_file_replace(), so will try to replace the
3509    /// file contents in the safest way possible. For example, atomic renames are
3510    /// used when replacing local files’ contents.
3511    ///
3512    /// If @cancellable is not [`None`], then the operation can be cancelled by
3513    /// triggering the cancellable object from another thread. If the operation
3514    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3515    ///
3516    /// The returned @new_etag can be used to verify that the file hasn't
3517    /// changed the next time it is saved over.
3518    /// ## `contents`
3519    /// a string containing the new contents for @self
3520    /// ## `etag`
3521    /// the old [entity-tag](#entity-tags) for the document,
3522    ///   or [`None`]
3523    /// ## `make_backup`
3524    /// [`true`] if a backup should be created
3525    /// ## `flags`
3526    /// a set of #GFileCreateFlags
3527    /// ## `cancellable`
3528    /// optional #GCancellable object, [`None`] to ignore
3529    ///
3530    /// # Returns
3531    ///
3532    /// [`true`] if successful. If an error has occurred, this function
3533    ///   will return [`false`] and set @error appropriately if present.
3534    ///
3535    /// ## `new_etag`
3536    /// a location to a new [entity tag](#entity-tags)
3537    ///   for the document. This should be freed with g_free() when no longer
3538    ///   needed, or [`None`]
3539    #[doc(alias = "g_file_replace_contents")]
3540    fn replace_contents(
3541        &self,
3542        contents: &[u8],
3543        etag: Option<&str>,
3544        make_backup: bool,
3545        flags: FileCreateFlags,
3546        cancellable: Option<&impl IsA<Cancellable>>,
3547    ) -> Result<Option<glib::GString>, glib::Error> {
3548        let length = contents.len() as _;
3549        unsafe {
3550            let mut new_etag = std::ptr::null_mut();
3551            let mut error = std::ptr::null_mut();
3552            let is_ok = ffi::g_file_replace_contents(
3553                self.as_ref().to_glib_none().0,
3554                contents.to_glib_none().0,
3555                length,
3556                etag.to_glib_none().0,
3557                make_backup.into_glib(),
3558                flags.into_glib(),
3559                &mut new_etag,
3560                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3561                &mut error,
3562            );
3563            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3564            if error.is_null() {
3565                Ok(from_glib_full(new_etag))
3566            } else {
3567                Err(from_glib_full(error))
3568            }
3569        }
3570    }
3571
3572    //#[doc(alias = "g_file_replace_contents_bytes_async")]
3573    //fn replace_contents_bytes_async<P: FnOnce(Result<(), glib::Error>) + 'static>(&self, contents: &glib::Bytes, etag: Option<&str>, make_backup: bool, flags: FileCreateFlags, cancellable: Option<&impl IsA<Cancellable>>, callback: P) {
3574    //    unsafe { TODO: call ffi:g_file_replace_contents_bytes_async() }
3575    //}
3576
3577    /// Returns an output stream for overwriting the file in readwrite mode,
3578    /// possibly creating a backup copy of the file first. If the file doesn't
3579    /// exist, it will be created.
3580    ///
3581    /// For details about the behaviour, see g_file_replace() which does the
3582    /// same thing but returns an output stream only.
3583    ///
3584    /// Note that in many non-local file cases read and write streams are not
3585    /// supported, so make sure you really need to do read and write streaming,
3586    /// rather than just opening for reading or writing.
3587    /// ## `etag`
3588    /// an optional [entity tag](#entity-tags)
3589    ///   for the current #GFile, or #NULL to ignore
3590    /// ## `make_backup`
3591    /// [`true`] if a backup should be created
3592    /// ## `flags`
3593    /// a set of #GFileCreateFlags
3594    /// ## `cancellable`
3595    /// optional #GCancellable object,
3596    ///   [`None`] to ignore
3597    ///
3598    /// # Returns
3599    ///
3600    /// a #GFileIOStream or [`None`] on error.
3601    ///   Free the returned object with g_object_unref().
3602    #[doc(alias = "g_file_replace_readwrite")]
3603    fn replace_readwrite(
3604        &self,
3605        etag: Option<&str>,
3606        make_backup: bool,
3607        flags: FileCreateFlags,
3608        cancellable: Option<&impl IsA<Cancellable>>,
3609    ) -> Result<FileIOStream, glib::Error> {
3610        unsafe {
3611            let mut error = std::ptr::null_mut();
3612            let ret = ffi::g_file_replace_readwrite(
3613                self.as_ref().to_glib_none().0,
3614                etag.to_glib_none().0,
3615                make_backup.into_glib(),
3616                flags.into_glib(),
3617                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3618                &mut error,
3619            );
3620            if error.is_null() {
3621                Ok(from_glib_full(ret))
3622            } else {
3623                Err(from_glib_full(error))
3624            }
3625        }
3626    }
3627
3628    /// Asynchronously overwrites the file in read-write mode,
3629    /// replacing the contents, possibly creating a backup copy
3630    /// of the file first.
3631    ///
3632    /// For more details, see g_file_replace_readwrite() which is
3633    /// the synchronous version of this call.
3634    ///
3635    /// When the operation is finished, @callback will be called.
3636    /// You can then call g_file_replace_readwrite_finish() to get
3637    /// the result of the operation.
3638    /// ## `etag`
3639    /// an [entity tag](#entity-tags) for the current #GFile,
3640    ///   or [`None`] to ignore
3641    /// ## `make_backup`
3642    /// [`true`] if a backup should be created
3643    /// ## `flags`
3644    /// a set of #GFileCreateFlags
3645    /// ## `io_priority`
3646    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3647    /// ## `cancellable`
3648    /// optional #GCancellable object,
3649    ///   [`None`] to ignore
3650    /// ## `callback`
3651    /// a #GAsyncReadyCallback
3652    ///   to call when the request is satisfied
3653    #[doc(alias = "g_file_replace_readwrite_async")]
3654    fn replace_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
3655        &self,
3656        etag: Option<&str>,
3657        make_backup: bool,
3658        flags: FileCreateFlags,
3659        io_priority: glib::Priority,
3660        cancellable: Option<&impl IsA<Cancellable>>,
3661        callback: P,
3662    ) {
3663        let main_context = glib::MainContext::ref_thread_default();
3664        let is_main_context_owner = main_context.is_owner();
3665        let has_acquired_main_context = (!is_main_context_owner)
3666            .then(|| main_context.acquire().ok())
3667            .flatten();
3668        assert!(
3669            is_main_context_owner || has_acquired_main_context.is_some(),
3670            "Async operations only allowed if the thread is owning the MainContext"
3671        );
3672
3673        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3674            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3675        unsafe extern "C" fn replace_readwrite_async_trampoline<
3676            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
3677        >(
3678            _source_object: *mut glib::gobject_ffi::GObject,
3679            res: *mut crate::ffi::GAsyncResult,
3680            user_data: glib::ffi::gpointer,
3681        ) {
3682            unsafe {
3683                let mut error = std::ptr::null_mut();
3684                let ret =
3685                    ffi::g_file_replace_readwrite_finish(_source_object as *mut _, res, &mut error);
3686                let result = if error.is_null() {
3687                    Ok(from_glib_full(ret))
3688                } else {
3689                    Err(from_glib_full(error))
3690                };
3691                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3692                    Box_::from_raw(user_data as *mut _);
3693                let callback: P = callback.into_inner();
3694                callback(result);
3695            }
3696        }
3697        let callback = replace_readwrite_async_trampoline::<P>;
3698        unsafe {
3699            ffi::g_file_replace_readwrite_async(
3700                self.as_ref().to_glib_none().0,
3701                etag.to_glib_none().0,
3702                make_backup.into_glib(),
3703                flags.into_glib(),
3704                io_priority.into_glib(),
3705                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3706                Some(callback),
3707                Box_::into_raw(user_data) as *mut _,
3708            );
3709        }
3710    }
3711
3712    fn replace_readwrite_future(
3713        &self,
3714        etag: Option<&str>,
3715        make_backup: bool,
3716        flags: FileCreateFlags,
3717        io_priority: glib::Priority,
3718    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
3719    {
3720        let etag = etag.map(ToOwned::to_owned);
3721        Box_::pin(crate::GioFuture::new(
3722            self,
3723            move |obj, cancellable, send| {
3724                obj.replace_readwrite_async(
3725                    etag.as_ref().map(::std::borrow::Borrow::borrow),
3726                    make_backup,
3727                    flags,
3728                    io_priority,
3729                    Some(cancellable),
3730                    move |res| {
3731                        send.resolve(res);
3732                    },
3733                );
3734            },
3735        ))
3736    }
3737
3738    /// Resolves a relative path for @self to an absolute path.
3739    ///
3740    /// This call does no blocking I/O.
3741    ///
3742    /// If the @relative_path is an absolute path name, the resolution
3743    /// is done absolutely (without taking @self path as base).
3744    /// ## `relative_path`
3745    /// a given relative path string
3746    ///
3747    /// # Returns
3748    ///
3749    /// a #GFile for the resolved path.
3750    #[doc(alias = "g_file_resolve_relative_path")]
3751    #[must_use]
3752    fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
3753        unsafe {
3754            from_glib_full(ffi::g_file_resolve_relative_path(
3755                self.as_ref().to_glib_none().0,
3756                relative_path.as_ref().to_glib_none().0,
3757            ))
3758        }
3759    }
3760
3761    //#[doc(alias = "g_file_set_attribute")]
3762    //fn set_attribute(&self, attribute: &str, type_: FileAttributeType, value_p: /*Unimplemented*/Option<Basic: Pointer>, flags: FileQueryInfoFlags, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
3763    //    unsafe { TODO: call ffi:g_file_set_attribute() }
3764    //}
3765
3766    /// Sets @attribute of type [`FileAttributeType::ByteString`][crate::FileAttributeType::ByteString] to @value.
3767    /// If @attribute is of a different type, this operation will fail,
3768    /// returning [`false`].
3769    ///
3770    /// If @cancellable is not [`None`], then the operation can be cancelled by
3771    /// triggering the cancellable object from another thread. If the operation
3772    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3773    /// ## `attribute`
3774    /// a string containing the attribute's name
3775    /// ## `value`
3776    /// a string containing the attribute's new value
3777    /// ## `flags`
3778    /// a #GFileQueryInfoFlags
3779    /// ## `cancellable`
3780    /// optional #GCancellable object,
3781    ///   [`None`] to ignore
3782    ///
3783    /// # Returns
3784    ///
3785    /// [`true`] if the @attribute was successfully set to @value
3786    ///   in the @self, [`false`] otherwise.
3787    #[doc(alias = "g_file_set_attribute_byte_string")]
3788    fn set_attribute_byte_string(
3789        &self,
3790        attribute: &str,
3791        value: &str,
3792        flags: FileQueryInfoFlags,
3793        cancellable: Option<&impl IsA<Cancellable>>,
3794    ) -> Result<(), glib::Error> {
3795        unsafe {
3796            let mut error = std::ptr::null_mut();
3797            let is_ok = ffi::g_file_set_attribute_byte_string(
3798                self.as_ref().to_glib_none().0,
3799                attribute.to_glib_none().0,
3800                value.to_glib_none().0,
3801                flags.into_glib(),
3802                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3803                &mut error,
3804            );
3805            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3806            if error.is_null() {
3807                Ok(())
3808            } else {
3809                Err(from_glib_full(error))
3810            }
3811        }
3812    }
3813
3814    /// Sets @attribute of type [`FileAttributeType::Int32`][crate::FileAttributeType::Int32] to @value.
3815    /// If @attribute is of a different type, this operation will fail.
3816    ///
3817    /// If @cancellable is not [`None`], then the operation can be cancelled by
3818    /// triggering the cancellable object from another thread. If the operation
3819    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3820    /// ## `attribute`
3821    /// a string containing the attribute's name
3822    /// ## `value`
3823    /// a #gint32 containing the attribute's new value
3824    /// ## `flags`
3825    /// a #GFileQueryInfoFlags
3826    /// ## `cancellable`
3827    /// optional #GCancellable object,
3828    ///   [`None`] to ignore
3829    ///
3830    /// # Returns
3831    ///
3832    /// [`true`] if the @attribute was successfully set to @value
3833    ///   in the @self, [`false`] otherwise.
3834    #[doc(alias = "g_file_set_attribute_int32")]
3835    fn set_attribute_int32(
3836        &self,
3837        attribute: &str,
3838        value: i32,
3839        flags: FileQueryInfoFlags,
3840        cancellable: Option<&impl IsA<Cancellable>>,
3841    ) -> Result<(), glib::Error> {
3842        unsafe {
3843            let mut error = std::ptr::null_mut();
3844            let is_ok = ffi::g_file_set_attribute_int32(
3845                self.as_ref().to_glib_none().0,
3846                attribute.to_glib_none().0,
3847                value,
3848                flags.into_glib(),
3849                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3850                &mut error,
3851            );
3852            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3853            if error.is_null() {
3854                Ok(())
3855            } else {
3856                Err(from_glib_full(error))
3857            }
3858        }
3859    }
3860
3861    /// Sets @attribute of type [`FileAttributeType::Int64`][crate::FileAttributeType::Int64] to @value.
3862    /// If @attribute is of a different type, this operation will fail.
3863    ///
3864    /// If @cancellable is not [`None`], then the operation can be cancelled by
3865    /// triggering the cancellable object from another thread. If the operation
3866    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3867    /// ## `attribute`
3868    /// a string containing the attribute's name
3869    /// ## `value`
3870    /// a #guint64 containing the attribute's new value
3871    /// ## `flags`
3872    /// a #GFileQueryInfoFlags
3873    /// ## `cancellable`
3874    /// optional #GCancellable object,
3875    ///   [`None`] to ignore
3876    ///
3877    /// # Returns
3878    ///
3879    /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3880    #[doc(alias = "g_file_set_attribute_int64")]
3881    fn set_attribute_int64(
3882        &self,
3883        attribute: &str,
3884        value: i64,
3885        flags: FileQueryInfoFlags,
3886        cancellable: Option<&impl IsA<Cancellable>>,
3887    ) -> Result<(), glib::Error> {
3888        unsafe {
3889            let mut error = std::ptr::null_mut();
3890            let is_ok = ffi::g_file_set_attribute_int64(
3891                self.as_ref().to_glib_none().0,
3892                attribute.to_glib_none().0,
3893                value,
3894                flags.into_glib(),
3895                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3896                &mut error,
3897            );
3898            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3899            if error.is_null() {
3900                Ok(())
3901            } else {
3902                Err(from_glib_full(error))
3903            }
3904        }
3905    }
3906
3907    /// Sets @attribute of type [`FileAttributeType::String`][crate::FileAttributeType::String] to @value.
3908    /// If @attribute is of a different type, this operation will fail.
3909    ///
3910    /// If @cancellable is not [`None`], then the operation can be cancelled by
3911    /// triggering the cancellable object from another thread. If the operation
3912    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3913    /// ## `attribute`
3914    /// a string containing the attribute's name
3915    /// ## `value`
3916    /// a string containing the attribute's value
3917    /// ## `flags`
3918    /// #GFileQueryInfoFlags
3919    /// ## `cancellable`
3920    /// optional #GCancellable object,
3921    ///   [`None`] to ignore
3922    ///
3923    /// # Returns
3924    ///
3925    /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3926    #[doc(alias = "g_file_set_attribute_string")]
3927    fn set_attribute_string(
3928        &self,
3929        attribute: &str,
3930        value: &str,
3931        flags: FileQueryInfoFlags,
3932        cancellable: Option<&impl IsA<Cancellable>>,
3933    ) -> Result<(), glib::Error> {
3934        unsafe {
3935            let mut error = std::ptr::null_mut();
3936            let is_ok = ffi::g_file_set_attribute_string(
3937                self.as_ref().to_glib_none().0,
3938                attribute.to_glib_none().0,
3939                value.to_glib_none().0,
3940                flags.into_glib(),
3941                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3942                &mut error,
3943            );
3944            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3945            if error.is_null() {
3946                Ok(())
3947            } else {
3948                Err(from_glib_full(error))
3949            }
3950        }
3951    }
3952
3953    /// Sets @attribute of type [`FileAttributeType::Uint32`][crate::FileAttributeType::Uint32] to @value.
3954    /// If @attribute is of a different type, this operation will fail.
3955    ///
3956    /// If @cancellable is not [`None`], then the operation can be cancelled by
3957    /// triggering the cancellable object from another thread. If the operation
3958    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3959    /// ## `attribute`
3960    /// a string containing the attribute's name
3961    /// ## `value`
3962    /// a #guint32 containing the attribute's new value
3963    /// ## `flags`
3964    /// a #GFileQueryInfoFlags
3965    /// ## `cancellable`
3966    /// optional #GCancellable object,
3967    ///   [`None`] to ignore
3968    ///
3969    /// # Returns
3970    ///
3971    /// [`true`] if the @attribute was successfully set to @value
3972    ///   in the @self, [`false`] otherwise.
3973    #[doc(alias = "g_file_set_attribute_uint32")]
3974    fn set_attribute_uint32(
3975        &self,
3976        attribute: &str,
3977        value: u32,
3978        flags: FileQueryInfoFlags,
3979        cancellable: Option<&impl IsA<Cancellable>>,
3980    ) -> Result<(), glib::Error> {
3981        unsafe {
3982            let mut error = std::ptr::null_mut();
3983            let is_ok = ffi::g_file_set_attribute_uint32(
3984                self.as_ref().to_glib_none().0,
3985                attribute.to_glib_none().0,
3986                value,
3987                flags.into_glib(),
3988                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3989                &mut error,
3990            );
3991            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3992            if error.is_null() {
3993                Ok(())
3994            } else {
3995                Err(from_glib_full(error))
3996            }
3997        }
3998    }
3999
4000    /// Sets @attribute of type [`FileAttributeType::Uint64`][crate::FileAttributeType::Uint64] to @value.
4001    /// If @attribute is of a different type, this operation will fail.
4002    ///
4003    /// If @cancellable is not [`None`], then the operation can be cancelled by
4004    /// triggering the cancellable object from another thread. If the operation
4005    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4006    /// ## `attribute`
4007    /// a string containing the attribute's name
4008    /// ## `value`
4009    /// a #guint64 containing the attribute's new value
4010    /// ## `flags`
4011    /// a #GFileQueryInfoFlags
4012    /// ## `cancellable`
4013    /// optional #GCancellable object,
4014    ///   [`None`] to ignore
4015    ///
4016    /// # Returns
4017    ///
4018    /// [`true`] if the @attribute was successfully set to @value
4019    ///   in the @self, [`false`] otherwise.
4020    #[doc(alias = "g_file_set_attribute_uint64")]
4021    fn set_attribute_uint64(
4022        &self,
4023        attribute: &str,
4024        value: u64,
4025        flags: FileQueryInfoFlags,
4026        cancellable: Option<&impl IsA<Cancellable>>,
4027    ) -> Result<(), glib::Error> {
4028        unsafe {
4029            let mut error = std::ptr::null_mut();
4030            let is_ok = ffi::g_file_set_attribute_uint64(
4031                self.as_ref().to_glib_none().0,
4032                attribute.to_glib_none().0,
4033                value,
4034                flags.into_glib(),
4035                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4036                &mut error,
4037            );
4038            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4039            if error.is_null() {
4040                Ok(())
4041            } else {
4042                Err(from_glib_full(error))
4043            }
4044        }
4045    }
4046
4047    /// Asynchronously sets the attributes of @self with @info.
4048    ///
4049    /// For more details, see g_file_set_attributes_from_info(),
4050    /// which is the synchronous version of this call.
4051    ///
4052    /// When the operation is finished, @callback will be called.
4053    /// You can then call g_file_set_attributes_finish() to get
4054    /// the result of the operation.
4055    /// ## `info`
4056    /// a #GFileInfo
4057    /// ## `flags`
4058    /// a #GFileQueryInfoFlags
4059    /// ## `io_priority`
4060    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4061    /// ## `cancellable`
4062    /// optional #GCancellable object,
4063    ///   [`None`] to ignore
4064    /// ## `callback`
4065    /// a #GAsyncReadyCallback
4066    ///   to call when the request is satisfied
4067    #[doc(alias = "g_file_set_attributes_async")]
4068    fn set_attributes_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
4069        &self,
4070        info: &FileInfo,
4071        flags: FileQueryInfoFlags,
4072        io_priority: glib::Priority,
4073        cancellable: Option<&impl IsA<Cancellable>>,
4074        callback: P,
4075    ) {
4076        let main_context = glib::MainContext::ref_thread_default();
4077        let is_main_context_owner = main_context.is_owner();
4078        let has_acquired_main_context = (!is_main_context_owner)
4079            .then(|| main_context.acquire().ok())
4080            .flatten();
4081        assert!(
4082            is_main_context_owner || has_acquired_main_context.is_some(),
4083            "Async operations only allowed if the thread is owning the MainContext"
4084        );
4085
4086        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4087            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4088        unsafe extern "C" fn set_attributes_async_trampoline<
4089            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
4090        >(
4091            _source_object: *mut glib::gobject_ffi::GObject,
4092            res: *mut crate::ffi::GAsyncResult,
4093            user_data: glib::ffi::gpointer,
4094        ) {
4095            unsafe {
4096                let mut error = std::ptr::null_mut();
4097                let mut info = std::ptr::null_mut();
4098                ffi::g_file_set_attributes_finish(
4099                    _source_object as *mut _,
4100                    res,
4101                    &mut info,
4102                    &mut error,
4103                );
4104                let result = if error.is_null() {
4105                    Ok(from_glib_full(info))
4106                } else {
4107                    Err(from_glib_full(error))
4108                };
4109                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4110                    Box_::from_raw(user_data as *mut _);
4111                let callback: P = callback.into_inner();
4112                callback(result);
4113            }
4114        }
4115        let callback = set_attributes_async_trampoline::<P>;
4116        unsafe {
4117            ffi::g_file_set_attributes_async(
4118                self.as_ref().to_glib_none().0,
4119                info.to_glib_none().0,
4120                flags.into_glib(),
4121                io_priority.into_glib(),
4122                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4123                Some(callback),
4124                Box_::into_raw(user_data) as *mut _,
4125            );
4126        }
4127    }
4128
4129    fn set_attributes_future(
4130        &self,
4131        info: &FileInfo,
4132        flags: FileQueryInfoFlags,
4133        io_priority: glib::Priority,
4134    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
4135        let info = info.clone();
4136        Box_::pin(crate::GioFuture::new(
4137            self,
4138            move |obj, cancellable, send| {
4139                obj.set_attributes_async(
4140                    &info,
4141                    flags,
4142                    io_priority,
4143                    Some(cancellable),
4144                    move |res| {
4145                        send.resolve(res);
4146                    },
4147                );
4148            },
4149        ))
4150    }
4151
4152    /// Tries to set all attributes in the #GFileInfo on the target
4153    /// values, not stopping on the first error.
4154    ///
4155    /// If there is any error during this operation then @error will
4156    /// be set to the first error. Error on particular fields are flagged
4157    /// by setting the "status" field in the attribute value to
4158    /// [`FileAttributeStatus::ErrorSetting`][crate::FileAttributeStatus::ErrorSetting], which means you can
4159    /// also detect further errors.
4160    ///
4161    /// If @cancellable is not [`None`], then the operation can be cancelled by
4162    /// triggering the cancellable object from another thread. If the operation
4163    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4164    /// ## `info`
4165    /// a #GFileInfo
4166    /// ## `flags`
4167    /// #GFileQueryInfoFlags
4168    /// ## `cancellable`
4169    /// optional #GCancellable object,
4170    ///   [`None`] to ignore
4171    ///
4172    /// # Returns
4173    ///
4174    /// [`false`] if there was any error, [`true`] otherwise.
4175    #[doc(alias = "g_file_set_attributes_from_info")]
4176    fn set_attributes_from_info(
4177        &self,
4178        info: &FileInfo,
4179        flags: FileQueryInfoFlags,
4180        cancellable: Option<&impl IsA<Cancellable>>,
4181    ) -> Result<(), glib::Error> {
4182        unsafe {
4183            let mut error = std::ptr::null_mut();
4184            let is_ok = ffi::g_file_set_attributes_from_info(
4185                self.as_ref().to_glib_none().0,
4186                info.to_glib_none().0,
4187                flags.into_glib(),
4188                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4189                &mut error,
4190            );
4191            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4192            if error.is_null() {
4193                Ok(())
4194            } else {
4195                Err(from_glib_full(error))
4196            }
4197        }
4198    }
4199
4200    /// Renames @self to the specified display name.
4201    ///
4202    /// The display name is converted from UTF-8 to the correct encoding
4203    /// for the target filesystem if possible and the @self is renamed to this.
4204    ///
4205    /// If you want to implement a rename operation in the user interface the
4206    /// edit name ([`FILE_ATTRIBUTE_STANDARD_EDIT_NAME`][crate::FILE_ATTRIBUTE_STANDARD_EDIT_NAME]) should be used as the
4207    /// initial value in the rename widget, and then the result after editing
4208    /// should be passed to g_file_set_display_name().
4209    ///
4210    /// On success the resulting converted filename is returned.
4211    ///
4212    /// If @cancellable is not [`None`], then the operation can be cancelled by
4213    /// triggering the cancellable object from another thread. If the operation
4214    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4215    /// ## `display_name`
4216    /// a string
4217    /// ## `cancellable`
4218    /// optional #GCancellable object,
4219    ///   [`None`] to ignore
4220    ///
4221    /// # Returns
4222    ///
4223    /// a #GFile specifying what @self was renamed to,
4224    ///   or [`None`] if there was an error.
4225    ///   Free the returned object with g_object_unref().
4226    #[doc(alias = "g_file_set_display_name")]
4227    fn set_display_name(
4228        &self,
4229        display_name: &str,
4230        cancellable: Option<&impl IsA<Cancellable>>,
4231    ) -> Result<File, glib::Error> {
4232        unsafe {
4233            let mut error = std::ptr::null_mut();
4234            let ret = ffi::g_file_set_display_name(
4235                self.as_ref().to_glib_none().0,
4236                display_name.to_glib_none().0,
4237                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4238                &mut error,
4239            );
4240            if error.is_null() {
4241                Ok(from_glib_full(ret))
4242            } else {
4243                Err(from_glib_full(error))
4244            }
4245        }
4246    }
4247
4248    /// Asynchronously sets the display name for a given #GFile.
4249    ///
4250    /// For more details, see g_file_set_display_name() which is
4251    /// the synchronous version of this call.
4252    ///
4253    /// When the operation is finished, @callback will be called.
4254    /// You can then call g_file_set_display_name_finish() to get
4255    /// the result of the operation.
4256    /// ## `display_name`
4257    /// a string
4258    /// ## `io_priority`
4259    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4260    /// ## `cancellable`
4261    /// optional #GCancellable object,
4262    ///   [`None`] to ignore
4263    /// ## `callback`
4264    /// a #GAsyncReadyCallback
4265    ///   to call when the request is satisfied
4266    #[doc(alias = "g_file_set_display_name_async")]
4267    fn set_display_name_async<P: FnOnce(Result<File, glib::Error>) + 'static>(
4268        &self,
4269        display_name: &str,
4270        io_priority: glib::Priority,
4271        cancellable: Option<&impl IsA<Cancellable>>,
4272        callback: P,
4273    ) {
4274        let main_context = glib::MainContext::ref_thread_default();
4275        let is_main_context_owner = main_context.is_owner();
4276        let has_acquired_main_context = (!is_main_context_owner)
4277            .then(|| main_context.acquire().ok())
4278            .flatten();
4279        assert!(
4280            is_main_context_owner || has_acquired_main_context.is_some(),
4281            "Async operations only allowed if the thread is owning the MainContext"
4282        );
4283
4284        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4285            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4286        unsafe extern "C" fn set_display_name_async_trampoline<
4287            P: FnOnce(Result<File, glib::Error>) + 'static,
4288        >(
4289            _source_object: *mut glib::gobject_ffi::GObject,
4290            res: *mut crate::ffi::GAsyncResult,
4291            user_data: glib::ffi::gpointer,
4292        ) {
4293            unsafe {
4294                let mut error = std::ptr::null_mut();
4295                let ret =
4296                    ffi::g_file_set_display_name_finish(_source_object as *mut _, res, &mut error);
4297                let result = if error.is_null() {
4298                    Ok(from_glib_full(ret))
4299                } else {
4300                    Err(from_glib_full(error))
4301                };
4302                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4303                    Box_::from_raw(user_data as *mut _);
4304                let callback: P = callback.into_inner();
4305                callback(result);
4306            }
4307        }
4308        let callback = set_display_name_async_trampoline::<P>;
4309        unsafe {
4310            ffi::g_file_set_display_name_async(
4311                self.as_ref().to_glib_none().0,
4312                display_name.to_glib_none().0,
4313                io_priority.into_glib(),
4314                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4315                Some(callback),
4316                Box_::into_raw(user_data) as *mut _,
4317            );
4318        }
4319    }
4320
4321    fn set_display_name_future(
4322        &self,
4323        display_name: &str,
4324        io_priority: glib::Priority,
4325    ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
4326        let display_name = String::from(display_name);
4327        Box_::pin(crate::GioFuture::new(
4328            self,
4329            move |obj, cancellable, send| {
4330                obj.set_display_name_async(
4331                    &display_name,
4332                    io_priority,
4333                    Some(cancellable),
4334                    move |res| {
4335                        send.resolve(res);
4336                    },
4337                );
4338            },
4339        ))
4340    }
4341
4342    /// Starts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4343    /// Using @start_operation, you can request callbacks when, for instance,
4344    /// passwords are needed during authentication.
4345    ///
4346    /// If @cancellable is not [`None`], then the operation can be cancelled by
4347    /// triggering the cancellable object from another thread. If the operation
4348    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4349    ///
4350    /// When the operation is finished, @callback will be called.
4351    /// You can then call g_file_mount_mountable_finish() to get
4352    /// the result of the operation.
4353    /// ## `flags`
4354    /// flags affecting the operation
4355    /// ## `start_operation`
4356    /// a #GMountOperation, or [`None`] to avoid user interaction
4357    /// ## `cancellable`
4358    /// optional #GCancellable object, [`None`] to ignore
4359    /// ## `callback`
4360    /// a #GAsyncReadyCallback to call when the request is satisfied, or [`None`]
4361    #[doc(alias = "g_file_start_mountable")]
4362    fn start_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4363        &self,
4364        flags: DriveStartFlags,
4365        start_operation: Option<&impl IsA<MountOperation>>,
4366        cancellable: Option<&impl IsA<Cancellable>>,
4367        callback: P,
4368    ) {
4369        let main_context = glib::MainContext::ref_thread_default();
4370        let is_main_context_owner = main_context.is_owner();
4371        let has_acquired_main_context = (!is_main_context_owner)
4372            .then(|| main_context.acquire().ok())
4373            .flatten();
4374        assert!(
4375            is_main_context_owner || has_acquired_main_context.is_some(),
4376            "Async operations only allowed if the thread is owning the MainContext"
4377        );
4378
4379        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4380            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4381        unsafe extern "C" fn start_mountable_trampoline<
4382            P: FnOnce(Result<(), glib::Error>) + 'static,
4383        >(
4384            _source_object: *mut glib::gobject_ffi::GObject,
4385            res: *mut crate::ffi::GAsyncResult,
4386            user_data: glib::ffi::gpointer,
4387        ) {
4388            unsafe {
4389                let mut error = std::ptr::null_mut();
4390                ffi::g_file_start_mountable_finish(_source_object as *mut _, res, &mut error);
4391                let result = if error.is_null() {
4392                    Ok(())
4393                } else {
4394                    Err(from_glib_full(error))
4395                };
4396                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4397                    Box_::from_raw(user_data as *mut _);
4398                let callback: P = callback.into_inner();
4399                callback(result);
4400            }
4401        }
4402        let callback = start_mountable_trampoline::<P>;
4403        unsafe {
4404            ffi::g_file_start_mountable(
4405                self.as_ref().to_glib_none().0,
4406                flags.into_glib(),
4407                start_operation.map(|p| p.as_ref()).to_glib_none().0,
4408                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4409                Some(callback),
4410                Box_::into_raw(user_data) as *mut _,
4411            );
4412        }
4413    }
4414
4415    fn start_mountable_future(
4416        &self,
4417        flags: DriveStartFlags,
4418        start_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4419    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4420        let start_operation = start_operation.map(ToOwned::to_owned);
4421        Box_::pin(crate::GioFuture::new(
4422            self,
4423            move |obj, cancellable, send| {
4424                obj.start_mountable(
4425                    flags,
4426                    start_operation.as_ref().map(::std::borrow::Borrow::borrow),
4427                    Some(cancellable),
4428                    move |res| {
4429                        send.resolve(res);
4430                    },
4431                );
4432            },
4433        ))
4434    }
4435
4436    /// Stops a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4437    ///
4438    /// If @cancellable is not [`None`], then the operation can be cancelled by
4439    /// triggering the cancellable object from another thread. If the operation
4440    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4441    ///
4442    /// When the operation is finished, @callback will be called.
4443    /// You can then call g_file_stop_mountable_finish() to get
4444    /// the result of the operation.
4445    /// ## `flags`
4446    /// flags affecting the operation
4447    /// ## `mount_operation`
4448    /// a #GMountOperation,
4449    ///   or [`None`] to avoid user interaction.
4450    /// ## `cancellable`
4451    /// optional #GCancellable object,
4452    ///   [`None`] to ignore
4453    /// ## `callback`
4454    /// a #GAsyncReadyCallback to call
4455    ///   when the request is satisfied, or [`None`]
4456    #[doc(alias = "g_file_stop_mountable")]
4457    fn stop_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4458        &self,
4459        flags: MountUnmountFlags,
4460        mount_operation: Option<&impl IsA<MountOperation>>,
4461        cancellable: Option<&impl IsA<Cancellable>>,
4462        callback: P,
4463    ) {
4464        let main_context = glib::MainContext::ref_thread_default();
4465        let is_main_context_owner = main_context.is_owner();
4466        let has_acquired_main_context = (!is_main_context_owner)
4467            .then(|| main_context.acquire().ok())
4468            .flatten();
4469        assert!(
4470            is_main_context_owner || has_acquired_main_context.is_some(),
4471            "Async operations only allowed if the thread is owning the MainContext"
4472        );
4473
4474        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4475            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4476        unsafe extern "C" fn stop_mountable_trampoline<
4477            P: FnOnce(Result<(), glib::Error>) + 'static,
4478        >(
4479            _source_object: *mut glib::gobject_ffi::GObject,
4480            res: *mut crate::ffi::GAsyncResult,
4481            user_data: glib::ffi::gpointer,
4482        ) {
4483            unsafe {
4484                let mut error = std::ptr::null_mut();
4485                ffi::g_file_stop_mountable_finish(_source_object as *mut _, res, &mut error);
4486                let result = if error.is_null() {
4487                    Ok(())
4488                } else {
4489                    Err(from_glib_full(error))
4490                };
4491                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4492                    Box_::from_raw(user_data as *mut _);
4493                let callback: P = callback.into_inner();
4494                callback(result);
4495            }
4496        }
4497        let callback = stop_mountable_trampoline::<P>;
4498        unsafe {
4499            ffi::g_file_stop_mountable(
4500                self.as_ref().to_glib_none().0,
4501                flags.into_glib(),
4502                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4503                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4504                Some(callback),
4505                Box_::into_raw(user_data) as *mut _,
4506            );
4507        }
4508    }
4509
4510    fn stop_mountable_future(
4511        &self,
4512        flags: MountUnmountFlags,
4513        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4514    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4515        let mount_operation = mount_operation.map(ToOwned::to_owned);
4516        Box_::pin(crate::GioFuture::new(
4517            self,
4518            move |obj, cancellable, send| {
4519                obj.stop_mountable(
4520                    flags,
4521                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4522                    Some(cancellable),
4523                    move |res| {
4524                        send.resolve(res);
4525                    },
4526                );
4527            },
4528        ))
4529    }
4530
4531    /// Checks if @self supports thread-default main contexts
4532    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
4533    /// If this returns [`false`], you cannot perform asynchronous operations on
4534    /// @self in a thread that has a thread-default context.
4535    ///
4536    /// # Returns
4537    ///
4538    /// Whether or not @self supports thread-default contexts.
4539    #[doc(alias = "g_file_supports_thread_contexts")]
4540    fn supports_thread_contexts(&self) -> bool {
4541        unsafe {
4542            from_glib(ffi::g_file_supports_thread_contexts(
4543                self.as_ref().to_glib_none().0,
4544            ))
4545        }
4546    }
4547
4548    /// Sends @self to the "Trashcan", if possible. This is similar to
4549    /// deleting it, but the user can recover it before emptying the trashcan.
4550    /// Trashing is disabled for system mounts by default (see
4551    /// g_unix_mount_entry_is_system_internal()), so this call can return the
4552    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error. Since GLib 2.66, the `x-gvfs-notrash` unix
4553    /// mount option can be used to disable g_file_trash() support for particular
4554    /// mounts, the [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error will be returned in that case.
4555    /// Since 2.82, the `x-gvfs-trash` unix mount option can be used to enable
4556    /// g_file_trash() support for particular system mounts.
4557    ///
4558    /// If @cancellable is not [`None`], then the operation can be cancelled by
4559    /// triggering the cancellable object from another thread. If the operation
4560    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4561    /// ## `cancellable`
4562    /// optional #GCancellable object,
4563    ///   [`None`] to ignore
4564    ///
4565    /// # Returns
4566    ///
4567    /// [`true`] on successful trash, [`false`] otherwise.
4568    #[doc(alias = "g_file_trash")]
4569    fn trash(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
4570        unsafe {
4571            let mut error = std::ptr::null_mut();
4572            let is_ok = ffi::g_file_trash(
4573                self.as_ref().to_glib_none().0,
4574                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4575                &mut error,
4576            );
4577            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4578            if error.is_null() {
4579                Ok(())
4580            } else {
4581                Err(from_glib_full(error))
4582            }
4583        }
4584    }
4585
4586    /// Asynchronously sends @self to the Trash location, if possible.
4587    /// ## `io_priority`
4588    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4589    /// ## `cancellable`
4590    /// optional #GCancellable object,
4591    ///   [`None`] to ignore
4592    /// ## `callback`
4593    /// a #GAsyncReadyCallback to call
4594    ///   when the request is satisfied
4595    #[doc(alias = "g_file_trash_async")]
4596    fn trash_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
4597        &self,
4598        io_priority: glib::Priority,
4599        cancellable: Option<&impl IsA<Cancellable>>,
4600        callback: P,
4601    ) {
4602        let main_context = glib::MainContext::ref_thread_default();
4603        let is_main_context_owner = main_context.is_owner();
4604        let has_acquired_main_context = (!is_main_context_owner)
4605            .then(|| main_context.acquire().ok())
4606            .flatten();
4607        assert!(
4608            is_main_context_owner || has_acquired_main_context.is_some(),
4609            "Async operations only allowed if the thread is owning the MainContext"
4610        );
4611
4612        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4613            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4614        unsafe extern "C" fn trash_async_trampoline<
4615            P: FnOnce(Result<(), glib::Error>) + 'static,
4616        >(
4617            _source_object: *mut glib::gobject_ffi::GObject,
4618            res: *mut crate::ffi::GAsyncResult,
4619            user_data: glib::ffi::gpointer,
4620        ) {
4621            unsafe {
4622                let mut error = std::ptr::null_mut();
4623                ffi::g_file_trash_finish(_source_object as *mut _, res, &mut error);
4624                let result = if error.is_null() {
4625                    Ok(())
4626                } else {
4627                    Err(from_glib_full(error))
4628                };
4629                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4630                    Box_::from_raw(user_data as *mut _);
4631                let callback: P = callback.into_inner();
4632                callback(result);
4633            }
4634        }
4635        let callback = trash_async_trampoline::<P>;
4636        unsafe {
4637            ffi::g_file_trash_async(
4638                self.as_ref().to_glib_none().0,
4639                io_priority.into_glib(),
4640                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4641                Some(callback),
4642                Box_::into_raw(user_data) as *mut _,
4643            );
4644        }
4645    }
4646
4647    fn trash_future(
4648        &self,
4649        io_priority: glib::Priority,
4650    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4651        Box_::pin(crate::GioFuture::new(
4652            self,
4653            move |obj, cancellable, send| {
4654                obj.trash_async(io_priority, Some(cancellable), move |res| {
4655                    send.resolve(res);
4656                });
4657            },
4658        ))
4659    }
4660
4661    /// Unmounts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4662    ///
4663    /// If @cancellable is not [`None`], then the operation can be cancelled by
4664    /// triggering the cancellable object from another thread. If the operation
4665    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4666    ///
4667    /// When the operation is finished, @callback will be called.
4668    /// You can then call g_file_unmount_mountable_finish() to get
4669    /// the result of the operation.
4670    /// ## `flags`
4671    /// flags affecting the operation
4672    /// ## `mount_operation`
4673    /// a #GMountOperation,
4674    ///   or [`None`] to avoid user interaction
4675    /// ## `cancellable`
4676    /// optional #GCancellable object,
4677    ///   [`None`] to ignore
4678    /// ## `callback`
4679    /// a #GAsyncReadyCallback
4680    ///   to call when the request is satisfied
4681    #[doc(alias = "g_file_unmount_mountable_with_operation")]
4682    fn unmount_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
4683        &self,
4684        flags: MountUnmountFlags,
4685        mount_operation: Option<&impl IsA<MountOperation>>,
4686        cancellable: Option<&impl IsA<Cancellable>>,
4687        callback: P,
4688    ) {
4689        let main_context = glib::MainContext::ref_thread_default();
4690        let is_main_context_owner = main_context.is_owner();
4691        let has_acquired_main_context = (!is_main_context_owner)
4692            .then(|| main_context.acquire().ok())
4693            .flatten();
4694        assert!(
4695            is_main_context_owner || has_acquired_main_context.is_some(),
4696            "Async operations only allowed if the thread is owning the MainContext"
4697        );
4698
4699        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4700            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4701        unsafe extern "C" fn unmount_mountable_with_operation_trampoline<
4702            P: FnOnce(Result<(), glib::Error>) + 'static,
4703        >(
4704            _source_object: *mut glib::gobject_ffi::GObject,
4705            res: *mut crate::ffi::GAsyncResult,
4706            user_data: glib::ffi::gpointer,
4707        ) {
4708            unsafe {
4709                let mut error = std::ptr::null_mut();
4710                ffi::g_file_unmount_mountable_with_operation_finish(
4711                    _source_object as *mut _,
4712                    res,
4713                    &mut error,
4714                );
4715                let result = if error.is_null() {
4716                    Ok(())
4717                } else {
4718                    Err(from_glib_full(error))
4719                };
4720                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4721                    Box_::from_raw(user_data as *mut _);
4722                let callback: P = callback.into_inner();
4723                callback(result);
4724            }
4725        }
4726        let callback = unmount_mountable_with_operation_trampoline::<P>;
4727        unsafe {
4728            ffi::g_file_unmount_mountable_with_operation(
4729                self.as_ref().to_glib_none().0,
4730                flags.into_glib(),
4731                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4732                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4733                Some(callback),
4734                Box_::into_raw(user_data) as *mut _,
4735            );
4736        }
4737    }
4738
4739    fn unmount_mountable_with_operation_future(
4740        &self,
4741        flags: MountUnmountFlags,
4742        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4743    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4744        let mount_operation = mount_operation.map(ToOwned::to_owned);
4745        Box_::pin(crate::GioFuture::new(
4746            self,
4747            move |obj, cancellable, send| {
4748                obj.unmount_mountable_with_operation(
4749                    flags,
4750                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4751                    Some(cancellable),
4752                    move |res| {
4753                        send.resolve(res);
4754                    },
4755                );
4756            },
4757        ))
4758    }
4759}
4760
4761impl<O: IsA<File>> FileExt for O {}