// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::{
    AppInfo, AsyncResult, Cancellable, DriveStartFlags, FileAttributeInfoList, FileCopyFlags,
    FileCreateFlags, FileEnumerator, FileIOStream, FileInfo, FileInputStream, FileMonitor,
    FileMonitorFlags, FileOutputStream, FileQueryInfoFlags, FileType, Mount, MountMountFlags,
    MountOperation, MountUnmountFlags,
};
use glib::{prelude::*, translate::*};
use std::{boxed::Box as Box_, fmt, mem, pin::Pin, ptr};

glib::wrapper! {
    #[doc(alias = "GFile")]
    pub struct File(Interface<ffi::GFile, ffi::GFileIface>);

    match fn {
        type_ => || ffi::g_file_get_type(),
    }
}

impl File {
    pub const NONE: Option<&'static File> = None;

    //#[doc(alias = "g_file_new_build_filename")]
    //pub fn new_build_filename(first_element: impl AsRef<std::path::Path>, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> File {
    //    unsafe { TODO: call ffi:g_file_new_build_filename() }
    //}

    #[cfg(feature = "v2_78")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
    #[doc(alias = "g_file_new_build_filenamev")]
    pub fn new_build_filenamev(args: &[&std::path::Path]) -> File {
        unsafe { from_glib_full(ffi::g_file_new_build_filenamev(args.to_glib_none().0)) }
    }

