gio/auto/
file.rs

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