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