    #[doc(alias = "g_file_new_for_commandline_arg")]
    #[doc(alias = "new_for_commandline_arg")]
    pub fn for_commandline_arg(arg: impl AsRef<std::ffi::OsStr>) -> File {
        unsafe {
            from_glib_full(ffi::g_file_new_for_commandline_arg(
                arg.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_new_for_commandline_arg_and_cwd")]
    #[doc(alias = "new_for_commandline_arg_and_cwd")]
    pub fn for_commandline_arg_and_cwd(
        arg: impl AsRef<std::ffi::OsStr>,
        cwd: impl AsRef<std::path::Path>,
    ) -> File {
        unsafe {
            from_glib_full(ffi::g_file_new_for_commandline_arg_and_cwd(
                arg.as_ref().to_glib_none().0,
                cwd.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_new_for_path")]
    #[doc(alias = "new_for_path")]
    pub fn for_path(path: impl AsRef<std::path::Path>) -> File {
        unsafe { from_glib_full(ffi::g_file_new_for_path(path.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_new_for_uri")]
    #[doc(alias = "new_for_uri")]
    pub fn for_uri(uri: &str) -> File {
        unsafe { from_glib_full(ffi::g_file_new_for_uri(uri.to_glib_none().0)) }
    }

    #[doc(alias = "g_file_new_tmp")]
    pub fn new_tmp(
        tmpl: Option<impl AsRef<std::path::Path>>,
    ) -> Result<(File, FileIOStream), glib::Error> {
        unsafe {
            let mut iostream = ptr::null_mut();
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_new_tmp(
                tmpl.as_ref().map(|p| p.as_ref()).to_glib_none().0,
                &mut iostream,
                &mut error,
            );
            if error.is_null() {
                Ok((from_glib_full(ret), from_glib_full(iostream)))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_parse_name")]
    #[doc(alias = "parse_name")]
    pub fn for_parse_name(parse_name: &str) -> File {
        unsafe { from_glib_full(ffi::g_file_parse_name(parse_name.to_glib_none().0)) }
    }
}

unsafe impl Send for File {}
unsafe impl Sync for File {}

mod sealed {
    pub trait Sealed {}
    impl<T: super::IsA<super::File>> Sealed for T {}
}

pub trait FileExt: IsA<File> + sealed::Sealed + 'static {
    #[doc(alias = "g_file_append_to")]
    fn append_to(
        &self,
        flags: FileCreateFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileOutputStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_append_to(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_append_to_async")]
    fn append_to_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
        &self,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn append_to_async_trampoline<
            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_append_to_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = append_to_async_trampoline::<P>;
        unsafe {
            ffi::g_file_append_to_async(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn append_to_future(
        &self,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
    {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.append_to_async(flags, io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[cfg(feature = "v2_68")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v2_68")))]
    #[doc(alias = "g_file_build_attribute_list_for_copy")]
    fn build_attribute_list_for_copy(
        &self,
        flags: FileCopyFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<glib::GString, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_build_attribute_list_for_copy(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_copy")]
    fn copy(
        &self,
        destination: &impl IsA<File>,
        flags: FileCopyFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
        progress_callback: Option<&mut dyn (FnMut(i64, i64))>,
    ) -> Result<(), glib::Error> {
        let progress_callback_data: Option<&mut dyn (FnMut(i64, i64))> = progress_callback;
        unsafe extern "C" fn progress_callback_func(
            current_num_bytes: i64,
            total_num_bytes: i64,
            data: glib::ffi::gpointer,
        ) {
            let callback: *mut Option<&mut dyn (FnMut(i64, i64))> =
                data as *const _ as usize as *mut Option<&mut dyn (FnMut(i64, i64))>;
            if let Some(ref mut callback) = *callback {
                callback(current_num_bytes, total_num_bytes)
            } else {
                panic!("cannot get closure...")
            }
        }
        let progress_callback = if progress_callback_data.is_some() {
            Some(progress_callback_func as _)
        } else {
            None
        };
        let super_callback0: &Option<&mut dyn (FnMut(i64, i64))> = &progress_callback_data;
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_copy(
                self.as_ref().to_glib_none().0,
                destination.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                progress_callback,
                super_callback0 as *const _ as usize as *mut _,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_copy_attributes")]
    fn copy_attributes(
        &self,
        destination: &impl IsA<File>,
        flags: FileCopyFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_copy_attributes(
                self.as_ref().to_glib_none().0,
                destination.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_create")]
    fn create(
        &self,
        flags: FileCreateFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileOutputStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_create(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_create_async")]
    fn create_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
        &self,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn create_async_trampoline<
            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_create_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = create_async_trampoline::<P>;
        unsafe {
            ffi::g_file_create_async(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn create_future(
        &self,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
    {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.create_async(flags, io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_create_readwrite")]
    fn create_readwrite(
        &self,
        flags: FileCreateFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileIOStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_create_readwrite(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_create_readwrite_async")]
    fn create_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
        &self,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn create_readwrite_async_trampoline<
            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret =
                ffi::g_file_create_readwrite_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = create_readwrite_async_trampoline::<P>;
        unsafe {
            ffi::g_file_create_readwrite_async(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn create_readwrite_future(
        &self,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
    {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.create_readwrite_async(flags, io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_delete")]
    fn delete(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_delete(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_delete_async")]
    fn delete_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn delete_async_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_delete_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = delete_async_trampoline::<P>;
        unsafe {
            ffi::g_file_delete_async(
                self.as_ref().to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn delete_future(
        &self,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.delete_async(io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_dup")]
    #[must_use]
    fn dup(&self) -> File {
        unsafe { from_glib_full(ffi::g_file_dup(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_eject_mountable_with_operation")]
    fn eject_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        flags: MountUnmountFlags,
        mount_operation: Option<&impl IsA<MountOperation>>,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn eject_mountable_with_operation_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_eject_mountable_with_operation_finish(
                _source_object as *mut _,
                res,
                &mut error,
            );
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = eject_mountable_with_operation_trampoline::<P>;
        unsafe {
            ffi::g_file_eject_mountable_with_operation(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn eject_mountable_with_operation_future(
        &self,
        flags: MountUnmountFlags,
        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        let mount_operation = mount_operation.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.eject_mountable_with_operation(
                    flags,
                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_enumerate_children")]
    fn enumerate_children(
        &self,
        attributes: &str,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileEnumerator, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_enumerate_children(
                self.as_ref().to_glib_none().0,
                attributes.to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_equal")]
    fn equal(&self, file2: &impl IsA<File>) -> bool {
        unsafe {
            from_glib(ffi::g_file_equal(
                self.as_ref().to_glib_none().0,
                file2.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_find_enclosing_mount")]
    fn find_enclosing_mount(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<Mount, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_find_enclosing_mount(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_get_basename")]
    #[doc(alias = "get_basename")]
    fn basename(&self) -> Option<std::path::PathBuf> {
        unsafe { from_glib_full(ffi::g_file_get_basename(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_get_child")]
    #[doc(alias = "get_child")]
    #[must_use]
    fn child(&self, name: impl AsRef<std::path::Path>) -> File {
        unsafe {
            from_glib_full(ffi::g_file_get_child(
                self.as_ref().to_glib_none().0,
                name.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_get_child_for_display_name")]
    #[doc(alias = "get_child_for_display_name")]
    fn child_for_display_name(&self, display_name: &str) -> Result<File, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_get_child_for_display_name(
                self.as_ref().to_glib_none().0,
                display_name.to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_get_parent")]
    #[doc(alias = "get_parent")]
    #[must_use]
    fn parent(&self) -> Option<File> {
        unsafe { from_glib_full(ffi::g_file_get_parent(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_get_parse_name")]
    #[doc(alias = "get_parse_name")]
    fn parse_name(&self) -> glib::GString {
        unsafe { from_glib_full(ffi::g_file_get_parse_name(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_get_path")]
    #[doc(alias = "get_path")]
    fn path(&self) -> Option<std::path::PathBuf> {
        unsafe { from_glib_full(ffi::g_file_get_path(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_get_relative_path")]
    #[doc(alias = "get_relative_path")]
    fn relative_path(&self, descendant: &impl IsA<File>) -> Option<std::path::PathBuf> {
        unsafe {
            from_glib_full(ffi::g_file_get_relative_path(
                self.as_ref().to_glib_none().0,
                descendant.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_get_uri")]
    #[doc(alias = "get_uri")]
    fn uri(&self) -> glib::GString {
        unsafe { from_glib_full(ffi::g_file_get_uri(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_get_uri_scheme")]
    #[doc(alias = "get_uri_scheme")]
    fn uri_scheme(&self) -> Option<glib::GString> {
        unsafe { from_glib_full(ffi::g_file_get_uri_scheme(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_has_parent")]
    fn has_parent(&self, parent: Option<&impl IsA<File>>) -> bool {
        unsafe {
            from_glib(ffi::g_file_has_parent(
                self.as_ref().to_glib_none().0,
                parent.map(|p| p.as_ref()).to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_has_prefix")]
    fn has_prefix(&self, prefix: &impl IsA<File>) -> bool {
        unsafe {
            from_glib(ffi::g_file_has_prefix(
                self.as_ref().to_glib_none().0,
                prefix.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_has_uri_scheme")]
    fn has_uri_scheme(&self, uri_scheme: &str) -> bool {
        unsafe {
            from_glib(ffi::g_file_has_uri_scheme(
                self.as_ref().to_glib_none().0,
                uri_scheme.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_is_native")]
    fn is_native(&self) -> bool {
        unsafe { from_glib(ffi::g_file_is_native(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_load_bytes")]
    fn load_bytes(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(glib::Bytes, Option<glib::GString>), glib::Error> {
        unsafe {
            let mut etag_out = ptr::null_mut();
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_load_bytes(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut etag_out,
                &mut error,
            );
            if error.is_null() {
                Ok((from_glib_full(ret), from_glib_full(etag_out)))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_load_bytes_async")]
    fn load_bytes_async<
        P: FnOnce(Result<(glib::Bytes, Option<glib::GString>), glib::Error>) + 'static,
    >(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn load_bytes_async_trampoline<
            P: FnOnce(Result<(glib::Bytes, Option<glib::GString>), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let mut etag_out = ptr::null_mut();
            let ret = ffi::g_file_load_bytes_finish(
                _source_object as *mut _,
                res,
                &mut etag_out,
                &mut error,
            );
            let result = if error.is_null() {
                Ok((from_glib_full(ret), from_glib_full(etag_out)))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = load_bytes_async_trampoline::<P>;
        unsafe {
            ffi::g_file_load_bytes_async(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn load_bytes_future(
        &self,
    ) -> Pin<
        Box_<
            dyn std::future::Future<
                    Output = Result<(glib::Bytes, Option<glib::GString>), glib::Error>,
                > + 'static,
        >,
    > {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.load_bytes_async(Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_load_contents")]
    fn load_contents(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(Vec<u8>, Option<glib::GString>), glib::Error> {
        unsafe {
            let mut contents = ptr::null_mut();
            let mut length = mem::MaybeUninit::uninit();
            let mut etag_out = ptr::null_mut();
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_load_contents(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut contents,
                length.as_mut_ptr(),
                &mut etag_out,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok((
                    FromGlibContainer::from_glib_full_num(contents, length.assume_init() as _),
                    from_glib_full(etag_out),
                ))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_load_contents_async")]
    fn load_contents_async<
        P: FnOnce(Result<(Vec<u8>, Option<glib::GString>), glib::Error>) + 'static,
    >(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn load_contents_async_trampoline<
            P: FnOnce(Result<(Vec<u8>, Option<glib::GString>), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let mut contents = ptr::null_mut();
            let mut length = mem::MaybeUninit::uninit();
            let mut etag_out = ptr::null_mut();
            let _ = ffi::g_file_load_contents_finish(
                _source_object as *mut _,
                res,
                &mut contents,
                length.as_mut_ptr(),
                &mut etag_out,
                &mut error,
            );
            let result = if error.is_null() {
                Ok((
                    FromGlibContainer::from_glib_full_num(contents, length.assume_init() as _),
                    from_glib_full(etag_out),
                ))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = load_contents_async_trampoline::<P>;
        unsafe {
            ffi::g_file_load_contents_async(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn load_contents_future(
        &self,
    ) -> Pin<
        Box_<
            dyn std::future::Future<Output = Result<(Vec<u8>, Option<glib::GString>), glib::Error>>
                + 'static,
        >,
    > {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.load_contents_async(Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_make_directory")]
    fn make_directory(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_make_directory(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_make_directory_async")]
    fn make_directory_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn make_directory_async_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_make_directory_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = make_directory_async_trampoline::<P>;
        unsafe {
            ffi::g_file_make_directory_async(
                self.as_ref().to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn make_directory_future(
        &self,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.make_directory_async(io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_make_directory_with_parents")]
    fn make_directory_with_parents(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_make_directory_with_parents(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_make_symbolic_link")]
    fn make_symbolic_link(
        &self,
        symlink_value: impl AsRef<std::path::Path>,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_make_symbolic_link(
                self.as_ref().to_glib_none().0,
                symlink_value.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_monitor")]
    fn monitor(
        &self,
        flags: FileMonitorFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileMonitor, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_monitor(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_monitor_directory")]
    fn monitor_directory(
        &self,
        flags: FileMonitorFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileMonitor, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_monitor_directory(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_monitor_file")]
    fn monitor_file(
        &self,
        flags: FileMonitorFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileMonitor, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_monitor_file(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_mount_enclosing_volume")]
    fn mount_enclosing_volume<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        flags: MountMountFlags,
        mount_operation: Option<&impl IsA<MountOperation>>,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn mount_enclosing_volume_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_mount_enclosing_volume_finish(
                _source_object as *mut _,
                res,
                &mut error,
            );
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = mount_enclosing_volume_trampoline::<P>;
        unsafe {
            ffi::g_file_mount_enclosing_volume(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn mount_enclosing_volume_future(
        &self,
        flags: MountMountFlags,
        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        let mount_operation = mount_operation.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.mount_enclosing_volume(
                    flags,
                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_mount_mountable")]
    fn mount_mountable<P: FnOnce(Result<File, glib::Error>) + 'static>(
        &self,
        flags: MountMountFlags,
        mount_operation: Option<&impl IsA<MountOperation>>,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn mount_mountable_trampoline<
            P: FnOnce(Result<File, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_mount_mountable_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = mount_mountable_trampoline::<P>;
        unsafe {
            ffi::g_file_mount_mountable(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn mount_mountable_future(
        &self,
        flags: MountMountFlags,
        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
        let mount_operation = mount_operation.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.mount_mountable(
                    flags,
                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_move")]
    #[doc(alias = "move")]
    fn move_(
        &self,
        destination: &impl IsA<File>,
        flags: FileCopyFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
        progress_callback: Option<&mut dyn (FnMut(i64, i64))>,
    ) -> Result<(), glib::Error> {
        let progress_callback_data: Option<&mut dyn (FnMut(i64, i64))> = progress_callback;
        unsafe extern "C" fn progress_callback_func(
            current_num_bytes: i64,
            total_num_bytes: i64,
            data: glib::ffi::gpointer,
        ) {
            let callback: *mut Option<&mut dyn (FnMut(i64, i64))> =
                data as *const _ as usize as *mut Option<&mut dyn (FnMut(i64, i64))>;
            if let Some(ref mut callback) = *callback {
                callback(current_num_bytes, total_num_bytes)
            } else {
                panic!("cannot get closure...")
            }
        }
        let progress_callback = if progress_callback_data.is_some() {
            Some(progress_callback_func as _)
        } else {
            None
        };
        let super_callback0: &Option<&mut dyn (FnMut(i64, i64))> = &progress_callback_data;
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_move(
                self.as_ref().to_glib_none().0,
                destination.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                progress_callback,
                super_callback0 as *const _ as usize as *mut _,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_open_readwrite")]
    fn open_readwrite(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileIOStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_open_readwrite(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_open_readwrite_async")]
    fn open_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
        &self,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn open_readwrite_async_trampoline<
            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_open_readwrite_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = open_readwrite_async_trampoline::<P>;
        unsafe {
            ffi::g_file_open_readwrite_async(
                self.as_ref().to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn open_readwrite_future(
        &self,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
    {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.open_readwrite_async(io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_peek_path")]
    fn peek_path(&self) -> Option<std::path::PathBuf> {
        unsafe { from_glib_none(ffi::g_file_peek_path(self.as_ref().to_glib_none().0)) }
    }

    #[doc(alias = "g_file_poll_mountable")]
    fn poll_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn poll_mountable_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_poll_mountable_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = poll_mountable_trampoline::<P>;
        unsafe {
            ffi::g_file_poll_mountable(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn poll_mountable_future(
        &self,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.poll_mountable(Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_query_default_handler")]
    fn query_default_handler(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<AppInfo, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_query_default_handler(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[cfg(feature = "v2_60")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
    #[doc(alias = "g_file_query_default_handler_async")]
    fn query_default_handler_async<P: FnOnce(Result<AppInfo, glib::Error>) + 'static>(
        &self,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn query_default_handler_async_trampoline<
            P: FnOnce(Result<AppInfo, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret =
                ffi::g_file_query_default_handler_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = query_default_handler_async_trampoline::<P>;
        unsafe {
            ffi::g_file_query_default_handler_async(
                self.as_ref().to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    #[cfg(feature = "v2_60")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
    fn query_default_handler_future(
        &self,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<AppInfo, glib::Error>> + 'static>> {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.query_default_handler_async(io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_query_exists")]
    fn query_exists(&self, cancellable: Option<&impl IsA<Cancellable>>) -> bool {
        unsafe {
            from_glib(ffi::g_file_query_exists(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_query_file_type")]
    fn query_file_type(
        &self,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> FileType {
        unsafe {
            from_glib(ffi::g_file_query_file_type(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_query_filesystem_info")]
    fn query_filesystem_info(
        &self,
        attributes: &str,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileInfo, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_query_filesystem_info(
                self.as_ref().to_glib_none().0,
                attributes.to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_query_filesystem_info_async")]
    fn query_filesystem_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
        &self,
        attributes: &str,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn query_filesystem_info_async_trampoline<
            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret =
                ffi::g_file_query_filesystem_info_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = query_filesystem_info_async_trampoline::<P>;
        unsafe {
            ffi::g_file_query_filesystem_info_async(
                self.as_ref().to_glib_none().0,
                attributes.to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn query_filesystem_info_future(
        &self,
        attributes: &str,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
        let attributes = String::from(attributes);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.query_filesystem_info_async(
                    &attributes,
                    io_priority,
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_query_info")]
    fn query_info(
        &self,
        attributes: &str,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileInfo, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_query_info(
                self.as_ref().to_glib_none().0,
                attributes.to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_query_info_async")]
    fn query_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
        &self,
        attributes: &str,
        flags: FileQueryInfoFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn query_info_async_trampoline<
            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_query_info_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = query_info_async_trampoline::<P>;
        unsafe {
            ffi::g_file_query_info_async(
                self.as_ref().to_glib_none().0,
                attributes.to_glib_none().0,
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn query_info_future(
        &self,
        attributes: &str,
        flags: FileQueryInfoFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
        let attributes = String::from(attributes);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.query_info_async(
                    &attributes,
                    flags,
                    io_priority,
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_query_settable_attributes")]
    fn query_settable_attributes(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileAttributeInfoList, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_query_settable_attributes(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_query_writable_namespaces")]
    fn query_writable_namespaces(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileAttributeInfoList, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_query_writable_namespaces(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_read")]
    fn read(
        &self,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileInputStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_read(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_read_async")]
    fn read_async<P: FnOnce(Result<FileInputStream, glib::Error>) + 'static>(
        &self,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn read_async_trampoline<
            P: FnOnce(Result<FileInputStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_read_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = read_async_trampoline::<P>;
        unsafe {
            ffi::g_file_read_async(
                self.as_ref().to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn read_future(
        &self,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInputStream, glib::Error>> + 'static>>
    {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.read_async(io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_replace")]
    fn replace(
        &self,
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileOutputStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_replace(
                self.as_ref().to_glib_none().0,
                etag.to_glib_none().0,
                make_backup.into_glib(),
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_replace_async")]
    fn replace_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
        &self,
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn replace_async_trampoline<
            P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_replace_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = replace_async_trampoline::<P>;
        unsafe {
            ffi::g_file_replace_async(
                self.as_ref().to_glib_none().0,
                etag.to_glib_none().0,
                make_backup.into_glib(),
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn replace_future(
        &self,
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
    {
        let etag = etag.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.replace_async(
                    etag.as_ref().map(::std::borrow::Borrow::borrow),
                    make_backup,
                    flags,
                    io_priority,
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_replace_contents")]
    fn replace_contents(
        &self,
        contents: &[u8],
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<Option<glib::GString>, glib::Error> {
        let length = contents.len() as _;
        unsafe {
            let mut new_etag = ptr::null_mut();
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_replace_contents(
                self.as_ref().to_glib_none().0,
                contents.to_glib_none().0,
                length,
                etag.to_glib_none().0,
                make_backup.into_glib(),
                flags.into_glib(),
                &mut new_etag,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(from_glib_full(new_etag))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    //#[doc(alias = "g_file_replace_contents_bytes_async")]
    //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) {
    //    unsafe { TODO: call ffi:g_file_replace_contents_bytes_async() }
    //}

    #[doc(alias = "g_file_replace_readwrite")]
    fn replace_readwrite(
        &self,
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<FileIOStream, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_replace_readwrite(
                self.as_ref().to_glib_none().0,
                etag.to_glib_none().0,
                make_backup.into_glib(),
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_replace_readwrite_async")]
    fn replace_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
        &self,
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn replace_readwrite_async_trampoline<
            P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret =
                ffi::g_file_replace_readwrite_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = replace_readwrite_async_trampoline::<P>;
        unsafe {
            ffi::g_file_replace_readwrite_async(
                self.as_ref().to_glib_none().0,
                etag.to_glib_none().0,
                make_backup.into_glib(),
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn replace_readwrite_future(
        &self,
        etag: Option<&str>,
        make_backup: bool,
        flags: FileCreateFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
    {
        let etag = etag.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.replace_readwrite_async(
                    etag.as_ref().map(::std::borrow::Borrow::borrow),
                    make_backup,
                    flags,
                    io_priority,
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_resolve_relative_path")]
    #[must_use]
    fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
        unsafe {
            from_glib_full(ffi::g_file_resolve_relative_path(
                self.as_ref().to_glib_none().0,
                relative_path.as_ref().to_glib_none().0,
            ))
        }
    }

    //#[doc(alias = "g_file_set_attribute")]
    //fn set_attribute(&self, attribute: &str, type_: FileAttributeType, value_p: /*Unimplemented*/Option<Basic: Pointer>, flags: FileQueryInfoFlags, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
    //    unsafe { TODO: call ffi:g_file_set_attribute() }
    //}

    #[doc(alias = "g_file_set_attribute_byte_string")]
    fn set_attribute_byte_string(
        &self,
        attribute: &str,
        value: &str,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attribute_byte_string(
                self.as_ref().to_glib_none().0,
                attribute.to_glib_none().0,
                value.to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_attribute_int32")]
    fn set_attribute_int32(
        &self,
        attribute: &str,
        value: i32,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attribute_int32(
                self.as_ref().to_glib_none().0,
                attribute.to_glib_none().0,
                value,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_attribute_int64")]
    fn set_attribute_int64(
        &self,
        attribute: &str,
        value: i64,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attribute_int64(
                self.as_ref().to_glib_none().0,
                attribute.to_glib_none().0,
                value,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_attribute_string")]
    fn set_attribute_string(
        &self,
        attribute: &str,
        value: &str,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attribute_string(
                self.as_ref().to_glib_none().0,
                attribute.to_glib_none().0,
                value.to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_attribute_uint32")]
    fn set_attribute_uint32(
        &self,
        attribute: &str,
        value: u32,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attribute_uint32(
                self.as_ref().to_glib_none().0,
                attribute.to_glib_none().0,
                value,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_attribute_uint64")]
    fn set_attribute_uint64(
        &self,
        attribute: &str,
        value: u64,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attribute_uint64(
                self.as_ref().to_glib_none().0,
                attribute.to_glib_none().0,
                value,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_attributes_async")]
    fn set_attributes_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
        &self,
        info: &FileInfo,
        flags: FileQueryInfoFlags,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn set_attributes_async_trampoline<
            P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let mut info = ptr::null_mut();
            let _ = ffi::g_file_set_attributes_finish(
                _source_object as *mut _,
                res,
                &mut info,
                &mut error,
            );
            let result = if error.is_null() {
                Ok(from_glib_full(info))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = set_attributes_async_trampoline::<P>;
        unsafe {
            ffi::g_file_set_attributes_async(
                self.as_ref().to_glib_none().0,
                info.to_glib_none().0,
                flags.into_glib(),
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn set_attributes_future(
        &self,
        info: &FileInfo,
        flags: FileQueryInfoFlags,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
        let info = info.clone();
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.set_attributes_async(
                    &info,
                    flags,
                    io_priority,
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_set_attributes_from_info")]
    fn set_attributes_from_info(
        &self,
        info: &FileInfo,
        flags: FileQueryInfoFlags,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_set_attributes_from_info(
                self.as_ref().to_glib_none().0,
                info.to_glib_none().0,
                flags.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_display_name")]
    fn set_display_name(
        &self,
        display_name: &str,
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<File, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_file_set_display_name(
                self.as_ref().to_glib_none().0,
                display_name.to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_set_display_name_async")]
    fn set_display_name_async<P: FnOnce(Result<File, glib::Error>) + 'static>(
        &self,
        display_name: &str,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn set_display_name_async_trampoline<
            P: FnOnce(Result<File, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let ret =
                ffi::g_file_set_display_name_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = set_display_name_async_trampoline::<P>;
        unsafe {
            ffi::g_file_set_display_name_async(
                self.as_ref().to_glib_none().0,
                display_name.to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn set_display_name_future(
        &self,
        display_name: &str,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
        let display_name = String::from(display_name);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.set_display_name_async(
                    &display_name,
                    io_priority,
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_start_mountable")]
    fn start_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        flags: DriveStartFlags,
        start_operation: Option<&impl IsA<MountOperation>>,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn start_mountable_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_start_mountable_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = start_mountable_trampoline::<P>;
        unsafe {
            ffi::g_file_start_mountable(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                start_operation.map(|p| p.as_ref()).to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn start_mountable_future(
        &self,
        flags: DriveStartFlags,
        start_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        let start_operation = start_operation.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.start_mountable(
                    flags,
                    start_operation.as_ref().map(::std::borrow::Borrow::borrow),
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_stop_mountable")]
    fn stop_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        flags: MountUnmountFlags,
        mount_operation: Option<&impl IsA<MountOperation>>,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn stop_mountable_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_stop_mountable_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = stop_mountable_trampoline::<P>;
        unsafe {
            ffi::g_file_stop_mountable(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn stop_mountable_future(
        &self,
        flags: MountUnmountFlags,
        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        let mount_operation = mount_operation.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.stop_mountable(
                    flags,
                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }

    #[doc(alias = "g_file_supports_thread_contexts")]
    fn supports_thread_contexts(&self) -> bool {
        unsafe {
            from_glib(ffi::g_file_supports_thread_contexts(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "g_file_trash")]
    fn trash(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let is_ok = ffi::g_file_trash(
                self.as_ref().to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "g_file_trash_async")]
    fn trash_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        io_priority: glib::Priority,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn trash_async_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_trash_finish(_source_object as *mut _, res, &mut error);
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = trash_async_trampoline::<P>;
        unsafe {
            ffi::g_file_trash_async(
                self.as_ref().to_glib_none().0,
                io_priority.into_glib(),
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn trash_future(
        &self,
        io_priority: glib::Priority,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.trash_async(io_priority, Some(cancellable), move |res| {
                    send.resolve(res);
                });
            },
        ))
    }

    #[doc(alias = "g_file_unmount_mountable_with_operation")]
    fn unmount_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
        &self,
        flags: MountUnmountFlags,
        mount_operation: Option<&impl IsA<MountOperation>>,
        cancellable: Option<&impl IsA<Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn unmount_mountable_with_operation_trampoline<
            P: FnOnce(Result<(), glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut crate::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = ptr::null_mut();
            let _ = ffi::g_file_unmount_mountable_with_operation_finish(
                _source_object as *mut _,
                res,
                &mut error,
            );
            let result = if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = unmount_mountable_with_operation_trampoline::<P>;
        unsafe {
            ffi::g_file_unmount_mountable_with_operation(
                self.as_ref().to_glib_none().0,
                flags.into_glib(),
                mount_operation.map(|p| p.as_ref()).to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    fn unmount_mountable_with_operation_future(
        &self,
        flags: MountUnmountFlags,
        mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
        let mount_operation = mount_operation.map(ToOwned::to_owned);
        Box_::pin(crate::GioFuture::new(
            self,
            move |obj, cancellable, send| {
                obj.unmount_mountable_with_operation(
                    flags,
                    mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
                    Some(cancellable),
                    move |res| {
                        send.resolve(res);
                    },
                );
            },
        ))
    }
}

impl<O: IsA<File>> FileExt for O {}

impl fmt::Display for File {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("File")
    }
}
