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