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            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            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.
1633    ///
1634    /// Note that this will only create a child directory
1635    /// of the immediate parent directory of the path or URI given by the #GFile.
1636    /// To recursively create directories, see g_file_make_directory_with_parents().
1637    ///
1638    /// This function will fail if the parent directory does not exist, setting
1639    /// @error to [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound]. If the file system doesn't support
1640    /// creating directories, this function will fail, setting @error to
1641    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported]. If the directory already exists,
1642    /// [error@Gio.IOErrorEnum.EXISTS] will be returned.
1643    ///
1644    /// For a local #GFile the newly created directory will have the default
1645    /// (current) ownership and permissions of the current process.
1646    ///
1647    /// If @cancellable is not [`None`], then the operation can be cancelled by
1648    /// triggering the cancellable object from another thread. If the operation
1649    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1650    /// ## `cancellable`
1651    /// optional #GCancellable object,
1652    ///   [`None`] to ignore
1653    ///
1654    /// # Returns
1655    ///
1656    /// [`true`] on successful creation, [`false`] otherwise.
1657    #[doc(alias = "g_file_make_directory")]
1658    fn make_directory(
1659        &self,
1660        cancellable: Option<&impl IsA<Cancellable>>,
1661    ) -> Result<(), glib::Error> {
1662        unsafe {
1663            let mut error = std::ptr::null_mut();
1664            let is_ok = ffi::g_file_make_directory(
1665                self.as_ref().to_glib_none().0,
1666                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1667                &mut error,
1668            );
1669            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1670            if error.is_null() {
1671                Ok(())
1672            } else {
1673                Err(from_glib_full(error))
1674            }
1675        }
1676    }
1677
1678    /// Asynchronously creates a directory.
1679    /// ## `io_priority`
1680    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
1681    /// ## `cancellable`
1682    /// optional #GCancellable object,
1683    ///   [`None`] to ignore
1684    /// ## `callback`
1685    /// a #GAsyncReadyCallback to call
1686    ///   when the request is satisfied
1687    #[doc(alias = "g_file_make_directory_async")]
1688    fn make_directory_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
1689        &self,
1690        io_priority: glib::Priority,
1691        cancellable: Option<&impl IsA<Cancellable>>,
1692        callback: P,
1693    ) {
1694        let main_context = glib::MainContext::ref_thread_default();
1695        let is_main_context_owner = main_context.is_owner();
1696        let has_acquired_main_context = (!is_main_context_owner)
1697            .then(|| main_context.acquire().ok())
1698            .flatten();
1699        assert!(
1700            is_main_context_owner || has_acquired_main_context.is_some(),
1701            "Async operations only allowed if the thread is owning the MainContext"
1702        );
1703
1704        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1705            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1706        unsafe extern "C" fn make_directory_async_trampoline<
1707            P: FnOnce(Result<(), glib::Error>) + 'static,
1708        >(
1709            _source_object: *mut glib::gobject_ffi::GObject,
1710            res: *mut crate::ffi::GAsyncResult,
1711            user_data: glib::ffi::gpointer,
1712        ) {
1713            let mut error = std::ptr::null_mut();
1714            ffi::g_file_make_directory_finish(_source_object as *mut _, res, &mut error);
1715            let result = if error.is_null() {
1716                Ok(())
1717            } else {
1718                Err(from_glib_full(error))
1719            };
1720            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1721                Box_::from_raw(user_data as *mut _);
1722            let callback: P = callback.into_inner();
1723            callback(result);
1724        }
1725        let callback = make_directory_async_trampoline::<P>;
1726        unsafe {
1727            ffi::g_file_make_directory_async(
1728                self.as_ref().to_glib_none().0,
1729                io_priority.into_glib(),
1730                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1731                Some(callback),
1732                Box_::into_raw(user_data) as *mut _,
1733            );
1734        }
1735    }
1736
1737    fn make_directory_future(
1738        &self,
1739        io_priority: glib::Priority,
1740    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1741        Box_::pin(crate::GioFuture::new(
1742            self,
1743            move |obj, cancellable, send| {
1744                obj.make_directory_async(io_priority, Some(cancellable), move |res| {
1745                    send.resolve(res);
1746                });
1747            },
1748        ))
1749    }
1750
1751    /// Creates a directory and any parent directories that may not
1752    /// exist similar to 'mkdir -p'. If the file system does not support
1753    /// creating directories, this function will fail, setting @error to
1754    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported]. If the directory itself already exists,
1755    /// this function will fail setting @error to [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists], unlike
1756    /// the similar g_mkdir_with_parents().
1757    ///
1758    /// For a local #GFile the newly created directories will have the default
1759    /// (current) ownership and permissions of the current process.
1760    ///
1761    /// If @cancellable is not [`None`], then the operation can be cancelled by
1762    /// triggering the cancellable object from another thread. If the operation
1763    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1764    /// ## `cancellable`
1765    /// optional #GCancellable object,
1766    ///   [`None`] to ignore
1767    ///
1768    /// # Returns
1769    ///
1770    /// [`true`] if all directories have been successfully created, [`false`]
1771    /// otherwise.
1772    #[doc(alias = "g_file_make_directory_with_parents")]
1773    fn make_directory_with_parents(
1774        &self,
1775        cancellable: Option<&impl IsA<Cancellable>>,
1776    ) -> Result<(), glib::Error> {
1777        unsafe {
1778            let mut error = std::ptr::null_mut();
1779            let is_ok = ffi::g_file_make_directory_with_parents(
1780                self.as_ref().to_glib_none().0,
1781                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1782                &mut error,
1783            );
1784            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1785            if error.is_null() {
1786                Ok(())
1787            } else {
1788                Err(from_glib_full(error))
1789            }
1790        }
1791    }
1792
1793    /// Creates a symbolic link named @self which contains the string
1794    /// @symlink_value.
1795    ///
1796    /// If @cancellable is not [`None`], then the operation can be cancelled by
1797    /// triggering the cancellable object from another thread. If the operation
1798    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1799    /// ## `symlink_value`
1800    /// a string with the path for the target
1801    ///   of the new symlink
1802    /// ## `cancellable`
1803    /// optional #GCancellable object,
1804    ///   [`None`] to ignore
1805    ///
1806    /// # Returns
1807    ///
1808    /// [`true`] on the creation of a new symlink, [`false`] otherwise.
1809    #[doc(alias = "g_file_make_symbolic_link")]
1810    fn make_symbolic_link(
1811        &self,
1812        symlink_value: impl AsRef<std::path::Path>,
1813        cancellable: Option<&impl IsA<Cancellable>>,
1814    ) -> Result<(), glib::Error> {
1815        unsafe {
1816            let mut error = std::ptr::null_mut();
1817            let is_ok = ffi::g_file_make_symbolic_link(
1818                self.as_ref().to_glib_none().0,
1819                symlink_value.as_ref().to_glib_none().0,
1820                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1821                &mut error,
1822            );
1823            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1824            if error.is_null() {
1825                Ok(())
1826            } else {
1827                Err(from_glib_full(error))
1828            }
1829        }
1830    }
1831
1832    /// Obtains a file or directory monitor for the given file,
1833    /// depending on the type of the file.
1834    ///
1835    /// If @cancellable is not [`None`], then the operation can be cancelled by
1836    /// triggering the cancellable object from another thread. If the operation
1837    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1838    /// ## `flags`
1839    /// a set of #GFileMonitorFlags
1840    /// ## `cancellable`
1841    /// optional #GCancellable object,
1842    ///   [`None`] to ignore
1843    ///
1844    /// # Returns
1845    ///
1846    /// a #GFileMonitor for the given @self,
1847    ///   or [`None`] on error.
1848    ///   Free the returned object with g_object_unref().
1849    #[doc(alias = "g_file_monitor")]
1850    fn monitor(
1851        &self,
1852        flags: FileMonitorFlags,
1853        cancellable: Option<&impl IsA<Cancellable>>,
1854    ) -> Result<FileMonitor, glib::Error> {
1855        unsafe {
1856            let mut error = std::ptr::null_mut();
1857            let ret = ffi::g_file_monitor(
1858                self.as_ref().to_glib_none().0,
1859                flags.into_glib(),
1860                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1861                &mut error,
1862            );
1863            if error.is_null() {
1864                Ok(from_glib_full(ret))
1865            } else {
1866                Err(from_glib_full(error))
1867            }
1868        }
1869    }
1870
1871    /// Obtains a directory monitor for the given file.
1872    /// This may fail if directory monitoring is not supported.
1873    ///
1874    /// If @cancellable is not [`None`], then the operation can be cancelled by
1875    /// triggering the cancellable object from another thread. If the operation
1876    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1877    ///
1878    /// It does not make sense for @flags to contain
1879    /// [`FileMonitorFlags::WATCH_HARD_LINKS`][crate::FileMonitorFlags::WATCH_HARD_LINKS], since hard links can not be made to
1880    /// directories.  It is not possible to monitor all the files in a
1881    /// directory for changes made via hard links; if you want to do this then
1882    /// you must register individual watches with g_file_monitor().
1883    /// ## `flags`
1884    /// a set of #GFileMonitorFlags
1885    /// ## `cancellable`
1886    /// optional #GCancellable object,
1887    ///   [`None`] to ignore
1888    ///
1889    /// # Returns
1890    ///
1891    /// a #GFileMonitor for the given @self,
1892    ///   or [`None`] on error. Free the returned object with g_object_unref().
1893    #[doc(alias = "g_file_monitor_directory")]
1894    fn monitor_directory(
1895        &self,
1896        flags: FileMonitorFlags,
1897        cancellable: Option<&impl IsA<Cancellable>>,
1898    ) -> Result<FileMonitor, glib::Error> {
1899        unsafe {
1900            let mut error = std::ptr::null_mut();
1901            let ret = ffi::g_file_monitor_directory(
1902                self.as_ref().to_glib_none().0,
1903                flags.into_glib(),
1904                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1905                &mut error,
1906            );
1907            if error.is_null() {
1908                Ok(from_glib_full(ret))
1909            } else {
1910                Err(from_glib_full(error))
1911            }
1912        }
1913    }
1914
1915    /// Obtains a file monitor for the given file. If no file notification
1916    /// mechanism exists, then regular polling of the file is used.
1917    ///
1918    /// If @cancellable is not [`None`], then the operation can be cancelled by
1919    /// triggering the cancellable object from another thread. If the operation
1920    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1921    ///
1922    /// If @flags contains [`FileMonitorFlags::WATCH_HARD_LINKS`][crate::FileMonitorFlags::WATCH_HARD_LINKS] then the monitor
1923    /// will also attempt to report changes made to the file via another
1924    /// filename (ie, a hard link). Without this flag, you can only rely on
1925    /// changes made through the filename contained in @self to be
1926    /// reported. Using this flag may result in an increase in resource
1927    /// usage, and may not have any effect depending on the #GFileMonitor
1928    /// backend and/or filesystem type.
1929    /// ## `flags`
1930    /// a set of #GFileMonitorFlags
1931    /// ## `cancellable`
1932    /// optional #GCancellable object,
1933    ///   [`None`] to ignore
1934    ///
1935    /// # Returns
1936    ///
1937    /// a #GFileMonitor for the given @self,
1938    ///   or [`None`] on error.
1939    ///   Free the returned object with g_object_unref().
1940    #[doc(alias = "g_file_monitor_file")]
1941    fn monitor_file(
1942        &self,
1943        flags: FileMonitorFlags,
1944        cancellable: Option<&impl IsA<Cancellable>>,
1945    ) -> Result<FileMonitor, glib::Error> {
1946        unsafe {
1947            let mut error = std::ptr::null_mut();
1948            let ret = ffi::g_file_monitor_file(
1949                self.as_ref().to_glib_none().0,
1950                flags.into_glib(),
1951                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1952                &mut error,
1953            );
1954            if error.is_null() {
1955                Ok(from_glib_full(ret))
1956            } else {
1957                Err(from_glib_full(error))
1958            }
1959        }
1960    }
1961
1962    /// Starts a @mount_operation, mounting the volume that contains
1963    /// the file @self.
1964    ///
1965    /// When this operation has completed, @callback will be called with
1966    /// @user_user data, and the operation can be finalized with
1967    /// g_file_mount_enclosing_volume_finish().
1968    ///
1969    /// If @cancellable is not [`None`], then the operation can be cancelled by
1970    /// triggering the cancellable object from another thread. If the operation
1971    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1972    /// ## `flags`
1973    /// flags affecting the operation
1974    /// ## `mount_operation`
1975    /// a #GMountOperation
1976    ///   or [`None`] to avoid user interaction
1977    /// ## `cancellable`
1978    /// optional #GCancellable object,
1979    ///   [`None`] to ignore
1980    /// ## `callback`
1981    /// a #GAsyncReadyCallback to call
1982    ///   when the request is satisfied, or [`None`]
1983    #[doc(alias = "g_file_mount_enclosing_volume")]
1984    fn mount_enclosing_volume<P: FnOnce(Result<(), glib::Error>) + 'static>(
1985        &self,
1986        flags: MountMountFlags,
1987        mount_operation: Option<&impl IsA<MountOperation>>,
1988        cancellable: Option<&impl IsA<Cancellable>>,
1989        callback: P,
1990    ) {
1991        let main_context = glib::MainContext::ref_thread_default();
1992        let is_main_context_owner = main_context.is_owner();
1993        let has_acquired_main_context = (!is_main_context_owner)
1994            .then(|| main_context.acquire().ok())
1995            .flatten();
1996        assert!(
1997            is_main_context_owner || has_acquired_main_context.is_some(),
1998            "Async operations only allowed if the thread is owning the MainContext"
1999        );
2000
2001        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2002            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2003        unsafe extern "C" fn mount_enclosing_volume_trampoline<
2004            P: FnOnce(Result<(), glib::Error>) + 'static,
2005        >(
2006            _source_object: *mut glib::gobject_ffi::GObject,
2007            res: *mut crate::ffi::GAsyncResult,
2008            user_data: glib::ffi::gpointer,
2009        ) {
2010            let mut error = std::ptr::null_mut();
2011            ffi::g_file_mount_enclosing_volume_finish(_source_object as *mut _, res, &mut error);
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            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    ///
2802    /// The result is a [`FileInfo`][crate::FileInfo] object that contains key-value
2803    /// attributes (such as the type or size of the file).
2804    ///
2805    /// The @attributes value is a string that specifies the file
2806    /// attributes that should be gathered. It is not an error if
2807    /// it’s not possible to read a particular requested attribute
2808    /// from a file — it just won't be set. In particular this means that if a file
2809    /// is inaccessible (due to being in a folder with restrictive permissions), for
2810    /// example, you can expect the returned [`FileInfo`][crate::FileInfo] to have very few
2811    /// attributes set. You should check whether an attribute is set using
2812    /// [`FileInfo::has_attribute()`][crate::FileInfo::has_attribute()] before trying to retrieve its value.
2813    ///
2814    /// It is guaranteed that if any of the following attributes are listed in
2815    /// @attributes, they will always be set in the returned [`FileInfo`][crate::FileInfo],
2816    /// even if the user doesn’t have permissions to access the file:
2817    ///
2818    ///  - `Gio::FILE_ATTRIBUTE_STANDARD_NAME`
2819    ///  - `Gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME`
2820    ///
2821    /// @attributes should be a comma-separated list of attributes or attribute
2822    /// wildcards. The wildcard `"*"` means all attributes, and a wildcard like
2823    /// `"standard::*"` means all attributes in the standard namespace.
2824    /// An example attribute query might be `"standard::*,owner::user"`.
2825    /// The standard attributes are available as defines, like
2826    /// `Gio::FILE_ATTRIBUTE_STANDARD_NAME`.
2827    ///
2828    /// If @cancellable is not `NULL`, then the operation can be cancelled
2829    /// by triggering the cancellable object from another thread. If the
2830    /// operation was cancelled, the error [error@Gio.IOErrorEnum.CANCELLED] will be
2831    /// returned.
2832    ///
2833    /// For symlinks, normally the information about the target of the
2834    /// symlink is returned, rather than information about the symlink
2835    /// itself. However if you pass [flags@Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS]
2836    /// in @flags the information about the symlink itself will be returned.
2837    /// Also, for symlinks that point to non-existing files the information
2838    /// about the symlink itself will be returned.
2839    ///
2840    /// If the file does not exist, the [error@Gio.IOErrorEnum.NOT_FOUND] error will be
2841    /// returned. Other errors are possible too, and depend on what kind of
2842    /// file system the file is on.
2843    /// ## `attributes`
2844    /// an attribute query string
2845    /// ## `flags`
2846    /// flags to affect the query operation
2847    /// ## `cancellable`
2848    /// optional cancellable object
2849    ///
2850    /// # Returns
2851    ///
2852    /// a [`FileInfo`][crate::FileInfo] for the given @self
2853    #[doc(alias = "g_file_query_info")]
2854    fn query_info(
2855        &self,
2856        attributes: &str,
2857        flags: FileQueryInfoFlags,
2858        cancellable: Option<&impl IsA<Cancellable>>,
2859    ) -> Result<FileInfo, glib::Error> {
2860        unsafe {
2861            let mut error = std::ptr::null_mut();
2862            let ret = ffi::g_file_query_info(
2863                self.as_ref().to_glib_none().0,
2864                attributes.to_glib_none().0,
2865                flags.into_glib(),
2866                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2867                &mut error,
2868            );
2869            if error.is_null() {
2870                Ok(from_glib_full(ret))
2871            } else {
2872                Err(from_glib_full(error))
2873            }
2874        }
2875    }
2876
2877    /// Asynchronously gets the requested information about specified @self.
2878    /// The result is a #GFileInfo object that contains key-value attributes
2879    /// (such as type or size for the file).
2880    ///
2881    /// For more details, see g_file_query_info() which is the synchronous
2882    /// version of this call.
2883    ///
2884    /// When the operation is finished, @callback will be called. You can
2885    /// then call g_file_query_info_finish() to get the result of the operation.
2886    /// ## `attributes`
2887    /// an attribute query string
2888    /// ## `flags`
2889    /// a set of #GFileQueryInfoFlags
2890    /// ## `io_priority`
2891    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2892    /// ## `cancellable`
2893    /// optional #GCancellable object,
2894    ///   [`None`] to ignore
2895    /// ## `callback`
2896    /// a #GAsyncReadyCallback
2897    ///   to call when the request is satisfied
2898    #[doc(alias = "g_file_query_info_async")]
2899    fn query_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
2900        &self,
2901        attributes: &str,
2902        flags: FileQueryInfoFlags,
2903        io_priority: glib::Priority,
2904        cancellable: Option<&impl IsA<Cancellable>>,
2905        callback: P,
2906    ) {
2907        let main_context = glib::MainContext::ref_thread_default();
2908        let is_main_context_owner = main_context.is_owner();
2909        let has_acquired_main_context = (!is_main_context_owner)
2910            .then(|| main_context.acquire().ok())
2911            .flatten();
2912        assert!(
2913            is_main_context_owner || has_acquired_main_context.is_some(),
2914            "Async operations only allowed if the thread is owning the MainContext"
2915        );
2916
2917        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2918            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2919        unsafe extern "C" fn query_info_async_trampoline<
2920            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
2921        >(
2922            _source_object: *mut glib::gobject_ffi::GObject,
2923            res: *mut crate::ffi::GAsyncResult,
2924            user_data: glib::ffi::gpointer,
2925        ) {
2926            let mut error = std::ptr::null_mut();
2927            let ret = ffi::g_file_query_info_finish(_source_object as *mut _, res, &mut error);
2928            let result = if error.is_null() {
2929                Ok(from_glib_full(ret))
2930            } else {
2931                Err(from_glib_full(error))
2932            };
2933            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2934                Box_::from_raw(user_data as *mut _);
2935            let callback: P = callback.into_inner();
2936            callback(result);
2937        }
2938        let callback = query_info_async_trampoline::<P>;
2939        unsafe {
2940            ffi::g_file_query_info_async(
2941                self.as_ref().to_glib_none().0,
2942                attributes.to_glib_none().0,
2943                flags.into_glib(),
2944                io_priority.into_glib(),
2945                cancellable.map(|p| p.as_ref()).to_glib_none().0,
2946                Some(callback),
2947                Box_::into_raw(user_data) as *mut _,
2948            );
2949        }
2950    }
2951
2952    fn query_info_future(
2953        &self,
2954        attributes: &str,
2955        flags: FileQueryInfoFlags,
2956        io_priority: glib::Priority,
2957    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
2958        let attributes = String::from(attributes);
2959        Box_::pin(crate::GioFuture::new(
2960            self,
2961            move |obj, cancellable, send| {
2962                obj.query_info_async(
2963                    &attributes,
2964                    flags,
2965                    io_priority,
2966                    Some(cancellable),
2967                    move |res| {
2968                        send.resolve(res);
2969                    },
2970                );
2971            },
2972        ))
2973    }
2974
2975    /// Obtain the list of settable attributes for the file.
2976    ///
2977    /// Returns the type and full attribute name of all the attributes
2978    /// that can be set on this file. This doesn't mean setting it will
2979    /// always succeed though, you might get an access failure, or some
2980    /// specific file may not support a specific attribute.
2981    ///
2982    /// If @cancellable is not [`None`], then the operation can be cancelled by
2983    /// triggering the cancellable object from another thread. If the operation
2984    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2985    /// ## `cancellable`
2986    /// optional #GCancellable object,
2987    ///   [`None`] to ignore
2988    ///
2989    /// # Returns
2990    ///
2991    /// a #GFileAttributeInfoList describing the settable attributes.
2992    ///   When you are done with it, release it with
2993    ///   g_file_attribute_info_list_unref()
2994    #[doc(alias = "g_file_query_settable_attributes")]
2995    fn query_settable_attributes(
2996        &self,
2997        cancellable: Option<&impl IsA<Cancellable>>,
2998    ) -> Result<FileAttributeInfoList, glib::Error> {
2999        unsafe {
3000            let mut error = std::ptr::null_mut();
3001            let ret = ffi::g_file_query_settable_attributes(
3002                self.as_ref().to_glib_none().0,
3003                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3004                &mut error,
3005            );
3006            if error.is_null() {
3007                Ok(from_glib_full(ret))
3008            } else {
3009                Err(from_glib_full(error))
3010            }
3011        }
3012    }
3013
3014    /// Obtain the list of attribute namespaces where new attributes
3015    /// can be created by a user. An example of this is extended
3016    /// attributes (in the "xattr" namespace).
3017    ///
3018    /// If @cancellable is not [`None`], then the operation can be cancelled by
3019    /// triggering the cancellable object from another thread. If the operation
3020    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3021    /// ## `cancellable`
3022    /// optional #GCancellable object,
3023    ///   [`None`] to ignore
3024    ///
3025    /// # Returns
3026    ///
3027    /// a #GFileAttributeInfoList describing the writable namespaces.
3028    ///   When you are done with it, release it with
3029    ///   g_file_attribute_info_list_unref()
3030    #[doc(alias = "g_file_query_writable_namespaces")]
3031    fn query_writable_namespaces(
3032        &self,
3033        cancellable: Option<&impl IsA<Cancellable>>,
3034    ) -> Result<FileAttributeInfoList, glib::Error> {
3035        unsafe {
3036            let mut error = std::ptr::null_mut();
3037            let ret = ffi::g_file_query_writable_namespaces(
3038                self.as_ref().to_glib_none().0,
3039                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3040                &mut error,
3041            );
3042            if error.is_null() {
3043                Ok(from_glib_full(ret))
3044            } else {
3045                Err(from_glib_full(error))
3046            }
3047        }
3048    }
3049
3050    /// Opens a file for reading. The result is a #GFileInputStream that
3051    /// can be used to read the contents of the file.
3052    ///
3053    /// If @cancellable is not [`None`], then the operation can be cancelled by
3054    /// triggering the cancellable object from another thread. If the operation
3055    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3056    ///
3057    /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will be
3058    /// returned. If the file is a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
3059    /// error will be returned. Other errors are possible too, and depend
3060    /// on what kind of filesystem the file is on.
3061    /// ## `cancellable`
3062    /// a #GCancellable
3063    ///
3064    /// # Returns
3065    ///
3066    /// #GFileInputStream or [`None`] on error.
3067    ///   Free the returned object with g_object_unref().
3068    #[doc(alias = "g_file_read")]
3069    fn read(
3070        &self,
3071        cancellable: Option<&impl IsA<Cancellable>>,
3072    ) -> Result<FileInputStream, glib::Error> {
3073        unsafe {
3074            let mut error = std::ptr::null_mut();
3075            let ret = ffi::g_file_read(
3076                self.as_ref().to_glib_none().0,
3077                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3078                &mut error,
3079            );
3080            if error.is_null() {
3081                Ok(from_glib_full(ret))
3082            } else {
3083                Err(from_glib_full(error))
3084            }
3085        }
3086    }
3087
3088    /// Asynchronously opens @self for reading.
3089    ///
3090    /// For more details, see g_file_read() which is
3091    /// the synchronous version of this call.
3092    ///
3093    /// When the operation is finished, @callback will be called.
3094    /// You can then call g_file_read_finish() to get the result
3095    /// of the operation.
3096    /// ## `io_priority`
3097    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3098    /// ## `cancellable`
3099    /// optional #GCancellable object,
3100    ///   [`None`] to ignore
3101    /// ## `callback`
3102    /// a #GAsyncReadyCallback
3103    ///   to call when the request is satisfied
3104    #[doc(alias = "g_file_read_async")]
3105    fn read_async<P: FnOnce(Result<FileInputStream, glib::Error>) + 'static>(
3106        &self,
3107        io_priority: glib::Priority,
3108        cancellable: Option<&impl IsA<Cancellable>>,
3109        callback: P,
3110    ) {
3111        let main_context = glib::MainContext::ref_thread_default();
3112        let is_main_context_owner = main_context.is_owner();
3113        let has_acquired_main_context = (!is_main_context_owner)
3114            .then(|| main_context.acquire().ok())
3115            .flatten();
3116        assert!(
3117            is_main_context_owner || has_acquired_main_context.is_some(),
3118            "Async operations only allowed if the thread is owning the MainContext"
3119        );
3120
3121        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3122            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3123        unsafe extern "C" fn read_async_trampoline<
3124            P: FnOnce(Result<FileInputStream, glib::Error>) + 'static,
3125        >(
3126            _source_object: *mut glib::gobject_ffi::GObject,
3127            res: *mut crate::ffi::GAsyncResult,
3128            user_data: glib::ffi::gpointer,
3129        ) {
3130            let mut error = std::ptr::null_mut();
3131            let ret = ffi::g_file_read_finish(_source_object as *mut _, res, &mut error);
3132            let result = if error.is_null() {
3133                Ok(from_glib_full(ret))
3134            } else {
3135                Err(from_glib_full(error))
3136            };
3137            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3138                Box_::from_raw(user_data as *mut _);
3139            let callback: P = callback.into_inner();
3140            callback(result);
3141        }
3142        let callback = read_async_trampoline::<P>;
3143        unsafe {
3144            ffi::g_file_read_async(
3145                self.as_ref().to_glib_none().0,
3146                io_priority.into_glib(),
3147                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3148                Some(callback),
3149                Box_::into_raw(user_data) as *mut _,
3150            );
3151        }
3152    }
3153
3154    fn read_future(
3155        &self,
3156        io_priority: glib::Priority,
3157    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInputStream, glib::Error>> + 'static>>
3158    {
3159        Box_::pin(crate::GioFuture::new(
3160            self,
3161            move |obj, cancellable, send| {
3162                obj.read_async(io_priority, Some(cancellable), move |res| {
3163                    send.resolve(res);
3164                });
3165            },
3166        ))
3167    }
3168
3169    /// Returns an output stream for overwriting the file, possibly
3170    /// creating a backup copy of the file first. If the file doesn't exist,
3171    /// it will be created.
3172    ///
3173    /// This will try to replace the file in the safest way possible so
3174    /// that any errors during the writing will not affect an already
3175    /// existing copy of the file. For instance, for local files it
3176    /// may write to a temporary file and then atomically rename over
3177    /// the destination when the stream is closed.
3178    ///
3179    /// By default files created are generally readable by everyone,
3180    /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
3181    /// will be made readable only to the current user, to the level that
3182    /// is supported on the target filesystem.
3183    ///
3184    /// If @cancellable is not [`None`], then the operation can be cancelled
3185    /// by triggering the cancellable object from another thread. If the
3186    /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
3187    /// returned.
3188    ///
3189    /// If you pass in a non-[`None`] @etag value and @self already exists, then
3190    /// this value is compared to the current entity tag of the file, and if
3191    /// they differ an [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] error is returned. This
3192    /// generally means that the file has been changed since you last read
3193    /// it. You can get the new etag from g_file_output_stream_get_etag()
3194    /// after you've finished writing and closed the #GFileOutputStream. When
3195    /// you load a new file you can use g_file_input_stream_query_info() to
3196    /// get the etag of the file.
3197    ///
3198    /// If @make_backup is [`true`], this function will attempt to make a
3199    /// backup of the current file before overwriting it. If this fails
3200    /// a [`IOErrorEnum::CantCreateBackup`][crate::IOErrorEnum::CantCreateBackup] error will be returned. If you
3201    /// want to replace anyway, try again with @make_backup set to [`false`].
3202    ///
3203    /// If the file is a directory the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory] error will
3204    /// be returned, and if the file is some other form of non-regular file
3205    /// then a [`IOErrorEnum::NotRegularFile`][crate::IOErrorEnum::NotRegularFile] error will be returned. Some
3206    /// file systems don't allow all file names, and may return an
3207    /// [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename] error, and if the name is to long
3208    /// [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong] will be returned. Other errors are
3209    /// possible too, and depend on what kind of filesystem the file is on.
3210    /// ## `etag`
3211    /// an optional [entity tag](#entity-tags)
3212    ///   for the current #GFile, or #NULL to ignore
3213    /// ## `make_backup`
3214    /// [`true`] if a backup should be created
3215    /// ## `flags`
3216    /// a set of #GFileCreateFlags
3217    /// ## `cancellable`
3218    /// optional #GCancellable object,
3219    ///   [`None`] to ignore
3220    ///
3221    /// # Returns
3222    ///
3223    /// a #GFileOutputStream or [`None`] on error.
3224    ///   Free the returned object with g_object_unref().
3225    #[doc(alias = "g_file_replace")]
3226    fn replace(
3227        &self,
3228        etag: Option<&str>,
3229        make_backup: bool,
3230        flags: FileCreateFlags,
3231        cancellable: Option<&impl IsA<Cancellable>>,
3232    ) -> Result<FileOutputStream, glib::Error> {
3233        unsafe {
3234            let mut error = std::ptr::null_mut();
3235            let ret = ffi::g_file_replace(
3236                self.as_ref().to_glib_none().0,
3237                etag.to_glib_none().0,
3238                make_backup.into_glib(),
3239                flags.into_glib(),
3240                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3241                &mut error,
3242            );
3243            if error.is_null() {
3244                Ok(from_glib_full(ret))
3245            } else {
3246                Err(from_glib_full(error))
3247            }
3248        }
3249    }
3250
3251    /// Asynchronously overwrites the file, replacing the contents,
3252    /// possibly creating a backup copy of the file first.
3253    ///
3254    /// For more details, see g_file_replace() which is
3255    /// the synchronous version of this call.
3256    ///
3257    /// When the operation is finished, @callback will be called.
3258    /// You can then call g_file_replace_finish() to get the result
3259    /// of the operation.
3260    /// ## `etag`
3261    /// an [entity tag](#entity-tags) for the current #GFile,
3262    ///   or [`None`] to ignore
3263    /// ## `make_backup`
3264    /// [`true`] if a backup should be created
3265    /// ## `flags`
3266    /// a set of #GFileCreateFlags
3267    /// ## `io_priority`
3268    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3269    /// ## `cancellable`
3270    /// optional #GCancellable object,
3271    ///   [`None`] to ignore
3272    /// ## `callback`
3273    /// a #GAsyncReadyCallback
3274    ///   to call when the request is satisfied
3275    #[doc(alias = "g_file_replace_async")]
3276    fn replace_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
3277        &self,
3278        etag: Option<&str>,
3279        make_backup: bool,
3280        flags: FileCreateFlags,
3281        io_priority: glib::Priority,
3282        cancellable: Option<&impl IsA<Cancellable>>,
3283        callback: P,
3284    ) {
3285        let main_context = glib::MainContext::ref_thread_default();
3286        let is_main_context_owner = main_context.is_owner();
3287        let has_acquired_main_context = (!is_main_context_owner)
3288            .then(|| main_context.acquire().ok())
3289            .flatten();
3290        assert!(
3291            is_main_context_owner || has_acquired_main_context.is_some(),
3292            "Async operations only allowed if the thread is owning the MainContext"
3293        );
3294
3295        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3296            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3297        unsafe extern "C" fn replace_async_trampoline<
3298            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
3299        >(
3300            _source_object: *mut glib::gobject_ffi::GObject,
3301            res: *mut crate::ffi::GAsyncResult,
3302            user_data: glib::ffi::gpointer,
3303        ) {
3304            let mut error = std::ptr::null_mut();
3305            let ret = ffi::g_file_replace_finish(_source_object as *mut _, res, &mut error);
3306            let result = if error.is_null() {
3307                Ok(from_glib_full(ret))
3308            } else {
3309                Err(from_glib_full(error))
3310            };
3311            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3312                Box_::from_raw(user_data as *mut _);
3313            let callback: P = callback.into_inner();
3314            callback(result);
3315        }
3316        let callback = replace_async_trampoline::<P>;
3317        unsafe {
3318            ffi::g_file_replace_async(
3319                self.as_ref().to_glib_none().0,
3320                etag.to_glib_none().0,
3321                make_backup.into_glib(),
3322                flags.into_glib(),
3323                io_priority.into_glib(),
3324                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3325                Some(callback),
3326                Box_::into_raw(user_data) as *mut _,
3327            );
3328        }
3329    }
3330
3331    fn replace_future(
3332        &self,
3333        etag: Option<&str>,
3334        make_backup: bool,
3335        flags: FileCreateFlags,
3336        io_priority: glib::Priority,
3337    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
3338    {
3339        let etag = etag.map(ToOwned::to_owned);
3340        Box_::pin(crate::GioFuture::new(
3341            self,
3342            move |obj, cancellable, send| {
3343                obj.replace_async(
3344                    etag.as_ref().map(::std::borrow::Borrow::borrow),
3345                    make_backup,
3346                    flags,
3347                    io_priority,
3348                    Some(cancellable),
3349                    move |res| {
3350                        send.resolve(res);
3351                    },
3352                );
3353            },
3354        ))
3355    }
3356
3357    /// Replaces the contents of @self with @contents of @length bytes.
3358    ///
3359    /// If @etag is specified (not [`None`]), any existing file must have that etag,
3360    /// or the error [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] will be returned.
3361    ///
3362    /// If @make_backup is [`true`], this function will attempt to make a backup
3363    /// of @self. Internally, it uses g_file_replace(), so will try to replace the
3364    /// file contents in the safest way possible. For example, atomic renames are
3365    /// used when replacing local files’ contents.
3366    ///
3367    /// If @cancellable is not [`None`], then the operation can be cancelled by
3368    /// triggering the cancellable object from another thread. If the operation
3369    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3370    ///
3371    /// The returned @new_etag can be used to verify that the file hasn't
3372    /// changed the next time it is saved over.
3373    /// ## `contents`
3374    /// a string containing the new contents for @self
3375    /// ## `etag`
3376    /// the old [entity-tag](#entity-tags) for the document,
3377    ///   or [`None`]
3378    /// ## `make_backup`
3379    /// [`true`] if a backup should be created
3380    /// ## `flags`
3381    /// a set of #GFileCreateFlags
3382    /// ## `cancellable`
3383    /// optional #GCancellable object, [`None`] to ignore
3384    ///
3385    /// # Returns
3386    ///
3387    /// [`true`] if successful. If an error has occurred, this function
3388    ///   will return [`false`] and set @error appropriately if present.
3389    ///
3390    /// ## `new_etag`
3391    /// a location to a new [entity tag](#entity-tags)
3392    ///   for the document. This should be freed with g_free() when no longer
3393    ///   needed, or [`None`]
3394    #[doc(alias = "g_file_replace_contents")]
3395    fn replace_contents(
3396        &self,
3397        contents: &[u8],
3398        etag: Option<&str>,
3399        make_backup: bool,
3400        flags: FileCreateFlags,
3401        cancellable: Option<&impl IsA<Cancellable>>,
3402    ) -> Result<Option<glib::GString>, glib::Error> {
3403        let length = contents.len() as _;
3404        unsafe {
3405            let mut new_etag = std::ptr::null_mut();
3406            let mut error = std::ptr::null_mut();
3407            let is_ok = ffi::g_file_replace_contents(
3408                self.as_ref().to_glib_none().0,
3409                contents.to_glib_none().0,
3410                length,
3411                etag.to_glib_none().0,
3412                make_backup.into_glib(),
3413                flags.into_glib(),
3414                &mut new_etag,
3415                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3416                &mut error,
3417            );
3418            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3419            if error.is_null() {
3420                Ok(from_glib_full(new_etag))
3421            } else {
3422                Err(from_glib_full(error))
3423            }
3424        }
3425    }
3426
3427    //#[doc(alias = "g_file_replace_contents_bytes_async")]
3428    //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) {
3429    //    unsafe { TODO: call ffi:g_file_replace_contents_bytes_async() }
3430    //}
3431
3432    /// Returns an output stream for overwriting the file in readwrite mode,
3433    /// possibly creating a backup copy of the file first. If the file doesn't
3434    /// exist, it will be created.
3435    ///
3436    /// For details about the behaviour, see g_file_replace() which does the
3437    /// same thing but returns an output stream only.
3438    ///
3439    /// Note that in many non-local file cases read and write streams are not
3440    /// supported, so make sure you really need to do read and write streaming,
3441    /// rather than just opening for reading or writing.
3442    /// ## `etag`
3443    /// an optional [entity tag](#entity-tags)
3444    ///   for the current #GFile, or #NULL to ignore
3445    /// ## `make_backup`
3446    /// [`true`] if a backup should be created
3447    /// ## `flags`
3448    /// a set of #GFileCreateFlags
3449    /// ## `cancellable`
3450    /// optional #GCancellable object,
3451    ///   [`None`] to ignore
3452    ///
3453    /// # Returns
3454    ///
3455    /// a #GFileIOStream or [`None`] on error.
3456    ///   Free the returned object with g_object_unref().
3457    #[doc(alias = "g_file_replace_readwrite")]
3458    fn replace_readwrite(
3459        &self,
3460        etag: Option<&str>,
3461        make_backup: bool,
3462        flags: FileCreateFlags,
3463        cancellable: Option<&impl IsA<Cancellable>>,
3464    ) -> Result<FileIOStream, glib::Error> {
3465        unsafe {
3466            let mut error = std::ptr::null_mut();
3467            let ret = ffi::g_file_replace_readwrite(
3468                self.as_ref().to_glib_none().0,
3469                etag.to_glib_none().0,
3470                make_backup.into_glib(),
3471                flags.into_glib(),
3472                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3473                &mut error,
3474            );
3475            if error.is_null() {
3476                Ok(from_glib_full(ret))
3477            } else {
3478                Err(from_glib_full(error))
3479            }
3480        }
3481    }
3482
3483    /// Asynchronously overwrites the file in read-write mode,
3484    /// replacing the contents, possibly creating a backup copy
3485    /// of the file first.
3486    ///
3487    /// For more details, see g_file_replace_readwrite() which is
3488    /// the synchronous version of this call.
3489    ///
3490    /// When the operation is finished, @callback will be called.
3491    /// You can then call g_file_replace_readwrite_finish() to get
3492    /// the result of the operation.
3493    /// ## `etag`
3494    /// an [entity tag](#entity-tags) for the current #GFile,
3495    ///   or [`None`] to ignore
3496    /// ## `make_backup`
3497    /// [`true`] if a backup should be created
3498    /// ## `flags`
3499    /// a set of #GFileCreateFlags
3500    /// ## `io_priority`
3501    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3502    /// ## `cancellable`
3503    /// optional #GCancellable object,
3504    ///   [`None`] to ignore
3505    /// ## `callback`
3506    /// a #GAsyncReadyCallback
3507    ///   to call when the request is satisfied
3508    #[doc(alias = "g_file_replace_readwrite_async")]
3509    fn replace_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
3510        &self,
3511        etag: Option<&str>,
3512        make_backup: bool,
3513        flags: FileCreateFlags,
3514        io_priority: glib::Priority,
3515        cancellable: Option<&impl IsA<Cancellable>>,
3516        callback: P,
3517    ) {
3518        let main_context = glib::MainContext::ref_thread_default();
3519        let is_main_context_owner = main_context.is_owner();
3520        let has_acquired_main_context = (!is_main_context_owner)
3521            .then(|| main_context.acquire().ok())
3522            .flatten();
3523        assert!(
3524            is_main_context_owner || has_acquired_main_context.is_some(),
3525            "Async operations only allowed if the thread is owning the MainContext"
3526        );
3527
3528        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3529            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3530        unsafe extern "C" fn replace_readwrite_async_trampoline<
3531            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
3532        >(
3533            _source_object: *mut glib::gobject_ffi::GObject,
3534            res: *mut crate::ffi::GAsyncResult,
3535            user_data: glib::ffi::gpointer,
3536        ) {
3537            let mut error = std::ptr::null_mut();
3538            let ret =
3539                ffi::g_file_replace_readwrite_finish(_source_object as *mut _, res, &mut error);
3540            let result = if error.is_null() {
3541                Ok(from_glib_full(ret))
3542            } else {
3543                Err(from_glib_full(error))
3544            };
3545            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3546                Box_::from_raw(user_data as *mut _);
3547            let callback: P = callback.into_inner();
3548            callback(result);
3549        }
3550        let callback = replace_readwrite_async_trampoline::<P>;
3551        unsafe {
3552            ffi::g_file_replace_readwrite_async(
3553                self.as_ref().to_glib_none().0,
3554                etag.to_glib_none().0,
3555                make_backup.into_glib(),
3556                flags.into_glib(),
3557                io_priority.into_glib(),
3558                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3559                Some(callback),
3560                Box_::into_raw(user_data) as *mut _,
3561            );
3562        }
3563    }
3564
3565    fn replace_readwrite_future(
3566        &self,
3567        etag: Option<&str>,
3568        make_backup: bool,
3569        flags: FileCreateFlags,
3570        io_priority: glib::Priority,
3571    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
3572    {
3573        let etag = etag.map(ToOwned::to_owned);
3574        Box_::pin(crate::GioFuture::new(
3575            self,
3576            move |obj, cancellable, send| {
3577                obj.replace_readwrite_async(
3578                    etag.as_ref().map(::std::borrow::Borrow::borrow),
3579                    make_backup,
3580                    flags,
3581                    io_priority,
3582                    Some(cancellable),
3583                    move |res| {
3584                        send.resolve(res);
3585                    },
3586                );
3587            },
3588        ))
3589    }
3590
3591    /// Resolves a relative path for @self to an absolute path.
3592    ///
3593    /// This call does no blocking I/O.
3594    ///
3595    /// If the @relative_path is an absolute path name, the resolution
3596    /// is done absolutely (without taking @self path as base).
3597    /// ## `relative_path`
3598    /// a given relative path string
3599    ///
3600    /// # Returns
3601    ///
3602    /// a #GFile for the resolved path.
3603    #[doc(alias = "g_file_resolve_relative_path")]
3604    #[must_use]
3605    fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
3606        unsafe {
3607            from_glib_full(ffi::g_file_resolve_relative_path(
3608                self.as_ref().to_glib_none().0,
3609                relative_path.as_ref().to_glib_none().0,
3610            ))
3611        }
3612    }
3613
3614    //#[doc(alias = "g_file_set_attribute")]
3615    //fn set_attribute(&self, attribute: &str, type_: FileAttributeType, value_p: /*Unimplemented*/Option<Basic: Pointer>, flags: FileQueryInfoFlags, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
3616    //    unsafe { TODO: call ffi:g_file_set_attribute() }
3617    //}
3618
3619    /// Sets @attribute of type [`FileAttributeType::ByteString`][crate::FileAttributeType::ByteString] to @value.
3620    /// If @attribute is of a different type, this operation will fail,
3621    /// returning [`false`].
3622    ///
3623    /// If @cancellable is not [`None`], then the operation can be cancelled by
3624    /// triggering the cancellable object from another thread. If the operation
3625    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3626    /// ## `attribute`
3627    /// a string containing the attribute's name
3628    /// ## `value`
3629    /// a string containing the attribute's new value
3630    /// ## `flags`
3631    /// a #GFileQueryInfoFlags
3632    /// ## `cancellable`
3633    /// optional #GCancellable object,
3634    ///   [`None`] to ignore
3635    ///
3636    /// # Returns
3637    ///
3638    /// [`true`] if the @attribute was successfully set to @value
3639    ///   in the @self, [`false`] otherwise.
3640    #[doc(alias = "g_file_set_attribute_byte_string")]
3641    fn set_attribute_byte_string(
3642        &self,
3643        attribute: &str,
3644        value: &str,
3645        flags: FileQueryInfoFlags,
3646        cancellable: Option<&impl IsA<Cancellable>>,
3647    ) -> Result<(), glib::Error> {
3648        unsafe {
3649            let mut error = std::ptr::null_mut();
3650            let is_ok = ffi::g_file_set_attribute_byte_string(
3651                self.as_ref().to_glib_none().0,
3652                attribute.to_glib_none().0,
3653                value.to_glib_none().0,
3654                flags.into_glib(),
3655                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3656                &mut error,
3657            );
3658            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3659            if error.is_null() {
3660                Ok(())
3661            } else {
3662                Err(from_glib_full(error))
3663            }
3664        }
3665    }
3666
3667    /// Sets @attribute of type [`FileAttributeType::Int32`][crate::FileAttributeType::Int32] to @value.
3668    /// If @attribute is of a different type, this operation will fail.
3669    ///
3670    /// If @cancellable is not [`None`], then the operation can be cancelled by
3671    /// triggering the cancellable object from another thread. If the operation
3672    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3673    /// ## `attribute`
3674    /// a string containing the attribute's name
3675    /// ## `value`
3676    /// a #gint32 containing the attribute's new value
3677    /// ## `flags`
3678    /// a #GFileQueryInfoFlags
3679    /// ## `cancellable`
3680    /// optional #GCancellable object,
3681    ///   [`None`] to ignore
3682    ///
3683    /// # Returns
3684    ///
3685    /// [`true`] if the @attribute was successfully set to @value
3686    ///   in the @self, [`false`] otherwise.
3687    #[doc(alias = "g_file_set_attribute_int32")]
3688    fn set_attribute_int32(
3689        &self,
3690        attribute: &str,
3691        value: i32,
3692        flags: FileQueryInfoFlags,
3693        cancellable: Option<&impl IsA<Cancellable>>,
3694    ) -> Result<(), glib::Error> {
3695        unsafe {
3696            let mut error = std::ptr::null_mut();
3697            let is_ok = ffi::g_file_set_attribute_int32(
3698                self.as_ref().to_glib_none().0,
3699                attribute.to_glib_none().0,
3700                value,
3701                flags.into_glib(),
3702                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3703                &mut error,
3704            );
3705            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3706            if error.is_null() {
3707                Ok(())
3708            } else {
3709                Err(from_glib_full(error))
3710            }
3711        }
3712    }
3713
3714    /// Sets @attribute of type [`FileAttributeType::Int64`][crate::FileAttributeType::Int64] to @value.
3715    /// If @attribute is of a different type, this operation will fail.
3716    ///
3717    /// If @cancellable is not [`None`], then the operation can be cancelled by
3718    /// triggering the cancellable object from another thread. If the operation
3719    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3720    /// ## `attribute`
3721    /// a string containing the attribute's name
3722    /// ## `value`
3723    /// a #guint64 containing the attribute's new value
3724    /// ## `flags`
3725    /// a #GFileQueryInfoFlags
3726    /// ## `cancellable`
3727    /// optional #GCancellable object,
3728    ///   [`None`] to ignore
3729    ///
3730    /// # Returns
3731    ///
3732    /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3733    #[doc(alias = "g_file_set_attribute_int64")]
3734    fn set_attribute_int64(
3735        &self,
3736        attribute: &str,
3737        value: i64,
3738        flags: FileQueryInfoFlags,
3739        cancellable: Option<&impl IsA<Cancellable>>,
3740    ) -> Result<(), glib::Error> {
3741        unsafe {
3742            let mut error = std::ptr::null_mut();
3743            let is_ok = ffi::g_file_set_attribute_int64(
3744                self.as_ref().to_glib_none().0,
3745                attribute.to_glib_none().0,
3746                value,
3747                flags.into_glib(),
3748                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3749                &mut error,
3750            );
3751            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3752            if error.is_null() {
3753                Ok(())
3754            } else {
3755                Err(from_glib_full(error))
3756            }
3757        }
3758    }
3759
3760    /// Sets @attribute of type [`FileAttributeType::String`][crate::FileAttributeType::String] to @value.
3761    /// If @attribute is of a different type, this operation will fail.
3762    ///
3763    /// If @cancellable is not [`None`], then the operation can be cancelled by
3764    /// triggering the cancellable object from another thread. If the operation
3765    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3766    /// ## `attribute`
3767    /// a string containing the attribute's name
3768    /// ## `value`
3769    /// a string containing the attribute's value
3770    /// ## `flags`
3771    /// #GFileQueryInfoFlags
3772    /// ## `cancellable`
3773    /// optional #GCancellable object,
3774    ///   [`None`] to ignore
3775    ///
3776    /// # Returns
3777    ///
3778    /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3779    #[doc(alias = "g_file_set_attribute_string")]
3780    fn set_attribute_string(
3781        &self,
3782        attribute: &str,
3783        value: &str,
3784        flags: FileQueryInfoFlags,
3785        cancellable: Option<&impl IsA<Cancellable>>,
3786    ) -> Result<(), glib::Error> {
3787        unsafe {
3788            let mut error = std::ptr::null_mut();
3789            let is_ok = ffi::g_file_set_attribute_string(
3790                self.as_ref().to_glib_none().0,
3791                attribute.to_glib_none().0,
3792                value.to_glib_none().0,
3793                flags.into_glib(),
3794                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3795                &mut error,
3796            );
3797            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3798            if error.is_null() {
3799                Ok(())
3800            } else {
3801                Err(from_glib_full(error))
3802            }
3803        }
3804    }
3805
3806    /// Sets @attribute of type [`FileAttributeType::Uint32`][crate::FileAttributeType::Uint32] to @value.
3807    /// If @attribute is of a different type, this operation will fail.
3808    ///
3809    /// If @cancellable is not [`None`], then the operation can be cancelled by
3810    /// triggering the cancellable object from another thread. If the operation
3811    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3812    /// ## `attribute`
3813    /// a string containing the attribute's name
3814    /// ## `value`
3815    /// a #guint32 containing the attribute's new value
3816    /// ## `flags`
3817    /// a #GFileQueryInfoFlags
3818    /// ## `cancellable`
3819    /// optional #GCancellable object,
3820    ///   [`None`] to ignore
3821    ///
3822    /// # Returns
3823    ///
3824    /// [`true`] if the @attribute was successfully set to @value
3825    ///   in the @self, [`false`] otherwise.
3826    #[doc(alias = "g_file_set_attribute_uint32")]
3827    fn set_attribute_uint32(
3828        &self,
3829        attribute: &str,
3830        value: u32,
3831        flags: FileQueryInfoFlags,
3832        cancellable: Option<&impl IsA<Cancellable>>,
3833    ) -> Result<(), glib::Error> {
3834        unsafe {
3835            let mut error = std::ptr::null_mut();
3836            let is_ok = ffi::g_file_set_attribute_uint32(
3837                self.as_ref().to_glib_none().0,
3838                attribute.to_glib_none().0,
3839                value,
3840                flags.into_glib(),
3841                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3842                &mut error,
3843            );
3844            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3845            if error.is_null() {
3846                Ok(())
3847            } else {
3848                Err(from_glib_full(error))
3849            }
3850        }
3851    }
3852
3853    /// Sets @attribute of type [`FileAttributeType::Uint64`][crate::FileAttributeType::Uint64] to @value.
3854    /// If @attribute is of a different type, this operation will fail.
3855    ///
3856    /// If @cancellable is not [`None`], then the operation can be cancelled by
3857    /// triggering the cancellable object from another thread. If the operation
3858    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3859    /// ## `attribute`
3860    /// a string containing the attribute's name
3861    /// ## `value`
3862    /// a #guint64 containing the attribute's new value
3863    /// ## `flags`
3864    /// a #GFileQueryInfoFlags
3865    /// ## `cancellable`
3866    /// optional #GCancellable object,
3867    ///   [`None`] to ignore
3868    ///
3869    /// # Returns
3870    ///
3871    /// [`true`] if the @attribute was successfully set to @value
3872    ///   in the @self, [`false`] otherwise.
3873    #[doc(alias = "g_file_set_attribute_uint64")]
3874    fn set_attribute_uint64(
3875        &self,
3876        attribute: &str,
3877        value: u64,
3878        flags: FileQueryInfoFlags,
3879        cancellable: Option<&impl IsA<Cancellable>>,
3880    ) -> Result<(), glib::Error> {
3881        unsafe {
3882            let mut error = std::ptr::null_mut();
3883            let is_ok = ffi::g_file_set_attribute_uint64(
3884                self.as_ref().to_glib_none().0,
3885                attribute.to_glib_none().0,
3886                value,
3887                flags.into_glib(),
3888                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3889                &mut error,
3890            );
3891            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3892            if error.is_null() {
3893                Ok(())
3894            } else {
3895                Err(from_glib_full(error))
3896            }
3897        }
3898    }
3899
3900    /// Asynchronously sets the attributes of @self with @info.
3901    ///
3902    /// For more details, see g_file_set_attributes_from_info(),
3903    /// which is the synchronous version of this call.
3904    ///
3905    /// When the operation is finished, @callback will be called.
3906    /// You can then call g_file_set_attributes_finish() to get
3907    /// the result of the operation.
3908    /// ## `info`
3909    /// a #GFileInfo
3910    /// ## `flags`
3911    /// a #GFileQueryInfoFlags
3912    /// ## `io_priority`
3913    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3914    /// ## `cancellable`
3915    /// optional #GCancellable object,
3916    ///   [`None`] to ignore
3917    /// ## `callback`
3918    /// a #GAsyncReadyCallback
3919    ///   to call when the request is satisfied
3920    #[doc(alias = "g_file_set_attributes_async")]
3921    fn set_attributes_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
3922        &self,
3923        info: &FileInfo,
3924        flags: FileQueryInfoFlags,
3925        io_priority: glib::Priority,
3926        cancellable: Option<&impl IsA<Cancellable>>,
3927        callback: P,
3928    ) {
3929        let main_context = glib::MainContext::ref_thread_default();
3930        let is_main_context_owner = main_context.is_owner();
3931        let has_acquired_main_context = (!is_main_context_owner)
3932            .then(|| main_context.acquire().ok())
3933            .flatten();
3934        assert!(
3935            is_main_context_owner || has_acquired_main_context.is_some(),
3936            "Async operations only allowed if the thread is owning the MainContext"
3937        );
3938
3939        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3940            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3941        unsafe extern "C" fn set_attributes_async_trampoline<
3942            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
3943        >(
3944            _source_object: *mut glib::gobject_ffi::GObject,
3945            res: *mut crate::ffi::GAsyncResult,
3946            user_data: glib::ffi::gpointer,
3947        ) {
3948            let mut error = std::ptr::null_mut();
3949            let mut info = std::ptr::null_mut();
3950            ffi::g_file_set_attributes_finish(_source_object as *mut _, res, &mut info, &mut error);
3951            let result = if error.is_null() {
3952                Ok(from_glib_full(info))
3953            } else {
3954                Err(from_glib_full(error))
3955            };
3956            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3957                Box_::from_raw(user_data as *mut _);
3958            let callback: P = callback.into_inner();
3959            callback(result);
3960        }
3961        let callback = set_attributes_async_trampoline::<P>;
3962        unsafe {
3963            ffi::g_file_set_attributes_async(
3964                self.as_ref().to_glib_none().0,
3965                info.to_glib_none().0,
3966                flags.into_glib(),
3967                io_priority.into_glib(),
3968                cancellable.map(|p| p.as_ref()).to_glib_none().0,
3969                Some(callback),
3970                Box_::into_raw(user_data) as *mut _,
3971            );
3972        }
3973    }
3974
3975    fn set_attributes_future(
3976        &self,
3977        info: &FileInfo,
3978        flags: FileQueryInfoFlags,
3979        io_priority: glib::Priority,
3980    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
3981        let info = info.clone();
3982        Box_::pin(crate::GioFuture::new(
3983            self,
3984            move |obj, cancellable, send| {
3985                obj.set_attributes_async(
3986                    &info,
3987                    flags,
3988                    io_priority,
3989                    Some(cancellable),
3990                    move |res| {
3991                        send.resolve(res);
3992                    },
3993                );
3994            },
3995        ))
3996    }
3997
3998    /// Tries to set all attributes in the #GFileInfo on the target
3999    /// values, not stopping on the first error.
4000    ///
4001    /// If there is any error during this operation then @error will
4002    /// be set to the first error. Error on particular fields are flagged
4003    /// by setting the "status" field in the attribute value to
4004    /// [`FileAttributeStatus::ErrorSetting`][crate::FileAttributeStatus::ErrorSetting], which means you can
4005    /// also detect further errors.
4006    ///
4007    /// If @cancellable is not [`None`], then the operation can be cancelled by
4008    /// triggering the cancellable object from another thread. If the operation
4009    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4010    /// ## `info`
4011    /// a #GFileInfo
4012    /// ## `flags`
4013    /// #GFileQueryInfoFlags
4014    /// ## `cancellable`
4015    /// optional #GCancellable object,
4016    ///   [`None`] to ignore
4017    ///
4018    /// # Returns
4019    ///
4020    /// [`false`] if there was any error, [`true`] otherwise.
4021    #[doc(alias = "g_file_set_attributes_from_info")]
4022    fn set_attributes_from_info(
4023        &self,
4024        info: &FileInfo,
4025        flags: FileQueryInfoFlags,
4026        cancellable: Option<&impl IsA<Cancellable>>,
4027    ) -> Result<(), glib::Error> {
4028        unsafe {
4029            let mut error = std::ptr::null_mut();
4030            let is_ok = ffi::g_file_set_attributes_from_info(
4031                self.as_ref().to_glib_none().0,
4032                info.to_glib_none().0,
4033                flags.into_glib(),
4034                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4035                &mut error,
4036            );
4037            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4038            if error.is_null() {
4039                Ok(())
4040            } else {
4041                Err(from_glib_full(error))
4042            }
4043        }
4044    }
4045
4046    /// Renames @self to the specified display name.
4047    ///
4048    /// The display name is converted from UTF-8 to the correct encoding
4049    /// for the target filesystem if possible and the @self is renamed to this.
4050    ///
4051    /// If you want to implement a rename operation in the user interface the
4052    /// edit name ([`FILE_ATTRIBUTE_STANDARD_EDIT_NAME`][crate::FILE_ATTRIBUTE_STANDARD_EDIT_NAME]) should be used as the
4053    /// initial value in the rename widget, and then the result after editing
4054    /// should be passed to g_file_set_display_name().
4055    ///
4056    /// On success the resulting converted filename is returned.
4057    ///
4058    /// If @cancellable is not [`None`], then the operation can be cancelled by
4059    /// triggering the cancellable object from another thread. If the operation
4060    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4061    /// ## `display_name`
4062    /// a string
4063    /// ## `cancellable`
4064    /// optional #GCancellable object,
4065    ///   [`None`] to ignore
4066    ///
4067    /// # Returns
4068    ///
4069    /// a #GFile specifying what @self was renamed to,
4070    ///   or [`None`] if there was an error.
4071    ///   Free the returned object with g_object_unref().
4072    #[doc(alias = "g_file_set_display_name")]
4073    fn set_display_name(
4074        &self,
4075        display_name: &str,
4076        cancellable: Option<&impl IsA<Cancellable>>,
4077    ) -> Result<File, glib::Error> {
4078        unsafe {
4079            let mut error = std::ptr::null_mut();
4080            let ret = ffi::g_file_set_display_name(
4081                self.as_ref().to_glib_none().0,
4082                display_name.to_glib_none().0,
4083                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4084                &mut error,
4085            );
4086            if error.is_null() {
4087                Ok(from_glib_full(ret))
4088            } else {
4089                Err(from_glib_full(error))
4090            }
4091        }
4092    }
4093
4094    /// Asynchronously sets the display name for a given #GFile.
4095    ///
4096    /// For more details, see g_file_set_display_name() which is
4097    /// the synchronous version of this call.
4098    ///
4099    /// When the operation is finished, @callback will be called.
4100    /// You can then call g_file_set_display_name_finish() to get
4101    /// the result of the operation.
4102    /// ## `display_name`
4103    /// a string
4104    /// ## `io_priority`
4105    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4106    /// ## `cancellable`
4107    /// optional #GCancellable object,
4108    ///   [`None`] to ignore
4109    /// ## `callback`
4110    /// a #GAsyncReadyCallback
4111    ///   to call when the request is satisfied
4112    #[doc(alias = "g_file_set_display_name_async")]
4113    fn set_display_name_async<P: FnOnce(Result<File, glib::Error>) + 'static>(
4114        &self,
4115        display_name: &str,
4116        io_priority: glib::Priority,
4117        cancellable: Option<&impl IsA<Cancellable>>,
4118        callback: P,
4119    ) {
4120        let main_context = glib::MainContext::ref_thread_default();
4121        let is_main_context_owner = main_context.is_owner();
4122        let has_acquired_main_context = (!is_main_context_owner)
4123            .then(|| main_context.acquire().ok())
4124            .flatten();
4125        assert!(
4126            is_main_context_owner || has_acquired_main_context.is_some(),
4127            "Async operations only allowed if the thread is owning the MainContext"
4128        );
4129
4130        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4131            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4132        unsafe extern "C" fn set_display_name_async_trampoline<
4133            P: FnOnce(Result<File, glib::Error>) + 'static,
4134        >(
4135            _source_object: *mut glib::gobject_ffi::GObject,
4136            res: *mut crate::ffi::GAsyncResult,
4137            user_data: glib::ffi::gpointer,
4138        ) {
4139            let mut error = std::ptr::null_mut();
4140            let ret =
4141                ffi::g_file_set_display_name_finish(_source_object as *mut _, res, &mut error);
4142            let result = if error.is_null() {
4143                Ok(from_glib_full(ret))
4144            } else {
4145                Err(from_glib_full(error))
4146            };
4147            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4148                Box_::from_raw(user_data as *mut _);
4149            let callback: P = callback.into_inner();
4150            callback(result);
4151        }
4152        let callback = set_display_name_async_trampoline::<P>;
4153        unsafe {
4154            ffi::g_file_set_display_name_async(
4155                self.as_ref().to_glib_none().0,
4156                display_name.to_glib_none().0,
4157                io_priority.into_glib(),
4158                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4159                Some(callback),
4160                Box_::into_raw(user_data) as *mut _,
4161            );
4162        }
4163    }
4164
4165    fn set_display_name_future(
4166        &self,
4167        display_name: &str,
4168        io_priority: glib::Priority,
4169    ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
4170        let display_name = String::from(display_name);
4171        Box_::pin(crate::GioFuture::new(
4172            self,
4173            move |obj, cancellable, send| {
4174                obj.set_display_name_async(
4175                    &display_name,
4176                    io_priority,
4177                    Some(cancellable),
4178                    move |res| {
4179                        send.resolve(res);
4180                    },
4181                );
4182            },
4183        ))
4184    }
4185
4186    /// Starts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4187    /// Using @start_operation, you can request callbacks when, for instance,
4188    /// passwords are needed during authentication.
4189    ///
4190    /// If @cancellable is not [`None`], then the operation can be cancelled by
4191    /// triggering the cancellable object from another thread. If the operation
4192    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4193    ///
4194    /// When the operation is finished, @callback will be called.
4195    /// You can then call g_file_mount_mountable_finish() to get
4196    /// the result of the operation.
4197    /// ## `flags`
4198    /// flags affecting the operation
4199    /// ## `start_operation`
4200    /// a #GMountOperation, or [`None`] to avoid user interaction
4201    /// ## `cancellable`
4202    /// optional #GCancellable object, [`None`] to ignore
4203    /// ## `callback`
4204    /// a #GAsyncReadyCallback to call when the request is satisfied, or [`None`]
4205    #[doc(alias = "g_file_start_mountable")]
4206    fn start_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4207        &self,
4208        flags: DriveStartFlags,
4209        start_operation: Option<&impl IsA<MountOperation>>,
4210        cancellable: Option<&impl IsA<Cancellable>>,
4211        callback: P,
4212    ) {
4213        let main_context = glib::MainContext::ref_thread_default();
4214        let is_main_context_owner = main_context.is_owner();
4215        let has_acquired_main_context = (!is_main_context_owner)
4216            .then(|| main_context.acquire().ok())
4217            .flatten();
4218        assert!(
4219            is_main_context_owner || has_acquired_main_context.is_some(),
4220            "Async operations only allowed if the thread is owning the MainContext"
4221        );
4222
4223        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4224            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4225        unsafe extern "C" fn start_mountable_trampoline<
4226            P: FnOnce(Result<(), glib::Error>) + 'static,
4227        >(
4228            _source_object: *mut glib::gobject_ffi::GObject,
4229            res: *mut crate::ffi::GAsyncResult,
4230            user_data: glib::ffi::gpointer,
4231        ) {
4232            let mut error = std::ptr::null_mut();
4233            ffi::g_file_start_mountable_finish(_source_object as *mut _, res, &mut error);
4234            let result = if error.is_null() {
4235                Ok(())
4236            } else {
4237                Err(from_glib_full(error))
4238            };
4239            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4240                Box_::from_raw(user_data as *mut _);
4241            let callback: P = callback.into_inner();
4242            callback(result);
4243        }
4244        let callback = start_mountable_trampoline::<P>;
4245        unsafe {
4246            ffi::g_file_start_mountable(
4247                self.as_ref().to_glib_none().0,
4248                flags.into_glib(),
4249                start_operation.map(|p| p.as_ref()).to_glib_none().0,
4250                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4251                Some(callback),
4252                Box_::into_raw(user_data) as *mut _,
4253            );
4254        }
4255    }
4256
4257    fn start_mountable_future(
4258        &self,
4259        flags: DriveStartFlags,
4260        start_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4261    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4262        let start_operation = start_operation.map(ToOwned::to_owned);
4263        Box_::pin(crate::GioFuture::new(
4264            self,
4265            move |obj, cancellable, send| {
4266                obj.start_mountable(
4267                    flags,
4268                    start_operation.as_ref().map(::std::borrow::Borrow::borrow),
4269                    Some(cancellable),
4270                    move |res| {
4271                        send.resolve(res);
4272                    },
4273                );
4274            },
4275        ))
4276    }
4277
4278    /// Stops a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4279    ///
4280    /// If @cancellable is not [`None`], then the operation can be cancelled by
4281    /// triggering the cancellable object from another thread. If the operation
4282    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4283    ///
4284    /// When the operation is finished, @callback will be called.
4285    /// You can then call g_file_stop_mountable_finish() to get
4286    /// the result of the operation.
4287    /// ## `flags`
4288    /// flags affecting the operation
4289    /// ## `mount_operation`
4290    /// a #GMountOperation,
4291    ///   or [`None`] to avoid user interaction.
4292    /// ## `cancellable`
4293    /// optional #GCancellable object,
4294    ///   [`None`] to ignore
4295    /// ## `callback`
4296    /// a #GAsyncReadyCallback to call
4297    ///   when the request is satisfied, or [`None`]
4298    #[doc(alias = "g_file_stop_mountable")]
4299    fn stop_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4300        &self,
4301        flags: MountUnmountFlags,
4302        mount_operation: Option<&impl IsA<MountOperation>>,
4303        cancellable: Option<&impl IsA<Cancellable>>,
4304        callback: P,
4305    ) {
4306        let main_context = glib::MainContext::ref_thread_default();
4307        let is_main_context_owner = main_context.is_owner();
4308        let has_acquired_main_context = (!is_main_context_owner)
4309            .then(|| main_context.acquire().ok())
4310            .flatten();
4311        assert!(
4312            is_main_context_owner || has_acquired_main_context.is_some(),
4313            "Async operations only allowed if the thread is owning the MainContext"
4314        );
4315
4316        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4317            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4318        unsafe extern "C" fn stop_mountable_trampoline<
4319            P: FnOnce(Result<(), glib::Error>) + 'static,
4320        >(
4321            _source_object: *mut glib::gobject_ffi::GObject,
4322            res: *mut crate::ffi::GAsyncResult,
4323            user_data: glib::ffi::gpointer,
4324        ) {
4325            let mut error = std::ptr::null_mut();
4326            ffi::g_file_stop_mountable_finish(_source_object as *mut _, res, &mut error);
4327            let result = if error.is_null() {
4328                Ok(())
4329            } else {
4330                Err(from_glib_full(error))
4331            };
4332            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4333                Box_::from_raw(user_data as *mut _);
4334            let callback: P = callback.into_inner();
4335            callback(result);
4336        }
4337        let callback = stop_mountable_trampoline::<P>;
4338        unsafe {
4339            ffi::g_file_stop_mountable(
4340                self.as_ref().to_glib_none().0,
4341                flags.into_glib(),
4342                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4343                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4344                Some(callback),
4345                Box_::into_raw(user_data) as *mut _,
4346            );
4347        }
4348    }
4349
4350    fn stop_mountable_future(
4351        &self,
4352        flags: MountUnmountFlags,
4353        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4354    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4355        let mount_operation = mount_operation.map(ToOwned::to_owned);
4356        Box_::pin(crate::GioFuture::new(
4357            self,
4358            move |obj, cancellable, send| {
4359                obj.stop_mountable(
4360                    flags,
4361                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4362                    Some(cancellable),
4363                    move |res| {
4364                        send.resolve(res);
4365                    },
4366                );
4367            },
4368        ))
4369    }
4370
4371    /// Checks if @self supports thread-default main contexts
4372    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
4373    /// If this returns [`false`], you cannot perform asynchronous operations on
4374    /// @self in a thread that has a thread-default context.
4375    ///
4376    /// # Returns
4377    ///
4378    /// Whether or not @self supports thread-default contexts.
4379    #[doc(alias = "g_file_supports_thread_contexts")]
4380    fn supports_thread_contexts(&self) -> bool {
4381        unsafe {
4382            from_glib(ffi::g_file_supports_thread_contexts(
4383                self.as_ref().to_glib_none().0,
4384            ))
4385        }
4386    }
4387
4388    /// Sends @self to the "Trashcan", if possible. This is similar to
4389    /// deleting it, but the user can recover it before emptying the trashcan.
4390    /// Trashing is disabled for system mounts by default (see
4391    /// g_unix_mount_entry_is_system_internal()), so this call can return the
4392    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error. Since GLib 2.66, the `x-gvfs-notrash` unix
4393    /// mount option can be used to disable g_file_trash() support for particular
4394    /// mounts, the [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error will be returned in that case.
4395    /// Since 2.82, the `x-gvfs-trash` unix mount option can be used to enable
4396    /// g_file_trash() support for particular system mounts.
4397    ///
4398    /// If @cancellable is not [`None`], then the operation can be cancelled by
4399    /// triggering the cancellable object from another thread. If the operation
4400    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4401    /// ## `cancellable`
4402    /// optional #GCancellable object,
4403    ///   [`None`] to ignore
4404    ///
4405    /// # Returns
4406    ///
4407    /// [`true`] on successful trash, [`false`] otherwise.
4408    #[doc(alias = "g_file_trash")]
4409    fn trash(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
4410        unsafe {
4411            let mut error = std::ptr::null_mut();
4412            let is_ok = ffi::g_file_trash(
4413                self.as_ref().to_glib_none().0,
4414                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4415                &mut error,
4416            );
4417            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4418            if error.is_null() {
4419                Ok(())
4420            } else {
4421                Err(from_glib_full(error))
4422            }
4423        }
4424    }
4425
4426    /// Asynchronously sends @self to the Trash location, if possible.
4427    /// ## `io_priority`
4428    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4429    /// ## `cancellable`
4430    /// optional #GCancellable object,
4431    ///   [`None`] to ignore
4432    /// ## `callback`
4433    /// a #GAsyncReadyCallback to call
4434    ///   when the request is satisfied
4435    #[doc(alias = "g_file_trash_async")]
4436    fn trash_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
4437        &self,
4438        io_priority: glib::Priority,
4439        cancellable: Option<&impl IsA<Cancellable>>,
4440        callback: P,
4441    ) {
4442        let main_context = glib::MainContext::ref_thread_default();
4443        let is_main_context_owner = main_context.is_owner();
4444        let has_acquired_main_context = (!is_main_context_owner)
4445            .then(|| main_context.acquire().ok())
4446            .flatten();
4447        assert!(
4448            is_main_context_owner || has_acquired_main_context.is_some(),
4449            "Async operations only allowed if the thread is owning the MainContext"
4450        );
4451
4452        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4453            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4454        unsafe extern "C" fn trash_async_trampoline<
4455            P: FnOnce(Result<(), glib::Error>) + 'static,
4456        >(
4457            _source_object: *mut glib::gobject_ffi::GObject,
4458            res: *mut crate::ffi::GAsyncResult,
4459            user_data: glib::ffi::gpointer,
4460        ) {
4461            let mut error = std::ptr::null_mut();
4462            ffi::g_file_trash_finish(_source_object as *mut _, res, &mut error);
4463            let result = if error.is_null() {
4464                Ok(())
4465            } else {
4466                Err(from_glib_full(error))
4467            };
4468            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4469                Box_::from_raw(user_data as *mut _);
4470            let callback: P = callback.into_inner();
4471            callback(result);
4472        }
4473        let callback = trash_async_trampoline::<P>;
4474        unsafe {
4475            ffi::g_file_trash_async(
4476                self.as_ref().to_glib_none().0,
4477                io_priority.into_glib(),
4478                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4479                Some(callback),
4480                Box_::into_raw(user_data) as *mut _,
4481            );
4482        }
4483    }
4484
4485    fn trash_future(
4486        &self,
4487        io_priority: glib::Priority,
4488    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4489        Box_::pin(crate::GioFuture::new(
4490            self,
4491            move |obj, cancellable, send| {
4492                obj.trash_async(io_priority, Some(cancellable), move |res| {
4493                    send.resolve(res);
4494                });
4495            },
4496        ))
4497    }
4498
4499    /// Unmounts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4500    ///
4501    /// If @cancellable is not [`None`], then the operation can be cancelled by
4502    /// triggering the cancellable object from another thread. If the operation
4503    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4504    ///
4505    /// When the operation is finished, @callback will be called.
4506    /// You can then call g_file_unmount_mountable_finish() to get
4507    /// the result of the operation.
4508    /// ## `flags`
4509    /// flags affecting the operation
4510    /// ## `mount_operation`
4511    /// a #GMountOperation,
4512    ///   or [`None`] to avoid user interaction
4513    /// ## `cancellable`
4514    /// optional #GCancellable object,
4515    ///   [`None`] to ignore
4516    /// ## `callback`
4517    /// a #GAsyncReadyCallback
4518    ///   to call when the request is satisfied
4519    #[doc(alias = "g_file_unmount_mountable_with_operation")]
4520    fn unmount_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
4521        &self,
4522        flags: MountUnmountFlags,
4523        mount_operation: Option<&impl IsA<MountOperation>>,
4524        cancellable: Option<&impl IsA<Cancellable>>,
4525        callback: P,
4526    ) {
4527        let main_context = glib::MainContext::ref_thread_default();
4528        let is_main_context_owner = main_context.is_owner();
4529        let has_acquired_main_context = (!is_main_context_owner)
4530            .then(|| main_context.acquire().ok())
4531            .flatten();
4532        assert!(
4533            is_main_context_owner || has_acquired_main_context.is_some(),
4534            "Async operations only allowed if the thread is owning the MainContext"
4535        );
4536
4537        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4538            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4539        unsafe extern "C" fn unmount_mountable_with_operation_trampoline<
4540            P: FnOnce(Result<(), glib::Error>) + 'static,
4541        >(
4542            _source_object: *mut glib::gobject_ffi::GObject,
4543            res: *mut crate::ffi::GAsyncResult,
4544            user_data: glib::ffi::gpointer,
4545        ) {
4546            let mut error = std::ptr::null_mut();
4547            ffi::g_file_unmount_mountable_with_operation_finish(
4548                _source_object as *mut _,
4549                res,
4550                &mut error,
4551            );
4552            let result = if error.is_null() {
4553                Ok(())
4554            } else {
4555                Err(from_glib_full(error))
4556            };
4557            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4558                Box_::from_raw(user_data as *mut _);
4559            let callback: P = callback.into_inner();
4560            callback(result);
4561        }
4562        let callback = unmount_mountable_with_operation_trampoline::<P>;
4563        unsafe {
4564            ffi::g_file_unmount_mountable_with_operation(
4565                self.as_ref().to_glib_none().0,
4566                flags.into_glib(),
4567                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4568                cancellable.map(|p| p.as_ref()).to_glib_none().0,
4569                Some(callback),
4570                Box_::into_raw(user_data) as *mut _,
4571            );
4572        }
4573    }
4574
4575    fn unmount_mountable_with_operation_future(
4576        &self,
4577        flags: MountUnmountFlags,
4578        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4579    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4580        let mount_operation = mount_operation.map(ToOwned::to_owned);
4581        Box_::pin(crate::GioFuture::new(
4582            self,
4583            move |obj, cancellable, send| {
4584                obj.unmount_mountable_with_operation(
4585                    flags,
4586                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4587                    Some(cancellable),
4588                    move |res| {
4589                        send.resolve(res);
4590                    },
4591                );
4592            },
4593        ))
4594    }
4595}
4596
4597impl<O: IsA<File>> FileExt for O {}