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