Skip to main content

gio/subclass/
file.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{
4    Error, GString, Interface, Object, prelude::*, subclass::prelude::*, thread_guard, translate::*,
5};
6
7use crate::{
8    AsyncResult, Cancellable, DriveStartFlags, File, FileAttributeInfoList, FileAttributeValue,
9    FileCopyFlags, FileCreateFlags, FileEnumerator, FileIOStream, FileInfo, FileInputStream,
10    FileMeasureFlags, FileMonitor, FileMonitorFlags, FileOutputStream, FileQueryInfoFlags,
11    IOErrorEnum, Mount, MountMountFlags, MountOperation, MountUnmountFlags, Task, ffi,
12};
13
14use libc::{c_char, c_uint};
15
16use std::{boxed::Box, path::PathBuf};
17
18// Support custom implementation of virtual functions defined in `gio::ffi::GFileIface` except pairs `xxx_async/xxx_finish` for which GIO provides a default implementation.
19pub trait FileImpl: ObjectImpl + ObjectSubclass<Type: IsA<File>> {
20    const SUPPORT_THREAD_CONTEXT: bool = true;
21
22    fn dup(&self) -> File {
23        self.parent_dup()
24    }
25
26    fn hash(&self) -> u32 {
27        self.parent_hash()
28    }
29
30    fn equal(&self, file2: &File) -> bool {
31        self.parent_equal(file2)
32    }
33
34    fn is_native(&self) -> bool {
35        self.parent_is_native()
36    }
37
38    fn has_uri_scheme(&self, uri_scheme: &str) -> bool {
39        self.parent_has_uri_scheme(uri_scheme)
40    }
41
42    fn uri_scheme(&self) -> Option<String> {
43        self.parent_uri_scheme()
44    }
45
46    fn basename(&self) -> Option<PathBuf> {
47        self.parent_basename()
48    }
49
50    fn path(&self) -> Option<PathBuf> {
51        self.parent_path()
52    }
53
54    fn uri(&self) -> String {
55        self.parent_uri()
56    }
57
58    fn parse_name(&self) -> String {
59        self.parent_parse_name()
60    }
61
62    fn parent(&self) -> Option<File> {
63        self.parent_parent()
64    }
65
66    fn has_prefix(&self, prefix: &File) -> bool {
67        self.parent_has_prefix(prefix)
68    }
69
70    fn relative_path(&self, descendant: &File) -> Option<PathBuf> {
71        self.parent_relative_path(descendant)
72    }
73
74    fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
75        self.parent_resolve_relative_path(relative_path)
76    }
77
78    fn child_for_display_name(&self, display_name: &str) -> Result<File, Error> {
79        self.parent_child_for_display_name(display_name)
80    }
81
82    fn enumerate_children(
83        &self,
84        attributes: &str,
85        flags: FileQueryInfoFlags,
86        cancellable: Option<&Cancellable>,
87    ) -> Result<FileEnumerator, Error> {
88        self.parent_enumerate_children(attributes, flags, cancellable)
89    }
90
91    fn query_info(
92        &self,
93        attributes: &str,
94        flags: FileQueryInfoFlags,
95        cancellable: Option<&Cancellable>,
96    ) -> Result<FileInfo, Error> {
97        self.parent_query_info(attributes, flags, cancellable)
98    }
99
100    fn query_filesystem_info(
101        &self,
102        attributes: &str,
103        cancellable: Option<&Cancellable>,
104    ) -> Result<FileInfo, Error> {
105        self.parent_query_filesystem_info(attributes, cancellable)
106    }
107
108    fn find_enclosing_mount(&self, cancellable: Option<&Cancellable>) -> Result<Mount, Error> {
109        self.parent_find_enclosing_mount(cancellable)
110    }
111
112    fn set_display_name(
113        &self,
114        display_name: &str,
115        cancellable: Option<&Cancellable>,
116    ) -> Result<File, Error> {
117        self.parent_set_display_name(display_name, cancellable)
118    }
119
120    fn query_settable_attributes(
121        &self,
122        cancellable: Option<&Cancellable>,
123    ) -> Result<FileAttributeInfoList, Error> {
124        self.parent_query_settable_attributes(cancellable)
125    }
126
127    fn query_writable_namespaces(
128        &self,
129        cancellable: Option<&Cancellable>,
130    ) -> Result<FileAttributeInfoList, Error> {
131        self.parent_query_writable_namespaces(cancellable)
132    }
133
134    fn set_attribute<'a>(
135        &self,
136        attribute: &str,
137        value: impl Into<FileAttributeValue<'a>>,
138        flags: FileQueryInfoFlags,
139        cancellable: Option<&Cancellable>,
140    ) -> Result<(), Error> {
141        self.parent_set_attribute(attribute, value, flags, cancellable)
142    }
143
144    fn set_attributes_from_info(
145        &self,
146        info: &FileInfo,
147        flags: FileQueryInfoFlags,
148        cancellable: Option<&Cancellable>,
149    ) -> Result<(), Error> {
150        self.parent_set_attributes_from_info(info, flags, cancellable)
151    }
152
153    fn read_fn(&self, cancellable: Option<&Cancellable>) -> Result<FileInputStream, Error> {
154        self.parent_read_fn(cancellable)
155    }
156
157    fn append_to(
158        &self,
159        flags: FileCreateFlags,
160        cancellable: Option<&Cancellable>,
161    ) -> Result<FileOutputStream, Error> {
162        self.parent_append_to(flags, cancellable)
163    }
164
165    fn create(
166        &self,
167        flags: FileCreateFlags,
168        cancellable: Option<&Cancellable>,
169    ) -> Result<FileOutputStream, Error> {
170        self.parent_create(flags, cancellable)
171    }
172
173    fn replace(
174        &self,
175        etag: Option<&str>,
176        make_backup: bool,
177        flags: FileCreateFlags,
178        cancellable: Option<&Cancellable>,
179    ) -> Result<FileOutputStream, Error> {
180        self.parent_replace(etag, make_backup, flags, cancellable)
181    }
182
183    fn delete(&self, cancellable: Option<&Cancellable>) -> Result<(), Error> {
184        self.parent_delete(cancellable)
185    }
186
187    fn trash(&self, cancellable: Option<&Cancellable>) -> Result<(), Error> {
188        self.parent_trash(cancellable)
189    }
190
191    fn make_directory(&self, cancellable: Option<&Cancellable>) -> Result<(), Error> {
192        self.parent_make_directory(cancellable)
193    }
194
195    fn make_symbolic_link(
196        &self,
197        symlink_value: impl AsRef<std::path::Path>,
198        cancellable: Option<&Cancellable>,
199    ) -> Result<(), Error> {
200        self.parent_make_symbolic_link(symlink_value, cancellable)
201    }
202
203    fn copy(
204        source: &File,
205        destination: &File,
206        flags: FileCopyFlags,
207        cancellable: Option<&Cancellable>,
208        progress_callback: Option<&mut dyn FnMut(i64, i64)>,
209    ) -> Result<(), Error> {
210        Self::parent_copy(source, destination, flags, cancellable, progress_callback)
211    }
212
213    fn move_(
214        source: &File,
215        destination: &File,
216        flags: FileCopyFlags,
217        cancellable: Option<&Cancellable>,
218        progress_callback: Option<&mut dyn FnMut(i64, i64)>,
219    ) -> Result<(), Error> {
220        Self::parent_move(source, destination, flags, cancellable, progress_callback)
221    }
222
223    fn mount_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
224        &self,
225        flags: MountMountFlags,
226        mount_operation: Option<&MountOperation>,
227        cancellable: Option<&Cancellable>,
228        callback: Option<P>,
229    ) {
230        self.parent_mount_mountable(flags, mount_operation, cancellable, callback)
231    }
232
233    fn mount_mountable_finish(&self, res: &AsyncResult) -> Result<File, Error> {
234        self.parent_mount_mountable_finish(res)
235    }
236
237    fn unmount_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
238        &self,
239        flags: MountUnmountFlags,
240        cancellable: Option<&Cancellable>,
241        callback: Option<P>,
242    ) {
243        self.parent_unmount_mountable(flags, cancellable, callback)
244    }
245
246    fn unmount_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
247        self.parent_unmount_mountable_finish(res)
248    }
249
250    fn eject_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
251        &self,
252        flags: MountUnmountFlags,
253        cancellable: Option<&Cancellable>,
254        callback: Option<P>,
255    ) {
256        self.parent_eject_mountable(flags, cancellable, callback)
257    }
258
259    fn eject_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
260        self.parent_eject_mountable_finish(res)
261    }
262
263    fn mount_enclosing_volume<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
264        &self,
265        flags: MountMountFlags,
266        mount_operation: Option<&MountOperation>,
267        cancellable: Option<&Cancellable>,
268        callback: Option<P>,
269    ) {
270        self.parent_mount_enclosing_volume(flags, mount_operation, cancellable, callback)
271    }
272
273    fn mount_enclosing_volume_finish(&self, res: &AsyncResult) -> Result<(), Error> {
274        self.parent_mount_enclosing_volume_finish(res)
275    }
276
277    fn monitor_dir(
278        &self,
279        flags: FileMonitorFlags,
280        cancellable: Option<&Cancellable>,
281    ) -> Result<FileMonitor, Error> {
282        self.parent_monitor_dir(flags, cancellable)
283    }
284
285    fn monitor_file(
286        &self,
287        flags: FileMonitorFlags,
288        cancellable: Option<&Cancellable>,
289    ) -> Result<FileMonitor, Error> {
290        self.parent_monitor_file(flags, cancellable)
291    }
292
293    fn open_readwrite(&self, cancellable: Option<&Cancellable>) -> Result<FileIOStream, Error> {
294        self.parent_open_readwrite(cancellable)
295    }
296
297    fn create_readwrite(
298        &self,
299        flags: FileCreateFlags,
300        cancellable: Option<&Cancellable>,
301    ) -> Result<FileIOStream, Error> {
302        self.parent_create_readwrite(flags, cancellable)
303    }
304
305    fn replace_readwrite(
306        &self,
307        etag: Option<&str>,
308        make_backup: bool,
309        flags: FileCreateFlags,
310        cancellable: Option<&Cancellable>,
311    ) -> Result<FileIOStream, Error> {
312        self.parent_replace_readwrite(etag, make_backup, flags, cancellable)
313    }
314
315    fn start_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
316        &self,
317        flags: DriveStartFlags,
318        mount_operation: Option<&MountOperation>,
319        cancellable: Option<&Cancellable>,
320        callback: Option<P>,
321    ) {
322        self.parent_start_mountable(flags, mount_operation, cancellable, callback)
323    }
324
325    fn start_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
326        self.parent_start_mountable_finish(res)
327    }
328
329    fn stop_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
330        &self,
331        flags: MountUnmountFlags,
332        mount_operation: Option<&MountOperation>,
333        cancellable: Option<&Cancellable>,
334        callback: Option<P>,
335    ) {
336        self.parent_stop_mountable(flags, mount_operation, cancellable, callback)
337    }
338
339    fn stop_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
340        self.parent_stop_mountable_finish(res)
341    }
342
343    fn unmount_mountable_with_operation<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
344        &self,
345        flags: MountUnmountFlags,
346        mount_operation: Option<&MountOperation>,
347        cancellable: Option<&Cancellable>,
348        callback: Option<P>,
349    ) {
350        self.parent_unmount_mountable_with_operation(flags, mount_operation, cancellable, callback)
351    }
352
353    fn unmount_mountable_with_operation_finish(&self, res: &AsyncResult) -> Result<(), Error> {
354        self.parent_unmount_mountable_with_operation_finish(res)
355    }
356
357    fn eject_mountable_with_operation<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
358        &self,
359        flags: MountUnmountFlags,
360        mount_operation: Option<&MountOperation>,
361        cancellable: Option<&Cancellable>,
362        callback: Option<P>,
363    ) {
364        self.parent_eject_mountable_with_operation(flags, mount_operation, cancellable, callback)
365    }
366
367    fn eject_mountable_with_operation_finish(&self, res: &AsyncResult) -> Result<(), Error> {
368        self.parent_eject_mountable_with_operation_finish(res)
369    }
370
371    fn poll_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
372        &self,
373        cancellable: Option<&Cancellable>,
374        callback: Option<P>,
375    ) {
376        self.parent_poll_mountable(cancellable, callback)
377    }
378
379    fn poll_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
380        self.parent_poll_mountable_finish(res)
381    }
382
383    fn measure_disk_usage(
384        &self,
385        flags: FileMeasureFlags,
386        cancellable: Option<&Cancellable>,
387        progress_callback: Option<&mut dyn FnMut(bool, u64, u64, u64)>,
388    ) -> Result<(u64, u64, u64), Error> {
389        self.parent_measure_disk_usage(flags, cancellable, progress_callback)
390    }
391
392    fn query_exists(&self, cancellable: Option<&Cancellable>) -> bool {
393        self.parent_query_exists(cancellable)
394    }
395}
396
397// Support parent implementation of virtual functions defined in `gio::ffi::GFileIface` except pairs `xxx_async/xxx_finish` for which GIO provides a default implementation.
398pub trait FileImplExt: FileImpl {
399    fn parent_dup(&self) -> File {
400        unsafe {
401            let type_data = Self::type_data();
402            let parent_iface =
403                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
404
405            let func = (*parent_iface)
406                .dup
407                .expect("no parent \"dup\" implementation");
408            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
409            from_glib_full(ret)
410        }
411    }
412
413    fn parent_hash(&self) -> u32 {
414        unsafe {
415            let type_data = Self::type_data();
416            let parent_iface =
417                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
418
419            let func = (*parent_iface)
420                .hash
421                .expect("no parent \"hash\" implementation");
422            func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0)
423        }
424    }
425
426    fn parent_equal(&self, file2: &File) -> bool {
427        unsafe {
428            let type_data = Self::type_data();
429            let parent_iface =
430                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
431
432            let func = (*parent_iface)
433                .equal
434                .expect("no parent \"equal\" implementation");
435            let ret = func(
436                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
437                file2.to_glib_none().0,
438            );
439            from_glib(ret)
440        }
441    }
442
443    fn parent_is_native(&self) -> bool {
444        unsafe {
445            let type_data = Self::type_data();
446            let parent_iface =
447                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
448
449            let func = (*parent_iface)
450                .is_native
451                .expect("no parent \"is_native\" implementation");
452            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
453            from_glib(ret)
454        }
455    }
456
457    fn parent_has_uri_scheme(&self, uri_scheme: &str) -> bool {
458        unsafe {
459            let type_data = Self::type_data();
460            let parent_iface =
461                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
462
463            let func = (*parent_iface)
464                .has_uri_scheme
465                .expect("no parent \"has_uri_scheme\" implementation");
466            let ret = func(
467                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
468                uri_scheme.to_glib_none().0,
469            );
470            from_glib(ret)
471        }
472    }
473
474    fn parent_uri_scheme(&self) -> Option<String> {
475        unsafe {
476            let type_data = Self::type_data();
477            let parent_iface =
478                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
479
480            let func = (*parent_iface)
481                .get_uri_scheme
482                .expect("no parent \"get_uri_scheme\" implementation");
483            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
484            from_glib_full(ret)
485        }
486    }
487
488    fn parent_basename(&self) -> Option<PathBuf> {
489        unsafe {
490            let type_data = Self::type_data();
491            let parent_iface =
492                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
493
494            let func = (*parent_iface)
495                .get_basename
496                .expect("no parent \"get_basename\" implementation");
497            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
498            from_glib_full(ret)
499        }
500    }
501
502    fn parent_path(&self) -> Option<PathBuf> {
503        unsafe {
504            let type_data = Self::type_data();
505            let parent_iface =
506                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
507
508            let func = (*parent_iface)
509                .get_path
510                .expect("no parent \"get_path\" implementation");
511            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
512            from_glib_full(ret)
513        }
514    }
515
516    fn parent_uri(&self) -> String {
517        unsafe {
518            let type_data = Self::type_data();
519            let parent_iface =
520                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
521
522            let func = (*parent_iface)
523                .get_uri
524                .expect("no parent \"get_uri\" implementation");
525            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
526            from_glib_full(ret)
527        }
528    }
529
530    fn parent_parse_name(&self) -> String {
531        unsafe {
532            let type_data = Self::type_data();
533            let parent_iface =
534                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
535
536            let func = (*parent_iface)
537                .get_parse_name
538                .expect("no parent \"get_parse_name\" implementation");
539            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
540            from_glib_full(ret)
541        }
542    }
543
544    fn parent_parent(&self) -> Option<File> {
545        unsafe {
546            let type_data = Self::type_data();
547            let parent_iface =
548                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
549
550            let func = (*parent_iface)
551                .get_parent
552                .expect("no parent \"get_parent\" implementation");
553            let ret = func(self.obj().unsafe_cast_ref::<File>().to_glib_none().0);
554            from_glib_full(ret)
555        }
556    }
557
558    fn parent_has_prefix(&self, prefix: &File) -> bool {
559        unsafe {
560            let type_data = Self::type_data();
561            let parent_iface =
562                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
563
564            let func = (*parent_iface)
565                .prefix_matches
566                .expect("no parent \"prefix_matches\" implementation");
567            let ret = func(
568                prefix.to_glib_none().0,
569                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
570            );
571            from_glib(ret)
572        }
573    }
574
575    fn parent_relative_path(&self, descendant: &File) -> Option<PathBuf> {
576        unsafe {
577            let type_data = Self::type_data();
578            let parent_iface =
579                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
580
581            let func = (*parent_iface)
582                .get_relative_path
583                .expect("no parent \"get_relative_path\" implementation");
584            let ret = func(
585                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
586                descendant.to_glib_none().0,
587            );
588            from_glib_full(ret)
589        }
590    }
591
592    fn parent_resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
593        unsafe {
594            let type_data = Self::type_data();
595            let parent_iface =
596                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
597
598            let func = (*parent_iface)
599                .resolve_relative_path
600                .expect("no parent \"resolve_relative_path\" implementation");
601            let ret = func(
602                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
603                relative_path.as_ref().to_glib_none().0,
604            );
605            from_glib_full(ret)
606        }
607    }
608
609    fn parent_child_for_display_name(&self, display_name: &str) -> Result<File, Error> {
610        unsafe {
611            let type_data = Self::type_data();
612            let parent_iface =
613                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
614
615            let func = (*parent_iface)
616                .get_child_for_display_name
617                .expect("no parent \"get_child_for_display_name\" implementation");
618            let mut error = std::ptr::null_mut();
619            let ret = func(
620                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
621                display_name.to_glib_none().0,
622                &mut error,
623            );
624            if error.is_null() {
625                Ok(from_glib_full(ret))
626            } else {
627                Err(from_glib_full(error))
628            }
629        }
630    }
631
632    fn parent_enumerate_children(
633        &self,
634        attributes: &str,
635        flags: FileQueryInfoFlags,
636        cancellable: Option<&Cancellable>,
637    ) -> Result<FileEnumerator, Error> {
638        unsafe {
639            let type_data = Self::type_data();
640            let parent_iface =
641                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
642
643            if let Some(func) = (*parent_iface).enumerate_children {
644                let mut error = std::ptr::null_mut();
645                let ret = func(
646                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
647                    attributes.to_glib_none().0,
648                    flags.into_glib(),
649                    cancellable.to_glib_none().0,
650                    &mut error,
651                );
652                if error.is_null() {
653                    Ok(from_glib_full(ret))
654                } else {
655                    Err(from_glib_full(error))
656                }
657            } else {
658                Err(Error::new::<IOErrorEnum>(
659                    IOErrorEnum::NotSupported,
660                    "Operation not supported",
661                ))
662            }
663        }
664    }
665
666    fn parent_query_info(
667        &self,
668        attributes: &str,
669        flags: FileQueryInfoFlags,
670        cancellable: Option<&Cancellable>,
671    ) -> Result<FileInfo, Error> {
672        unsafe {
673            let type_data = Self::type_data();
674            let parent_iface =
675                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
676
677            if let Some(func) = (*parent_iface).query_info {
678                let mut error = std::ptr::null_mut();
679                let ret = func(
680                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
681                    attributes.to_glib_none().0,
682                    flags.into_glib(),
683                    cancellable.to_glib_none().0,
684                    &mut error,
685                );
686                if error.is_null() {
687                    Ok(from_glib_full(ret))
688                } else {
689                    Err(from_glib_full(error))
690                }
691            } else {
692                Err(Error::new::<IOErrorEnum>(
693                    IOErrorEnum::NotSupported,
694                    "Operation not supported",
695                ))
696            }
697        }
698    }
699
700    fn parent_query_filesystem_info(
701        &self,
702        attributes: &str,
703        cancellable: Option<&Cancellable>,
704    ) -> Result<FileInfo, Error> {
705        unsafe {
706            let type_data = Self::type_data();
707            let parent_iface =
708                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
709
710            if let Some(func) = (*parent_iface).query_filesystem_info {
711                let mut error = std::ptr::null_mut();
712                let ret = func(
713                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
714                    attributes.to_glib_none().0,
715                    cancellable.to_glib_none().0,
716                    &mut error,
717                );
718                if error.is_null() {
719                    Ok(from_glib_full(ret))
720                } else {
721                    Err(from_glib_full(error))
722                }
723            } else {
724                Err(Error::new::<IOErrorEnum>(
725                    IOErrorEnum::NotSupported,
726                    "Operation not supported",
727                ))
728            }
729        }
730    }
731
732    fn parent_find_enclosing_mount(
733        &self,
734        cancellable: Option<&Cancellable>,
735    ) -> Result<Mount, Error> {
736        unsafe {
737            let type_data = Self::type_data();
738            let parent_iface =
739                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
740
741            if let Some(func) = (*parent_iface).find_enclosing_mount {
742                let mut error = std::ptr::null_mut();
743                let ret = func(
744                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
745                    cancellable.to_glib_none().0,
746                    &mut error,
747                );
748                if error.is_null() {
749                    Ok(from_glib_full(ret))
750                } else {
751                    Err(from_glib_full(error))
752                }
753            } else {
754                Err(Error::new::<IOErrorEnum>(
755                    IOErrorEnum::NotFound,
756                    "Containing mount does not exist",
757                ))
758            }
759        }
760    }
761
762    fn parent_set_display_name(
763        &self,
764        display_name: &str,
765        cancellable: Option<&Cancellable>,
766    ) -> Result<File, Error> {
767        unsafe {
768            let type_data = Self::type_data();
769            let parent_iface =
770                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
771
772            let func = (*parent_iface)
773                .set_display_name
774                .expect("no parent \"set_display_name\" implementation");
775            let mut error = std::ptr::null_mut();
776            let ret = func(
777                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
778                display_name.to_glib_none().0,
779                cancellable.to_glib_none().0,
780                &mut error,
781            );
782            if error.is_null() {
783                Ok(from_glib_full(ret))
784            } else {
785                Err(from_glib_full(error))
786            }
787        }
788    }
789
790    fn parent_query_settable_attributes(
791        &self,
792        cancellable: Option<&Cancellable>,
793    ) -> Result<FileAttributeInfoList, Error> {
794        unsafe {
795            let type_data = Self::type_data();
796            let parent_iface =
797                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
798
799            if let Some(func) = (*parent_iface).query_settable_attributes {
800                let mut error = std::ptr::null_mut();
801                let ret = func(
802                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
803                    cancellable.to_glib_none().0,
804                    &mut error,
805                );
806                if error.is_null() {
807                    Ok(from_glib_full(ret))
808                } else {
809                    Err(from_glib_full(error))
810                }
811            } else {
812                Ok(FileAttributeInfoList::new())
813            }
814        }
815    }
816
817    fn parent_query_writable_namespaces(
818        &self,
819        cancellable: Option<&Cancellable>,
820    ) -> Result<FileAttributeInfoList, Error> {
821        unsafe {
822            let type_data = Self::type_data();
823            let parent_iface =
824                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
825
826            if let Some(func) = (*parent_iface).query_writable_namespaces {
827                let mut error = std::ptr::null_mut();
828                let ret = func(
829                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
830                    cancellable.to_glib_none().0,
831                    &mut error,
832                );
833                if error.is_null() {
834                    Ok(from_glib_full(ret))
835                } else {
836                    Err(from_glib_full(error))
837                }
838            } else {
839                Ok(FileAttributeInfoList::new())
840            }
841        }
842    }
843
844    fn parent_set_attribute<'a>(
845        &self,
846        attribute: &str,
847        value: impl Into<FileAttributeValue<'a>>,
848        flags: FileQueryInfoFlags,
849        cancellable: Option<&Cancellable>,
850    ) -> Result<(), Error> {
851        unsafe {
852            let type_data = Self::type_data();
853            let parent_iface =
854                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
855
856            if let Some(func) = (*parent_iface).set_attribute {
857                let mut error = std::ptr::null_mut();
858                let value: FileAttributeValue<'a> = value.into();
859                let is_ok = func(
860                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
861                    attribute.to_glib_none().0,
862                    value.type_().into_glib(),
863                    value.as_ptr(),
864                    flags.into_glib(),
865                    cancellable.to_glib_none().0,
866                    &mut error,
867                );
868                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
869                if error.is_null() {
870                    Ok(())
871                } else {
872                    Err(from_glib_full(error))
873                }
874            } else {
875                Err(Error::new::<IOErrorEnum>(
876                    IOErrorEnum::NotSupported,
877                    "Operation not supported",
878                ))
879            }
880        }
881    }
882
883    fn parent_set_attributes_from_info(
884        &self,
885        info: &FileInfo,
886        flags: FileQueryInfoFlags,
887        cancellable: Option<&Cancellable>,
888    ) -> Result<(), Error> {
889        unsafe {
890            let type_data = Self::type_data();
891            let parent_iface =
892                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
893
894            let func = (*parent_iface)
895                .set_attributes_from_info
896                .expect("no parent \"set_attributes_from_info\" implementation");
897            let mut error = std::ptr::null_mut();
898            let is_ok = func(
899                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
900                info.to_glib_none().0,
901                flags.into_glib(),
902                cancellable.to_glib_none().0,
903                &mut error,
904            );
905            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
906            if error.is_null() {
907                Ok(())
908            } else {
909                Err(from_glib_full(error))
910            }
911        }
912    }
913
914    fn parent_read_fn(&self, cancellable: Option<&Cancellable>) -> Result<FileInputStream, Error> {
915        unsafe {
916            let type_data = Self::type_data();
917            let parent_iface =
918                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
919
920            if let Some(func) = (*parent_iface).read_fn {
921                let mut error = std::ptr::null_mut();
922                let ret = func(
923                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
924                    cancellable.to_glib_none().0,
925                    &mut error,
926                );
927                if error.is_null() {
928                    Ok(from_glib_full(ret))
929                } else {
930                    Err(from_glib_full(error))
931                }
932            } else {
933                Err(Error::new::<IOErrorEnum>(
934                    IOErrorEnum::NotSupported,
935                    "Operation not supported",
936                ))
937            }
938        }
939    }
940
941    fn parent_append_to(
942        &self,
943        flags: FileCreateFlags,
944        cancellable: Option<&Cancellable>,
945    ) -> Result<FileOutputStream, Error> {
946        unsafe {
947            let type_data = Self::type_data();
948            let parent_iface =
949                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
950
951            if let Some(func) = (*parent_iface).append_to {
952                let mut error = std::ptr::null_mut();
953                let ret = func(
954                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
955                    flags.into_glib(),
956                    cancellable.to_glib_none().0,
957                    &mut error,
958                );
959                if error.is_null() {
960                    Ok(from_glib_full(ret))
961                } else {
962                    Err(from_glib_full(error))
963                }
964            } else {
965                Err(Error::new::<IOErrorEnum>(
966                    IOErrorEnum::NotSupported,
967                    "Operation not supported",
968                ))
969            }
970        }
971    }
972
973    fn parent_create(
974        &self,
975        flags: FileCreateFlags,
976        cancellable: Option<&Cancellable>,
977    ) -> Result<FileOutputStream, Error> {
978        unsafe {
979            let type_data = Self::type_data();
980            let parent_iface =
981                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
982
983            if let Some(func) = (*parent_iface).create {
984                let mut error = std::ptr::null_mut();
985                let ret = func(
986                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
987                    flags.into_glib(),
988                    cancellable.to_glib_none().0,
989                    &mut error,
990                );
991                if error.is_null() {
992                    Ok(from_glib_full(ret))
993                } else {
994                    Err(from_glib_full(error))
995                }
996            } else {
997                Err(Error::new::<IOErrorEnum>(
998                    IOErrorEnum::NotSupported,
999                    "Operation not supported",
1000                ))
1001            }
1002        }
1003    }
1004
1005    fn parent_replace(
1006        &self,
1007        etag: Option<&str>,
1008        make_backup: bool,
1009        flags: FileCreateFlags,
1010        cancellable: Option<&Cancellable>,
1011    ) -> Result<FileOutputStream, Error> {
1012        unsafe {
1013            let type_data = Self::type_data();
1014            let parent_iface =
1015                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1016
1017            if let Some(func) = (*parent_iface).replace {
1018                let mut error = std::ptr::null_mut();
1019                let ret = func(
1020                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1021                    etag.to_glib_none().0,
1022                    make_backup.into_glib(),
1023                    flags.into_glib(),
1024                    cancellable.to_glib_none().0,
1025                    &mut error,
1026                );
1027                if error.is_null() {
1028                    Ok(from_glib_full(ret))
1029                } else {
1030                    Err(from_glib_full(error))
1031                }
1032            } else {
1033                Err(Error::new::<IOErrorEnum>(
1034                    IOErrorEnum::NotSupported,
1035                    "Operation not supported",
1036                ))
1037            }
1038        }
1039    }
1040
1041    fn parent_delete(&self, cancellable: Option<&Cancellable>) -> Result<(), Error> {
1042        unsafe {
1043            let type_data = Self::type_data();
1044            let parent_iface =
1045                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1046
1047            if let Some(func) = (*parent_iface).delete_file {
1048                let mut error = std::ptr::null_mut();
1049                let is_ok = func(
1050                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1051                    cancellable.to_glib_none().0,
1052                    &mut error,
1053                );
1054                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1055                if error.is_null() {
1056                    Ok(())
1057                } else {
1058                    Err(from_glib_full(error))
1059                }
1060            } else {
1061                Err(Error::new::<IOErrorEnum>(
1062                    IOErrorEnum::NotSupported,
1063                    "Operation not supported",
1064                ))
1065            }
1066        }
1067    }
1068
1069    fn parent_trash(&self, cancellable: Option<&Cancellable>) -> Result<(), Error> {
1070        unsafe {
1071            let type_data = Self::type_data();
1072            let parent_iface =
1073                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1074
1075            if let Some(func) = (*parent_iface).trash {
1076                let mut error = std::ptr::null_mut();
1077                let is_ok = func(
1078                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1079                    cancellable.to_glib_none().0,
1080                    &mut error,
1081                );
1082                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1083                if error.is_null() {
1084                    Ok(())
1085                } else {
1086                    Err(from_glib_full(error))
1087                }
1088            } else {
1089                Err(Error::new::<IOErrorEnum>(
1090                    IOErrorEnum::NotSupported,
1091                    "Operation not supported",
1092                ))
1093            }
1094        }
1095    }
1096
1097    fn parent_make_directory(&self, cancellable: Option<&Cancellable>) -> Result<(), Error> {
1098        unsafe {
1099            let type_data = Self::type_data();
1100            let parent_iface =
1101                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1102
1103            if let Some(func) = (*parent_iface).make_directory {
1104                let mut error = std::ptr::null_mut();
1105                let is_ok = func(
1106                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1107                    cancellable.to_glib_none().0,
1108                    &mut error,
1109                );
1110                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1111                if error.is_null() {
1112                    Ok(())
1113                } else {
1114                    Err(from_glib_full(error))
1115                }
1116            } else {
1117                Err(Error::new::<IOErrorEnum>(
1118                    IOErrorEnum::NotSupported,
1119                    "Operation not supported",
1120                ))
1121            }
1122        }
1123    }
1124
1125    fn parent_make_symbolic_link(
1126        &self,
1127        symlink_value: impl AsRef<std::path::Path>,
1128        cancellable: Option<&Cancellable>,
1129    ) -> Result<(), Error> {
1130        unsafe {
1131            let type_data = Self::type_data();
1132            let parent_iface =
1133                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1134
1135            if let Some(func) = (*parent_iface).make_symbolic_link {
1136                let mut error = std::ptr::null_mut();
1137                let is_ok = func(
1138                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1139                    symlink_value.as_ref().to_glib_none().0,
1140                    cancellable.to_glib_none().0,
1141                    &mut error,
1142                );
1143                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1144                if error.is_null() {
1145                    Ok(())
1146                } else {
1147                    Err(from_glib_full(error))
1148                }
1149            } else {
1150                Err(Error::new::<IOErrorEnum>(
1151                    IOErrorEnum::NotSupported,
1152                    "Operation not supported",
1153                ))
1154            }
1155        }
1156    }
1157
1158    fn parent_copy(
1159        source: &File,
1160        destination: &File,
1161        flags: FileCopyFlags,
1162        cancellable: Option<&Cancellable>,
1163        progress_callback: Option<&mut dyn FnMut(i64, i64)>,
1164    ) -> Result<(), Error> {
1165        unsafe {
1166            let type_data = Self::type_data();
1167            let parent_iface =
1168                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1169
1170            if let Some(func) = (*parent_iface).copy {
1171                let mut super_callback0 = progress_callback;
1172                let (progress_callback, progress_callback_data) = super_callback0.as_mut().map_or(
1173                    (None, std::ptr::null_mut()),
1174                    |progress_callback| {
1175                        unsafe extern "C" fn progress_callback_trampoline(
1176                            current_num_bytes: i64,
1177                            total_num_bytes: i64,
1178                            user_data: glib::ffi::gpointer,
1179                        ) {
1180                            unsafe {
1181                                let progress_callback: &mut dyn FnMut(i64, i64) =
1182                                    *(user_data as *mut &mut dyn FnMut(i64, i64));
1183                                progress_callback(current_num_bytes, total_num_bytes);
1184                            }
1185                        }
1186                        (
1187                            Some(progress_callback_trampoline as _),
1188                            progress_callback as *mut &mut dyn FnMut(i64, i64) as *mut _,
1189                        )
1190                    },
1191                );
1192
1193                let mut error = std::ptr::null_mut();
1194                let is_ok = func(
1195                    source.to_glib_none().0,
1196                    destination.to_glib_none().0,
1197                    flags.into_glib(),
1198                    cancellable.to_glib_none().0,
1199                    progress_callback,
1200                    progress_callback_data,
1201                    &mut error,
1202                );
1203                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1204                if error.is_null() {
1205                    Ok(())
1206                } else {
1207                    Err(from_glib_full(error))
1208                }
1209            } else {
1210                // give a chance to g_file_copy to call file_copy_fallback
1211                Err(Error::new::<IOErrorEnum>(
1212                    IOErrorEnum::NotSupported,
1213                    "Operation not supported",
1214                ))
1215            }
1216        }
1217    }
1218
1219    fn parent_move(
1220        source: &File,
1221        destination: &File,
1222        flags: FileCopyFlags,
1223        cancellable: Option<&Cancellable>,
1224        progress_callback: Option<&mut dyn FnMut(i64, i64)>,
1225    ) -> Result<(), Error> {
1226        unsafe {
1227            let type_data = Self::type_data();
1228            let parent_iface =
1229                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1230
1231            if let Some(func) = (*parent_iface).move_ {
1232                let mut super_callback0 = progress_callback;
1233                let (progress_callback, progress_callback_data) = super_callback0.as_mut().map_or(
1234                    (None, std::ptr::null_mut()),
1235                    |progress_callback| {
1236                        unsafe extern "C" fn progress_callback_trampoline(
1237                            current_num_bytes: i64,
1238                            total_num_bytes: i64,
1239                            user_data: glib::ffi::gpointer,
1240                        ) {
1241                            unsafe {
1242                                let progress_callback: &mut Box<dyn FnMut(i64, i64) + 'static> =
1243                                    &mut *(user_data as *mut _);
1244                                progress_callback(current_num_bytes, total_num_bytes);
1245                            }
1246                        }
1247                        (
1248                            Some(progress_callback_trampoline as _),
1249                            progress_callback as *mut &mut dyn FnMut(i64, i64) as *mut _,
1250                        )
1251                    },
1252                );
1253
1254                let mut error = std::ptr::null_mut();
1255                let is_ok = func(
1256                    source.to_glib_none().0,
1257                    destination.to_glib_none().0,
1258                    flags.into_glib(),
1259                    cancellable.to_glib_none().0,
1260                    progress_callback,
1261                    progress_callback_data,
1262                    &mut error,
1263                );
1264                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1265                if error.is_null() {
1266                    Ok(())
1267                } else {
1268                    Err(from_glib_full(error))
1269                }
1270            } else {
1271                // give a chance to g_file_move to call g_file_copy
1272                Err(Error::new::<IOErrorEnum>(
1273                    IOErrorEnum::NotSupported,
1274                    "Operation not supported",
1275                ))
1276            }
1277        }
1278    }
1279
1280    fn parent_mount_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1281        &self,
1282        flags: MountMountFlags,
1283        mount_operation: Option<&MountOperation>,
1284        cancellable: Option<&Cancellable>,
1285        callback: Option<P>,
1286    ) {
1287        unsafe {
1288            let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
1289                let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1290
1291                unsafe extern "C" fn callback_trampoline<
1292                    T: FileImpl,
1293                    P: FnOnce(&T::Type, &AsyncResult) + 'static,
1294                >(
1295                    source_object: *mut glib::gobject_ffi::GObject,
1296                    res: *mut ffi::GAsyncResult,
1297                    data: glib::ffi::gpointer,
1298                ) {
1299                    unsafe {
1300                        let source: &T::Type = &from_glib_borrow(source_object as *mut _);
1301                        let res: &AsyncResult = &from_glib_borrow(res);
1302                        let callback: Box<thread_guard::ThreadGuard<P>> =
1303                            Box::from_raw(data as *mut _);
1304                        let callback: P = callback.into_inner();
1305                        callback(source, res);
1306                    }
1307                }
1308                let callback = callback_trampoline::<Self, P>;
1309
1310                (Some(callback as _), Box::into_raw(super_callback) as *mut _)
1311            });
1312
1313            let type_data = Self::type_data();
1314            let parent_iface =
1315                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1316
1317            if let Some(func) = (*parent_iface).mount_mountable {
1318                func(
1319                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1320                    flags.into_glib(),
1321                    mount_operation.to_glib_none().0,
1322                    cancellable.to_glib_none().0,
1323                    callback,
1324                    user_data,
1325                );
1326            } else {
1327                ffi::g_task_report_new_error(
1328                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
1329                    callback,
1330                    user_data,
1331                    ffi::g_file_mount_mountable as *mut _,
1332                    IOErrorEnum::domain().into_glib(),
1333                    IOErrorEnum::NotSupported.into_glib(),
1334                    "Operation not supported".to_glib_full(),
1335                );
1336            }
1337        }
1338    }
1339
1340    fn parent_mount_mountable_finish(&self, res: &AsyncResult) -> Result<File, Error> {
1341        unsafe {
1342            let type_data = Self::type_data();
1343            let parent_iface =
1344                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1345
1346            if let Some(func) = (*parent_iface).mount_mountable_finish {
1347                let mut error = std::ptr::null_mut();
1348                let ret = func(
1349                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1350                    res.to_glib_none().0,
1351                    &mut error,
1352                );
1353                if error.is_null() {
1354                    Ok(from_glib_full(ret))
1355                } else {
1356                    Err(from_glib_full(error))
1357                }
1358            } else if let Some(task) = res.downcast_ref::<Task<File>>() {
1359                // get the `Task` result as a `File` or as an error
1360                task.to_owned().propagate()
1361            } else {
1362                // no parent implementation and don't know how to deal with the result so let's panic
1363                panic!("no parent \"mount_mountable_finish\" implementation")
1364            }
1365        }
1366    }
1367
1368    fn parent_unmount_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1369        &self,
1370        flags: MountUnmountFlags,
1371        cancellable: Option<&Cancellable>,
1372        callback: Option<P>,
1373    ) {
1374        unsafe {
1375            let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
1376                let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1377
1378                unsafe extern "C" fn callback_trampoline<
1379                    T: FileImpl,
1380                    P: FnOnce(&T::Type, &AsyncResult) + 'static,
1381                >(
1382                    source_object: *mut glib::gobject_ffi::GObject,
1383                    res: *mut ffi::GAsyncResult,
1384                    data: glib::ffi::gpointer,
1385                ) {
1386                    unsafe {
1387                        let source: &T::Type = &from_glib_borrow(source_object as *mut _);
1388                        let res: &AsyncResult = &from_glib_borrow(res);
1389                        let callback: Box<thread_guard::ThreadGuard<P>> =
1390                            Box::from_raw(data as *mut _);
1391                        let callback: P = callback.into_inner();
1392                        callback(source, res);
1393                    }
1394                }
1395                let callback = callback_trampoline::<Self, P>;
1396
1397                (Some(callback as _), Box::into_raw(super_callback) as *mut _)
1398            });
1399
1400            let type_data = Self::type_data();
1401            let parent_iface =
1402                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1403
1404            if let Some(func) = (*parent_iface).unmount_mountable {
1405                func(
1406                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1407                    flags.into_glib(),
1408                    cancellable.to_glib_none().0,
1409                    callback,
1410                    user_data,
1411                );
1412            } else {
1413                ffi::g_task_report_new_error(
1414                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
1415                    callback,
1416                    user_data,
1417                    ffi::g_file_unmount_mountable_with_operation as *mut _,
1418                    IOErrorEnum::domain().into_glib(),
1419                    IOErrorEnum::NotSupported.into_glib(),
1420                    "Operation not supported".to_glib_full(),
1421                );
1422            }
1423        }
1424    }
1425
1426    fn parent_unmount_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
1427        unsafe {
1428            let type_data = Self::type_data();
1429            let parent_iface =
1430                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1431
1432            if let Some(func) = (*parent_iface).unmount_mountable_finish {
1433                let mut error = std::ptr::null_mut();
1434                let is_ok = func(
1435                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1436                    res.to_glib_none().0,
1437                    &mut error,
1438                );
1439                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1440                if error.is_null() {
1441                    Ok(())
1442                } else {
1443                    Err(from_glib_full(error))
1444                }
1445            } else if let Some(task) = res.downcast_ref::<Task<File>>() {
1446                // get the `Task` result as a boolean or as an error
1447                task.to_owned().propagate().map(|_| ())
1448            } else {
1449                // no parent implementation and don't know how to deal with the result so let's panic
1450                panic!("no parent \"unmount_mountable_finish\" implementation")
1451            }
1452        }
1453    }
1454
1455    fn parent_eject_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1456        &self,
1457        flags: MountUnmountFlags,
1458        cancellable: Option<&Cancellable>,
1459        callback: Option<P>,
1460    ) {
1461        let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
1462            let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1463
1464            unsafe extern "C" fn callback_trampoline<
1465                T: FileImpl,
1466                P: FnOnce(&T::Type, &AsyncResult) + 'static,
1467            >(
1468                source_object: *mut glib::gobject_ffi::GObject,
1469                res: *mut ffi::GAsyncResult,
1470                data: glib::ffi::gpointer,
1471            ) {
1472                unsafe {
1473                    let source: &T::Type = &from_glib_borrow(source_object as *mut _);
1474                    let res: &AsyncResult = &from_glib_borrow(res);
1475                    let callback: Box<thread_guard::ThreadGuard<P>> = Box::from_raw(data as *mut _);
1476                    let callback: P = callback.into_inner();
1477                    callback(source, res);
1478                }
1479            }
1480            let callback = callback_trampoline::<Self, P>;
1481
1482            (Some(callback as _), Box::into_raw(super_callback) as *mut _)
1483        });
1484
1485        unsafe {
1486            let type_data = Self::type_data();
1487            let parent_iface =
1488                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1489
1490            if let Some(func) = (*parent_iface).eject_mountable {
1491                func(
1492                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1493                    flags.into_glib(),
1494                    cancellable.to_glib_none().0,
1495                    callback,
1496                    user_data,
1497                );
1498            } else {
1499                ffi::g_task_report_new_error(
1500                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
1501                    callback,
1502                    user_data,
1503                    ffi::g_file_eject_mountable_with_operation as *mut _,
1504                    IOErrorEnum::domain().into_glib(),
1505                    IOErrorEnum::NotSupported.into_glib(),
1506                    "Operation not supported".to_glib_full(),
1507                );
1508            }
1509        }
1510    }
1511
1512    fn parent_eject_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
1513        unsafe {
1514            let type_data = Self::type_data();
1515            let parent_iface =
1516                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1517
1518            if let Some(func) = (*parent_iface).eject_mountable_finish {
1519                let mut error = std::ptr::null_mut();
1520                let is_ok = func(
1521                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1522                    res.to_glib_none().0,
1523                    &mut error,
1524                );
1525                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1526                if error.is_null() {
1527                    Ok(())
1528                } else {
1529                    Err(from_glib_full(error))
1530                }
1531            } else if let Some(task) = res.downcast_ref::<Task<bool>>() {
1532                // get the `Task` result as a boolean or as an error
1533                task.to_owned().propagate().map(|_| ())
1534            } else {
1535                // no parent implementation and don't know how to deal with the result so let's panic
1536                panic!("no parent \"eject_mountable_finish\" implementation")
1537            }
1538        }
1539    }
1540
1541    fn parent_mount_enclosing_volume<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1542        &self,
1543        flags: MountMountFlags,
1544        mount_operation: Option<&MountOperation>,
1545        cancellable: Option<&Cancellable>,
1546        callback: Option<P>,
1547    ) {
1548        let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
1549            let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1550
1551            unsafe extern "C" fn callback_trampoline<
1552                T: FileImpl,
1553                P: FnOnce(&T::Type, &AsyncResult) + 'static,
1554            >(
1555                source_object: *mut glib::gobject_ffi::GObject,
1556                res: *mut ffi::GAsyncResult,
1557                data: glib::ffi::gpointer,
1558            ) {
1559                unsafe {
1560                    let source: &T::Type = &from_glib_borrow(source_object as *mut _);
1561                    let res: &AsyncResult = &from_glib_borrow(res);
1562                    let callback: Box<thread_guard::ThreadGuard<P>> = Box::from_raw(data as *mut _);
1563                    let callback: P = callback.into_inner();
1564                    callback(source, res);
1565                }
1566            }
1567            let callback = callback_trampoline::<Self, P>;
1568
1569            (Some(callback as _), Box::into_raw(super_callback) as *mut _)
1570        });
1571
1572        unsafe {
1573            let type_data = Self::type_data();
1574            let parent_iface =
1575                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1576
1577            if let Some(func) = (*parent_iface).mount_enclosing_volume {
1578                func(
1579                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1580                    flags.into_glib(),
1581                    mount_operation.to_glib_none().0,
1582                    cancellable.to_glib_none().0,
1583                    callback,
1584                    user_data,
1585                );
1586            } else {
1587                ffi::g_task_report_new_error(
1588                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
1589                    callback,
1590                    user_data,
1591                    ffi::g_file_mount_enclosing_volume as *mut _,
1592                    IOErrorEnum::domain().into_glib(),
1593                    IOErrorEnum::NotSupported.into_glib(),
1594                    "volume doesn’t implement mount enclosing volume".to_glib_full(),
1595                );
1596            }
1597        }
1598    }
1599
1600    fn parent_mount_enclosing_volume_finish(&self, res: &AsyncResult) -> Result<(), Error> {
1601        unsafe {
1602            let type_data = Self::type_data();
1603            let parent_iface =
1604                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1605
1606            if let Some(func) = (*parent_iface).mount_enclosing_volume_finish {
1607                let mut error = std::ptr::null_mut();
1608                let is_ok = func(
1609                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1610                    res.to_glib_none().0,
1611                    &mut error,
1612                );
1613                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1614                if error.is_null() {
1615                    Ok(())
1616                } else {
1617                    Err(from_glib_full(error))
1618                }
1619            } else if let Some(task) = res.downcast_ref::<Task<bool>>() {
1620                // get the `Task` result as a boolean or as an error
1621                task.to_owned().propagate().map(|_| ())
1622            } else {
1623                // no parent implementation and don't know how to deal with the result so let's panic
1624                panic!("no parent \"mount_enclosing_volume_finish\" implementation")
1625            }
1626        }
1627    }
1628
1629    fn parent_monitor_dir(
1630        &self,
1631        flags: FileMonitorFlags,
1632        cancellable: Option<&Cancellable>,
1633    ) -> Result<FileMonitor, Error> {
1634        unsafe {
1635            let type_data = Self::type_data();
1636            let parent_iface =
1637                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1638
1639            if let Some(func) = (*parent_iface).monitor_dir {
1640                let mut error = std::ptr::null_mut();
1641                let ret = func(
1642                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1643                    flags.into_glib(),
1644                    cancellable.to_glib_none().0,
1645                    &mut error,
1646                );
1647                if error.is_null() {
1648                    Ok(from_glib_full(ret))
1649                } else {
1650                    Err(from_glib_full(error))
1651                }
1652            } else {
1653                Err(Error::new::<IOErrorEnum>(
1654                    IOErrorEnum::NotSupported,
1655                    "Operation not supported",
1656                ))
1657            }
1658        }
1659    }
1660
1661    fn parent_monitor_file(
1662        &self,
1663        flags: FileMonitorFlags,
1664        cancellable: Option<&Cancellable>,
1665    ) -> Result<FileMonitor, Error> {
1666        unsafe {
1667            let type_data = Self::type_data();
1668            let parent_iface =
1669                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1670
1671            if let Some(func) = (*parent_iface).monitor_file {
1672                let mut error = std::ptr::null_mut();
1673                let ret = func(
1674                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1675                    flags.into_glib(),
1676                    cancellable.to_glib_none().0,
1677                    &mut error,
1678                );
1679                if error.is_null() {
1680                    Ok(from_glib_full(ret))
1681                } else {
1682                    Err(from_glib_full(error))
1683                }
1684            } else {
1685                // cannot call private _g_poll_file_monitor_new
1686                panic!("no parent \"monitor_file\" implementation")
1687            }
1688        }
1689    }
1690
1691    fn parent_open_readwrite(
1692        &self,
1693        cancellable: Option<&Cancellable>,
1694    ) -> Result<FileIOStream, Error> {
1695        unsafe {
1696            let type_data = Self::type_data();
1697            let parent_iface =
1698                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1699
1700            if let Some(func) = (*parent_iface).open_readwrite {
1701                let mut error = std::ptr::null_mut();
1702                let ret = func(
1703                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1704                    cancellable.to_glib_none().0,
1705                    &mut error,
1706                );
1707                if error.is_null() {
1708                    Ok(from_glib_full(ret))
1709                } else {
1710                    Err(from_glib_full(error))
1711                }
1712            } else {
1713                Err(Error::new::<IOErrorEnum>(
1714                    IOErrorEnum::NotSupported,
1715                    "Operation not supported",
1716                ))
1717            }
1718        }
1719    }
1720
1721    fn parent_create_readwrite(
1722        &self,
1723        flags: FileCreateFlags,
1724        cancellable: Option<&Cancellable>,
1725    ) -> Result<FileIOStream, Error> {
1726        unsafe {
1727            let type_data = Self::type_data();
1728            let parent_iface =
1729                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1730
1731            if let Some(func) = (*parent_iface).create_readwrite {
1732                let mut error = std::ptr::null_mut();
1733                let ret = func(
1734                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1735                    flags.into_glib(),
1736                    cancellable.to_glib_none().0,
1737                    &mut error,
1738                );
1739                if error.is_null() {
1740                    Ok(from_glib_full(ret))
1741                } else {
1742                    Err(from_glib_full(error))
1743                }
1744            } else {
1745                Err(Error::new::<IOErrorEnum>(
1746                    IOErrorEnum::NotSupported,
1747                    "Operation not supported",
1748                ))
1749            }
1750        }
1751    }
1752
1753    fn parent_replace_readwrite(
1754        &self,
1755        etag: Option<&str>,
1756        make_backup: bool,
1757        flags: FileCreateFlags,
1758        cancellable: Option<&Cancellable>,
1759    ) -> Result<FileIOStream, Error> {
1760        unsafe {
1761            let type_data = Self::type_data();
1762            let parent_iface =
1763                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1764
1765            if let Some(func) = (*parent_iface).replace_readwrite {
1766                let mut error = std::ptr::null_mut();
1767                let ret = func(
1768                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1769                    etag.to_glib_none().0,
1770                    make_backup.into_glib(),
1771                    flags.into_glib(),
1772                    cancellable.to_glib_none().0,
1773                    &mut error,
1774                );
1775                if error.is_null() {
1776                    Ok(from_glib_full(ret))
1777                } else {
1778                    Err(from_glib_full(error))
1779                }
1780            } else {
1781                Err(Error::new::<IOErrorEnum>(
1782                    IOErrorEnum::NotSupported,
1783                    "Operation not supported",
1784                ))
1785            }
1786        }
1787    }
1788
1789    fn parent_start_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1790        &self,
1791        flags: DriveStartFlags,
1792        mount_operation: Option<&MountOperation>,
1793        cancellable: Option<&Cancellable>,
1794        callback: Option<P>,
1795    ) {
1796        let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
1797            let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1798
1799            unsafe extern "C" fn callback_trampoline<
1800                T: FileImpl,
1801                P: FnOnce(&T::Type, &AsyncResult) + 'static,
1802            >(
1803                source_object: *mut glib::gobject_ffi::GObject,
1804                res: *mut ffi::GAsyncResult,
1805                data: glib::ffi::gpointer,
1806            ) {
1807                unsafe {
1808                    let source: &T::Type = &from_glib_borrow(source_object as *mut _);
1809                    let res: &AsyncResult = &from_glib_borrow(res);
1810                    let callback: Box<thread_guard::ThreadGuard<P>> = Box::from_raw(data as *mut _);
1811                    let callback: P = callback.into_inner();
1812                    callback(source, res);
1813                }
1814            }
1815            let callback = callback_trampoline::<Self, P>;
1816
1817            (Some(callback as _), Box::into_raw(super_callback) as *mut _)
1818        });
1819
1820        unsafe {
1821            let type_data = Self::type_data();
1822            let parent_iface =
1823                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1824
1825            if let Some(func) = (*parent_iface).start_mountable {
1826                func(
1827                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1828                    flags.into_glib(),
1829                    mount_operation.to_glib_none().0,
1830                    cancellable.to_glib_none().0,
1831                    callback,
1832                    user_data,
1833                );
1834            } else {
1835                ffi::g_task_report_new_error(
1836                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
1837                    callback,
1838                    user_data,
1839                    ffi::g_file_start_mountable as *mut _,
1840                    IOErrorEnum::domain().into_glib(),
1841                    IOErrorEnum::NotSupported.into_glib(),
1842                    "Operation not supported".to_glib_full(),
1843                );
1844            }
1845        }
1846    }
1847
1848    fn parent_start_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
1849        unsafe {
1850            let type_data = Self::type_data();
1851            let parent_iface =
1852                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1853
1854            if let Some(func) = (*parent_iface).start_mountable_finish {
1855                let mut error = std::ptr::null_mut();
1856                let is_ok = func(
1857                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1858                    res.to_glib_none().0,
1859                    &mut error,
1860                );
1861                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1862                if error.is_null() {
1863                    Ok(())
1864                } else {
1865                    Err(from_glib_full(error))
1866                }
1867            } else if let Some(task) = res.downcast_ref::<Task<bool>>() {
1868                // get the `Task` result as a boolean or as an error
1869                task.to_owned().propagate().map(|_| ())
1870            } else {
1871                // no parent implementation and don't know how to deal with the result so let's panic
1872                panic!("no parent \"start_mountable_finish\" implementation")
1873            }
1874        }
1875    }
1876
1877    fn parent_stop_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1878        &self,
1879        flags: MountUnmountFlags,
1880        mount_operation: Option<&MountOperation>,
1881        cancellable: Option<&Cancellable>,
1882        callback: Option<P>,
1883    ) {
1884        let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
1885            let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1886
1887            unsafe extern "C" fn callback_trampoline<
1888                T: FileImpl,
1889                P: FnOnce(&T::Type, &AsyncResult) + 'static,
1890            >(
1891                source_object: *mut glib::gobject_ffi::GObject,
1892                res: *mut ffi::GAsyncResult,
1893                data: glib::ffi::gpointer,
1894            ) {
1895                unsafe {
1896                    let source: &T::Type = &from_glib_borrow(source_object as *mut _);
1897                    let res: &AsyncResult = &from_glib_borrow(res);
1898                    let callback: Box<thread_guard::ThreadGuard<P>> = Box::from_raw(data as *mut _);
1899                    let callback: P = callback.into_inner();
1900                    callback(source, res);
1901                }
1902            }
1903            let callback = callback_trampoline::<Self, P>;
1904
1905            (Some(callback as _), Box::into_raw(super_callback) as *mut _)
1906        });
1907
1908        unsafe {
1909            let type_data = Self::type_data();
1910            let parent_iface =
1911                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1912
1913            if let Some(func) = (*parent_iface).stop_mountable {
1914                func(
1915                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1916                    flags.into_glib(),
1917                    mount_operation.to_glib_none().0,
1918                    cancellable.to_glib_none().0,
1919                    callback,
1920                    user_data,
1921                );
1922            } else {
1923                ffi::g_task_report_new_error(
1924                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
1925                    callback,
1926                    user_data,
1927                    ffi::g_file_stop_mountable as *mut _,
1928                    IOErrorEnum::domain().into_glib(),
1929                    IOErrorEnum::NotSupported.into_glib(),
1930                    "Operation not supported".to_glib_full(),
1931                );
1932            }
1933        }
1934    }
1935
1936    fn parent_stop_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
1937        unsafe {
1938            let type_data = Self::type_data();
1939            let parent_iface =
1940                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1941
1942            if let Some(func) = (*parent_iface).stop_mountable_finish {
1943                let mut error = std::ptr::null_mut();
1944                let is_ok = func(
1945                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
1946                    res.to_glib_none().0,
1947                    &mut error,
1948                );
1949                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1950                if error.is_null() {
1951                    Ok(())
1952                } else {
1953                    Err(from_glib_full(error))
1954                }
1955            } else if let Some(task) = res.downcast_ref::<Task<bool>>() {
1956                // get the `Task` result as a boolean or as an error
1957                task.to_owned().propagate().map(|_| ())
1958            } else {
1959                // no parent implementation and don't know how to deal with the result so let's panic
1960                panic!("no parent \"stop_mountable_finish\" implementation")
1961            }
1962        }
1963    }
1964
1965    fn parent_unmount_mountable_with_operation<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
1966        &self,
1967        flags: MountUnmountFlags,
1968        mount_operation: Option<&MountOperation>,
1969        cancellable: Option<&Cancellable>,
1970        callback: Option<P>,
1971    ) {
1972        unsafe {
1973            let type_data = Self::type_data();
1974            let parent_iface =
1975                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
1976
1977            if let Some(func) = (*parent_iface).unmount_mountable_with_operation {
1978                let (callback, user_data) =
1979                    callback.map_or((None, std::ptr::null_mut()), |callback| {
1980                        let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
1981
1982                        unsafe extern "C" fn callback_trampoline<
1983                            T: FileImpl,
1984                            P: FnOnce(&T::Type, &AsyncResult) + 'static,
1985                        >(
1986                            source_object: *mut glib::gobject_ffi::GObject,
1987                            res: *mut ffi::GAsyncResult,
1988                            data: glib::ffi::gpointer,
1989                        ) {
1990                            unsafe {
1991                                let source_object: &T::Type =
1992                                    &from_glib_borrow(source_object as *mut _);
1993                                let res: &AsyncResult = &from_glib_borrow(res);
1994                                let callback: Box<thread_guard::ThreadGuard<P>> =
1995                                    Box::from_raw(data as *mut _);
1996                                let callback: P = callback.into_inner();
1997                                callback(source_object, res);
1998                            }
1999                        }
2000                        let callback = callback_trampoline::<Self, P>;
2001
2002                        (Some(callback as _), Box::into_raw(super_callback) as *mut _)
2003                    });
2004
2005                func(
2006                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2007                    flags.into_glib(),
2008                    mount_operation.to_glib_none().0,
2009                    cancellable.to_glib_none().0,
2010                    callback,
2011                    user_data,
2012                )
2013            } else {
2014                self.unmount_mountable(flags, cancellable, callback);
2015            }
2016        }
2017    }
2018
2019    fn parent_unmount_mountable_with_operation_finish(
2020        &self,
2021        res: &AsyncResult,
2022    ) -> Result<(), Error> {
2023        unsafe {
2024            let type_data = Self::type_data();
2025            let parent_iface =
2026                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2027
2028            if let Some(func) = (*parent_iface).unmount_mountable_with_operation_finish {
2029                let mut error = std::ptr::null_mut();
2030                let is_ok = func(
2031                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2032                    res.to_glib_none().0,
2033                    &mut error,
2034                );
2035                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
2036                if error.is_null() {
2037                    Ok(())
2038                } else {
2039                    Err(from_glib_full(error))
2040                }
2041            } else {
2042                self.unmount_mountable_finish(res)
2043            }
2044        }
2045    }
2046
2047    fn parent_eject_mountable_with_operation<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
2048        &self,
2049        flags: MountUnmountFlags,
2050        mount_operation: Option<&MountOperation>,
2051        cancellable: Option<&Cancellable>,
2052        callback: Option<P>,
2053    ) {
2054        unsafe {
2055            let type_data = Self::type_data();
2056            let parent_iface =
2057                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2058
2059            if let Some(func) = (*parent_iface).eject_mountable_with_operation {
2060                let (callback, user_data) =
2061                    callback.map_or((None, std::ptr::null_mut()), |callback| {
2062                        let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
2063
2064                        unsafe extern "C" fn callback_trampoline<
2065                            T: FileImpl,
2066                            P: FnOnce(&T::Type, &AsyncResult) + 'static,
2067                        >(
2068                            source_object: *mut glib::gobject_ffi::GObject,
2069                            res: *mut ffi::GAsyncResult,
2070                            data: glib::ffi::gpointer,
2071                        ) {
2072                            unsafe {
2073                                let source: &T::Type = &from_glib_borrow(source_object as *mut _);
2074                                let res: &AsyncResult = &from_glib_borrow(res);
2075                                let callback: Box<thread_guard::ThreadGuard<P>> =
2076                                    Box::from_raw(data as *mut _);
2077                                let callback: P = callback.into_inner();
2078                                callback(source, res);
2079                            }
2080                        }
2081                        let callback = callback_trampoline::<Self, P>;
2082
2083                        (Some(callback as _), Box::into_raw(super_callback) as *mut _)
2084                    });
2085
2086                func(
2087                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2088                    flags.into_glib(),
2089                    mount_operation.to_glib_none().0,
2090                    cancellable.to_glib_none().0,
2091                    callback,
2092                    user_data,
2093                );
2094            } else {
2095                self.eject_mountable(flags, cancellable, callback);
2096            }
2097        }
2098    }
2099
2100    fn parent_eject_mountable_with_operation_finish(&self, res: &AsyncResult) -> Result<(), Error> {
2101        unsafe {
2102            let type_data = Self::type_data();
2103            let parent_iface =
2104                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2105
2106            if let Some(func) = (*parent_iface).eject_mountable_with_operation_finish {
2107                let mut error = std::ptr::null_mut();
2108                let is_ok = func(
2109                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2110                    res.to_glib_none().0,
2111                    &mut error,
2112                );
2113                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
2114                if error.is_null() {
2115                    Ok(())
2116                } else {
2117                    Err(from_glib_full(error))
2118                }
2119            } else {
2120                self.eject_mountable_finish(res)
2121            }
2122        }
2123    }
2124
2125    fn parent_poll_mountable<P: FnOnce(&Self::Type, &AsyncResult) + 'static>(
2126        &self,
2127        cancellable: Option<&Cancellable>,
2128        callback: Option<P>,
2129    ) {
2130        let (callback, user_data) = callback.map_or((None, std::ptr::null_mut()), |callback| {
2131            let super_callback = Box::new(thread_guard::ThreadGuard::new(callback));
2132
2133            unsafe extern "C" fn callback_trampoline<
2134                T: FileImpl,
2135                P: FnOnce(&T::Type, &AsyncResult) + 'static,
2136            >(
2137                source_object: *mut glib::gobject_ffi::GObject,
2138                res: *mut ffi::GAsyncResult,
2139                data: glib::ffi::gpointer,
2140            ) {
2141                unsafe {
2142                    let source: &T::Type = &from_glib_borrow(source_object as *mut _);
2143                    let res: &AsyncResult = &from_glib_borrow(res);
2144                    let callback: Box<thread_guard::ThreadGuard<P>> = Box::from_raw(data as *mut _);
2145                    let callback: P = callback.into_inner();
2146                    callback(source, res);
2147                }
2148            }
2149            let callback = callback_trampoline::<Self, P>;
2150
2151            (Some(callback as _), Box::into_raw(super_callback) as *mut _)
2152        });
2153
2154        unsafe {
2155            let type_data = Self::type_data();
2156            let parent_iface =
2157                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2158
2159            if let Some(func) = (*parent_iface).poll_mountable {
2160                func(
2161                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2162                    cancellable.to_glib_none().0,
2163                    callback,
2164                    user_data,
2165                );
2166            } else {
2167                ffi::g_task_report_new_error(
2168                    self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
2169                    callback,
2170                    user_data,
2171                    ffi::g_file_poll_mountable as *mut _,
2172                    IOErrorEnum::domain().into_glib(),
2173                    IOErrorEnum::NotSupported.into_glib(),
2174                    "Operation not supported".to_glib_full(),
2175                );
2176            }
2177        }
2178    }
2179
2180    fn parent_poll_mountable_finish(&self, res: &AsyncResult) -> Result<(), Error> {
2181        unsafe {
2182            let type_data = Self::type_data();
2183            let parent_iface =
2184                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2185
2186            if let Some(func) = (*parent_iface).poll_mountable_finish {
2187                let mut error = std::ptr::null_mut();
2188                let is_ok = func(
2189                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2190                    res.to_glib_none().0,
2191                    &mut error,
2192                );
2193                debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
2194                if error.is_null() {
2195                    Ok(())
2196                } else {
2197                    Err(from_glib_full(error))
2198                }
2199            } else if let Some(task) = res.downcast_ref::<Task<bool>>() {
2200                // get the `Task` result as a boolean or as an error
2201                task.to_owned().propagate().map(|_| ())
2202            } else {
2203                // no parent implementation and don't know how to deal with the result so let's panic
2204                panic!("no parent \"poll_mountable_finish\" implementation")
2205            }
2206        }
2207    }
2208
2209    fn parent_measure_disk_usage(
2210        &self,
2211        flags: FileMeasureFlags,
2212        cancellable: Option<&Cancellable>,
2213        progress_callback: Option<&mut dyn FnMut(bool, u64, u64, u64)>,
2214    ) -> Result<(u64, u64, u64), Error> {
2215        let mut super_callback0 = progress_callback;
2216        let (progress_callback, progress_callback_data) =
2217            super_callback0
2218                .as_mut()
2219                .map_or((None, std::ptr::null_mut()), |progress_callback| {
2220                    unsafe extern "C" fn progress_callback_trampoline(
2221                        reporting: glib::ffi::gboolean,
2222                        current_size: u64,
2223                        num_dirs: u64,
2224                        num_files: u64,
2225                        user_data: glib::ffi::gpointer,
2226                    ) {
2227                        unsafe {
2228                            let progress_callback: &mut Box<
2229                                dyn FnMut(bool, u64, u64, u64) + 'static,
2230                            > = &mut *(user_data as *mut _);
2231                            progress_callback(
2232                                from_glib(reporting),
2233                                current_size,
2234                                num_dirs,
2235                                num_files,
2236                            )
2237                        }
2238                    }
2239                    (
2240                        Some(progress_callback_trampoline as _),
2241                        progress_callback as *mut &mut dyn FnMut(bool, u64, u64, u64) as *mut _,
2242                    )
2243                });
2244
2245        unsafe {
2246            let type_data = Self::type_data();
2247            let parent_iface =
2248                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2249
2250            let func = (*parent_iface)
2251                .measure_disk_usage
2252                .expect("no parent \"measure_disk_usage\" implementation");
2253            let mut disk_usage = 0u64;
2254            let mut num_dirs = 0u64;
2255            let mut num_files = 0u64;
2256            let mut error = std::ptr::null_mut();
2257            let is_ok = func(
2258                self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2259                flags.into_glib(),
2260                cancellable.to_glib_none().0,
2261                progress_callback,
2262                progress_callback_data,
2263                &mut disk_usage,
2264                &mut num_dirs,
2265                &mut num_files,
2266                &mut error,
2267            );
2268            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
2269            if error.is_null() {
2270                Ok((disk_usage, num_dirs, num_files))
2271            } else {
2272                Err(from_glib_full(error))
2273            }
2274        }
2275    }
2276
2277    fn parent_query_exists(&self, cancellable: Option<&Cancellable>) -> bool {
2278        unsafe {
2279            let type_data = Self::type_data();
2280            let parent_iface =
2281                type_data.as_ref().parent_interface::<File>() as *const ffi::GFileIface;
2282
2283            if let Some(func) = (*parent_iface).query_exists {
2284                let ret = func(
2285                    self.obj().unsafe_cast_ref::<File>().to_glib_none().0,
2286                    cancellable.to_glib_none().0,
2287                );
2288                from_glib(ret)
2289            } else {
2290                let file_info =
2291                    self.query_info("standard::type", FileQueryInfoFlags::NONE, cancellable);
2292                file_info.is_ok()
2293            }
2294        }
2295    }
2296}
2297
2298impl<T: FileImpl> FileImplExt for T {}
2299
2300// Implement virtual functions defined in `gio::ffi::GFileIface` except pairs `xxx_async/xxx_finish` for which GIO provides a default implementation.
2301unsafe impl<T: FileImpl> IsImplementable<T> for File {
2302    fn interface_init(iface: &mut Interface<Self>) {
2303        let iface = iface.as_mut();
2304
2305        iface.dup = Some(file_dup::<T>);
2306        iface.hash = Some(file_hash::<T>);
2307        iface.equal = Some(file_equal::<T>);
2308        iface.is_native = Some(file_is_native::<T>);
2309        iface.has_uri_scheme = Some(file_has_uri_scheme::<T>);
2310        iface.get_uri_scheme = Some(file_get_uri_scheme::<T>);
2311        iface.get_basename = Some(file_get_basename::<T>);
2312        iface.get_path = Some(file_get_path::<T>);
2313        iface.get_uri = Some(file_get_uri::<T>);
2314        iface.get_parse_name = Some(file_get_parse_name::<T>);
2315        iface.get_parent = Some(file_get_parent::<T>);
2316        iface.prefix_matches = Some(file_prefix_matches::<T>);
2317        iface.get_relative_path = Some(file_get_relative_path::<T>);
2318        iface.resolve_relative_path = Some(file_resolve_relative_path::<T>);
2319        iface.get_child_for_display_name = Some(file_get_child_for_display_name::<T>);
2320        iface.enumerate_children = Some(file_enumerate_children::<T>);
2321        iface.query_info = Some(file_query_info::<T>);
2322        iface.query_filesystem_info = Some(file_query_filesystem_info::<T>);
2323        iface.find_enclosing_mount = Some(file_find_enclosing_mount::<T>);
2324        iface.set_display_name = Some(file_set_display_name::<T>);
2325        iface.query_settable_attributes = Some(file_query_settable_attributes::<T>);
2326        iface.query_writable_namespaces = Some(file_query_writable_namespaces::<T>);
2327        iface.set_attribute = Some(file_set_attribute::<T>);
2328        iface.set_attributes_from_info = Some(file_set_attributes_from_info::<T>);
2329        iface.read_fn = Some(file_read_fn::<T>);
2330        iface.append_to = Some(file_append_to::<T>);
2331        iface.create = Some(file_create::<T>);
2332        iface.replace = Some(file_replace::<T>);
2333        iface.delete_file = Some(file_delete_file::<T>);
2334        iface.trash = Some(file_trash::<T>);
2335        iface.make_directory = Some(file_make_directory::<T>);
2336        iface.make_symbolic_link = Some(file_make_symbolic_link::<T>);
2337        iface.copy = Some(file_copy::<T>);
2338        iface.move_ = Some(file_move::<T>);
2339        iface.mount_mountable = Some(file_mount_mountable::<T>);
2340        iface.mount_mountable_finish = Some(file_mount_mountable_finish::<T>);
2341        iface.unmount_mountable = Some(file_unmount_mountable::<T>);
2342        iface.unmount_mountable_finish = Some(file_unmount_mountable_finish::<T>);
2343        iface.eject_mountable = Some(file_eject_mountable::<T>);
2344        iface.eject_mountable_finish = Some(file_eject_mountable_finish::<T>);
2345        iface.mount_enclosing_volume = Some(file_mount_enclosing_volume::<T>);
2346        iface.mount_enclosing_volume_finish = Some(file_mount_enclosing_volume_finish::<T>);
2347        iface.monitor_dir = Some(file_monitor_dir::<T>);
2348        iface.monitor_file = Some(file_monitor_file::<T>);
2349        iface.open_readwrite = Some(file_open_readwrite::<T>);
2350        iface.create_readwrite = Some(file_create_readwrite::<T>);
2351        iface.replace_readwrite = Some(file_replace_readwrite::<T>);
2352        iface.start_mountable = Some(file_start_mountable::<T>);
2353        iface.start_mountable_finish = Some(file_start_mountable_finish::<T>);
2354        iface.stop_mountable = Some(file_stop_mountable::<T>);
2355        iface.stop_mountable_finish = Some(file_stop_mountable_finish::<T>);
2356        iface.supports_thread_contexts = T::SUPPORT_THREAD_CONTEXT.into_glib();
2357        iface.unmount_mountable_with_operation = Some(file_unmount_mountable_with_operation::<T>);
2358        iface.unmount_mountable_with_operation_finish =
2359            Some(file_unmount_mountable_with_operation_finish::<T>);
2360        iface.eject_mountable_with_operation = Some(file_eject_mountable_with_operation::<T>);
2361        iface.eject_mountable_with_operation_finish =
2362            Some(file_eject_mountable_with_operation_finish::<T>);
2363        iface.poll_mountable = Some(file_poll_mountable::<T>);
2364        iface.poll_mountable_finish = Some(file_poll_mountable_finish::<T>);
2365        iface.measure_disk_usage = Some(file_measure_disk_usage::<T>);
2366        #[cfg(feature = "v2_84")]
2367        {
2368            iface.query_exists = Some(file_query_exists::<T>);
2369        }
2370        // `GFile` already implements `xxx_async/xxx_finish` vfuncs and this should be ok.
2371        // TODO: when needed, override the `GFile` implementation of the following vfuncs:
2372        // iface.enumerate_children_async = Some(file_enumerate_children_async::<T>);
2373        // iface.enumerate_children_finish = Some(file_enumerate_children_finish::<T>);
2374        // iface.query_info_async = Some(file_query_info_async::<T>);
2375        // iface.query_info_finish = Some(file_query_info_finish::<T>);
2376        // iface.query_filesystem_info_async = Some(file_query_filesystem_info_async::<T>);
2377        // iface.query_filesystem_info_finish = Some(file_query_filesystem_info_finish::<T>);
2378        // iface.find_enclosing_mount_async = Some(file_find_enclosing_mount_asyncv);
2379        // iface.find_enclosing_mount_finish = Some(file_find_enclosing_mount_finish::<T>);
2380        // iface.set_display_name_async = Some(file_set_display_name_async::<T>);
2381        // iface.set_display_name_finish = Some(file_set_display_name_finish::<T>);
2382        // iface._query_settable_attributes_async = Some(_file_query_settable_attributes_async::<T>);
2383        // iface._query_settable_attributes_finish = Some(_file_query_settable_attributes_finish::<T>);
2384        // iface._query_writable_namespaces_async = Some(_file_query_writable_namespaces_async::<T>);
2385        // iface._query_writable_namespaces_finish = Some(_file_query_writable_namespaces_finish::<T>);
2386        // iface.set_attributes_async = Some(file_set_attributes_async::<T>);
2387        // iface.set_attributes_finish = Some(file_set_attributes_finishv);
2388        // iface.read_async = Some(file_read_async::<T>);
2389        // iface.read_finish = Some(file_read_finish::<T>);
2390        // iface.append_to_async = Some(file_append_to_async::<T>);
2391        // iface.append_to_finish = Some(file_append_to_finish::<T>);
2392        // iface.create_async = Some(file_create_async::<T>);
2393        // iface.create_finish = Some(file_create_finish::<T>);
2394        // iface.replace_async = Some(file_replace_async::<T>);
2395        // iface.replace_finish = Some(file_replace_finish::<T>);
2396        // iface.delete_file_async = Some(file_delete_file_async::<T>);
2397        // iface.delete_file_finish = Some(file_delete_file_finish::<T>);
2398        // iface.trash_async = Some(file_trash_async::<T>);
2399        // iface.trash_finish = Some(file_trash_finish::<T>);
2400        // iface.make_directory_async = Some(file_make_directory_async::<T>);
2401        // iface.make_directory_finish = Some(file_make_directory_finish::<T>);
2402        // iface.make_symbolic_link_async = Some(file_make_symbolic_link_async::<T>);
2403        // iface.make_symbolic_link_finish = Some(file_make_symbolic_link_finish::<T>);
2404        // iface.copy_async = Some(file_copy_async::<T>);
2405        // iface.copy_finish = Some(file_copy_finish::<T>);
2406        // iface.move_async = Some(file_move_async::<T>);
2407        // iface.move_finish = Some(file_move_finish::<T>);
2408        // iface.open_readwrite_async = Some(file_open_readwrite_async::<T>);
2409        // iface.open_readwrite_finish = Some(file_open_readwrite_finish::<T>);
2410        // iface.create_readwrite_async = Some(file_create_readwrite_async::<T>);
2411        // iface.create_readwrite_finish = Some(file_create_readwrite_finish::<T>);
2412        // iface.replace_readwrite_async = Some(file_replace_readwrite_async::<T>);
2413        // iface.replace_readwrite_finish = Some(file_replace_readwrite_finish::<T>);
2414        // iface.measure_disk_usage_async = Some(file_measure_disk_usage_async::<T>);
2415        // iface.measure_disk_usage_finish = Some(file_measure_disk_usage_finish::<T>);
2416    }
2417}
2418
2419unsafe extern "C" fn file_dup<T: FileImpl>(file: *mut ffi::GFile) -> *mut ffi::GFile {
2420    unsafe {
2421        let instance = &*(file as *mut T::Instance);
2422        let imp = instance.imp();
2423
2424        imp.dup().to_glib_full()
2425    }
2426}
2427
2428unsafe extern "C" fn file_hash<T: FileImpl>(file: *mut ffi::GFile) -> c_uint {
2429    unsafe {
2430        let instance = &*(file as *mut T::Instance);
2431        let imp = instance.imp();
2432
2433        imp.hash()
2434    }
2435}
2436
2437unsafe extern "C" fn file_equal<T: FileImpl>(
2438    file1: *mut ffi::GFile,
2439    file2: *mut ffi::GFile,
2440) -> glib::ffi::gboolean {
2441    unsafe {
2442        let instance = &*(file1 as *mut T::Instance);
2443        let imp = instance.imp();
2444
2445        imp.equal(&from_glib_borrow(file2)).into_glib()
2446    }
2447}
2448
2449unsafe extern "C" fn file_is_native<T: FileImpl>(file: *mut ffi::GFile) -> glib::ffi::gboolean {
2450    unsafe {
2451        let instance = &*(file as *mut T::Instance);
2452        let imp = instance.imp();
2453
2454        imp.is_native().into_glib()
2455    }
2456}
2457
2458unsafe extern "C" fn file_has_uri_scheme<T: FileImpl>(
2459    file: *mut ffi::GFile,
2460    uri_scheme: *const c_char,
2461) -> glib::ffi::gboolean {
2462    unsafe {
2463        let instance = &*(file as *mut T::Instance);
2464        let imp = instance.imp();
2465
2466        imp.has_uri_scheme(&GString::from_glib_borrow(uri_scheme))
2467            .into_glib()
2468    }
2469}
2470
2471unsafe extern "C" fn file_get_uri_scheme<T: FileImpl>(file: *mut ffi::GFile) -> *mut c_char {
2472    unsafe {
2473        let instance = &*(file as *mut T::Instance);
2474        let imp = instance.imp();
2475
2476        let res = imp.uri_scheme();
2477        if let Some(uri_scheme) = res {
2478            uri_scheme.to_glib_full()
2479        } else {
2480            std::ptr::null_mut()
2481        }
2482    }
2483}
2484
2485unsafe extern "C" fn file_get_basename<T: FileImpl>(file: *mut ffi::GFile) -> *mut c_char {
2486    unsafe {
2487        let instance = &*(file as *mut T::Instance);
2488        let imp = instance.imp();
2489
2490        let res = imp.basename();
2491        if let Some(basename) = res {
2492            basename.to_glib_full()
2493        } else {
2494            std::ptr::null_mut()
2495        }
2496    }
2497}
2498
2499unsafe extern "C" fn file_get_path<T: FileImpl>(file: *mut ffi::GFile) -> *mut c_char {
2500    unsafe {
2501        let instance = &*(file as *mut T::Instance);
2502        let imp = instance.imp();
2503
2504        let res = imp.path();
2505        if let Some(path) = res {
2506            path.to_glib_full()
2507        } else {
2508            std::ptr::null_mut()
2509        }
2510    }
2511}
2512
2513unsafe extern "C" fn file_get_uri<T: FileImpl>(file: *mut ffi::GFile) -> *mut c_char {
2514    unsafe {
2515        let instance = &*(file as *mut T::Instance);
2516        let imp = instance.imp();
2517
2518        let uri = imp.uri();
2519        uri.to_glib_full()
2520    }
2521}
2522
2523unsafe extern "C" fn file_get_parse_name<T: FileImpl>(file: *mut ffi::GFile) -> *mut c_char {
2524    unsafe {
2525        let instance = &*(file as *mut T::Instance);
2526        let imp = instance.imp();
2527
2528        let parse_name = imp.parse_name();
2529        parse_name.to_glib_full()
2530    }
2531}
2532
2533unsafe extern "C" fn file_get_parent<T: FileImpl>(file: *mut ffi::GFile) -> *mut ffi::GFile {
2534    unsafe {
2535        let instance = &*(file as *mut T::Instance);
2536        let imp = instance.imp();
2537
2538        let res = imp.parent();
2539        if let Some(parent) = res {
2540            parent.to_glib_full()
2541        } else {
2542            std::ptr::null_mut()
2543        }
2544    }
2545}
2546
2547unsafe extern "C" fn file_prefix_matches<T: FileImpl>(
2548    prefix: *mut ffi::GFile,
2549    file: *mut ffi::GFile,
2550) -> glib::ffi::gboolean {
2551    unsafe {
2552        let instance = &*(file as *mut T::Instance);
2553        let imp = instance.imp();
2554
2555        imp.has_prefix(&from_glib_borrow(prefix)).into_glib()
2556    }
2557}
2558
2559unsafe extern "C" fn file_get_relative_path<T: FileImpl>(
2560    parent: *mut ffi::GFile,
2561    descendant: *mut ffi::GFile,
2562) -> *mut c_char {
2563    unsafe {
2564        let instance = &*(parent as *mut T::Instance);
2565        let imp = instance.imp();
2566
2567        let res = imp.relative_path(&from_glib_borrow(descendant));
2568        if let Some(relative_path) = res {
2569            relative_path.to_glib_full()
2570        } else {
2571            std::ptr::null_mut()
2572        }
2573    }
2574}
2575
2576unsafe extern "C" fn file_resolve_relative_path<T: FileImpl>(
2577    file: *mut ffi::GFile,
2578    relative_path: *const c_char,
2579) -> *mut ffi::GFile {
2580    unsafe {
2581        let instance = &*(file as *mut T::Instance);
2582        let imp = instance.imp();
2583
2584        let resolved_path =
2585            imp.resolve_relative_path(GString::from_glib_borrow(relative_path).as_ref());
2586        resolved_path.to_glib_full()
2587    }
2588}
2589
2590unsafe extern "C" fn file_get_child_for_display_name<T: FileImpl>(
2591    file: *mut ffi::GFile,
2592    display_name: *const c_char,
2593    error: *mut *mut glib::ffi::GError,
2594) -> *mut ffi::GFile {
2595    unsafe {
2596        let instance = &*(file as *mut T::Instance);
2597        let imp = instance.imp();
2598
2599        // check display name is a valid ut8 and handle error to avoid rust panicking if it is not
2600        let basename = glib::ffi::g_filename_from_utf8(
2601            display_name,
2602            -1,
2603            std::ptr::null_mut(),
2604            std::ptr::null_mut(),
2605            std::ptr::null_mut(),
2606        );
2607        if basename.is_null() {
2608            if !error.is_null() {
2609                *error =
2610                    Error::new::<IOErrorEnum>(IOErrorEnum::InvalidFilename, "Invalid filename")
2611                        .to_glib_full();
2612            }
2613            return std::ptr::null_mut();
2614        }
2615
2616        let res = imp.child_for_display_name(&GString::from_glib_borrow(display_name));
2617        match res {
2618            Ok(child) => child.to_glib_full(),
2619            Err(err) => {
2620                if !error.is_null() {
2621                    *error = err.to_glib_full()
2622                }
2623                std::ptr::null_mut()
2624            }
2625        }
2626    }
2627}
2628
2629unsafe extern "C" fn file_enumerate_children<T: FileImpl>(
2630    file: *mut ffi::GFile,
2631    attributes: *const c_char,
2632    flags: ffi::GFileQueryInfoFlags,
2633    cancellable: *mut ffi::GCancellable,
2634    error: *mut *mut glib::ffi::GError,
2635) -> *mut ffi::GFileEnumerator {
2636    unsafe {
2637        let instance = &*(file as *mut T::Instance);
2638        let imp = instance.imp();
2639        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2640
2641        let res = imp.enumerate_children(
2642            &GString::from_glib_borrow(attributes),
2643            from_glib(flags),
2644            cancellable.as_ref(),
2645        );
2646        match res {
2647            Ok(enumerator) => enumerator.to_glib_full(),
2648            Err(err) => {
2649                if !error.is_null() {
2650                    *error = err.to_glib_full()
2651                }
2652                std::ptr::null_mut()
2653            }
2654        }
2655    }
2656}
2657
2658unsafe extern "C" fn file_query_info<T: FileImpl>(
2659    file: *mut ffi::GFile,
2660    attributes: *const c_char,
2661    flags: ffi::GFileQueryInfoFlags,
2662    cancellable: *mut ffi::GCancellable,
2663    error: *mut *mut glib::ffi::GError,
2664) -> *mut ffi::GFileInfo {
2665    unsafe {
2666        let instance = &*(file as *mut T::Instance);
2667        let imp = instance.imp();
2668        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2669
2670        let res = imp.query_info(
2671            &GString::from_glib_borrow(attributes),
2672            from_glib(flags),
2673            cancellable.as_ref(),
2674        );
2675        match res {
2676            Ok(file_info) => file_info.to_glib_full(),
2677            Err(err) => {
2678                if !error.is_null() {
2679                    *error = err.to_glib_full()
2680                }
2681                std::ptr::null_mut()
2682            }
2683        }
2684    }
2685}
2686
2687unsafe extern "C" fn file_query_filesystem_info<T: FileImpl>(
2688    file: *mut ffi::GFile,
2689    attributes: *const c_char,
2690    cancellable: *mut ffi::GCancellable,
2691    error: *mut *mut glib::ffi::GError,
2692) -> *mut ffi::GFileInfo {
2693    unsafe {
2694        let instance = &*(file as *mut T::Instance);
2695        let imp = instance.imp();
2696        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2697
2698        let res =
2699            imp.query_filesystem_info(&GString::from_glib_borrow(attributes), cancellable.as_ref());
2700        match res {
2701            Ok(file_info) => file_info.to_glib_full(),
2702            Err(err) => {
2703                if !error.is_null() {
2704                    *error = err.to_glib_full()
2705                }
2706                std::ptr::null_mut()
2707            }
2708        }
2709    }
2710}
2711
2712unsafe extern "C" fn file_find_enclosing_mount<T: FileImpl>(
2713    file: *mut ffi::GFile,
2714    cancellable: *mut ffi::GCancellable,
2715    error: *mut *mut glib::ffi::GError,
2716) -> *mut ffi::GMount {
2717    unsafe {
2718        let instance = &*(file as *mut T::Instance);
2719        let imp = instance.imp();
2720        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2721
2722        let res = imp.find_enclosing_mount(cancellable.as_ref());
2723        match res {
2724            Ok(mount) => mount.to_glib_full(),
2725            Err(err) => {
2726                if !error.is_null() {
2727                    *error = err.to_glib_full()
2728                }
2729                std::ptr::null_mut()
2730            }
2731        }
2732    }
2733}
2734
2735unsafe extern "C" fn file_set_display_name<T: FileImpl>(
2736    file: *mut ffi::GFile,
2737    display_name: *const c_char,
2738    cancellable: *mut ffi::GCancellable,
2739    error: *mut *mut glib::ffi::GError,
2740) -> *mut ffi::GFile {
2741    unsafe {
2742        let instance = &*(file as *mut T::Instance);
2743        let imp = instance.imp();
2744        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2745
2746        let res = imp.set_display_name(
2747            &GString::from_glib_borrow(display_name),
2748            cancellable.as_ref(),
2749        );
2750        match res {
2751            Ok(renamed_file) => renamed_file.to_glib_full(),
2752            Err(err) => {
2753                if !error.is_null() {
2754                    *error = err.to_glib_full()
2755                }
2756                std::ptr::null_mut()
2757            }
2758        }
2759    }
2760}
2761
2762unsafe extern "C" fn file_query_settable_attributes<T: FileImpl>(
2763    file: *mut ffi::GFile,
2764    cancellable: *mut ffi::GCancellable,
2765    error: *mut *mut glib::ffi::GError,
2766) -> *mut ffi::GFileAttributeInfoList {
2767    unsafe {
2768        let instance = &*(file as *mut T::Instance);
2769        let imp = instance.imp();
2770        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2771
2772        let res = imp.query_settable_attributes(cancellable.as_ref());
2773        match res {
2774            Ok(settable_attributes) => settable_attributes.to_glib_full(),
2775            Err(err) => {
2776                if !error.is_null() {
2777                    *error = err.to_glib_full()
2778                }
2779                std::ptr::null_mut()
2780            }
2781        }
2782    }
2783}
2784
2785unsafe extern "C" fn file_query_writable_namespaces<T: FileImpl>(
2786    file: *mut ffi::GFile,
2787    cancellable: *mut ffi::GCancellable,
2788    error: *mut *mut glib::ffi::GError,
2789) -> *mut ffi::GFileAttributeInfoList {
2790    unsafe {
2791        let instance = &*(file as *mut T::Instance);
2792        let imp = instance.imp();
2793        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2794
2795        let res = imp.query_writable_namespaces(cancellable.as_ref());
2796        match res {
2797            Ok(writable_namespaces) => writable_namespaces.to_glib_full(),
2798            Err(err) => {
2799                if !error.is_null() {
2800                    *error = err.to_glib_full()
2801                }
2802                std::ptr::null_mut()
2803            }
2804        }
2805    }
2806}
2807
2808unsafe extern "C" fn file_set_attribute<T: FileImpl>(
2809    file: *mut ffi::GFile,
2810    attribute: *const c_char,
2811    type_: ffi::GFileAttributeType,
2812    value_p: glib::ffi::gpointer,
2813    flags: ffi::GFileQueryInfoFlags,
2814    cancellable: *mut ffi::GCancellable,
2815    error: *mut *mut glib::ffi::GError,
2816) -> glib::ffi::gboolean {
2817    unsafe {
2818        let instance = &*(file as *mut T::Instance);
2819        let imp = instance.imp();
2820        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2821
2822        let res_ = imp.set_attribute(
2823            &GString::from_glib_borrow(attribute),
2824            FileAttributeValue::for_pointer(from_glib(type_), value_p),
2825            from_glib(flags),
2826            cancellable.as_ref(),
2827        );
2828
2829        match res_ {
2830            Ok(_) => true.into_glib(),
2831            Err(err) => {
2832                if !error.is_null() {
2833                    *error = err.to_glib_full()
2834                }
2835                false.into_glib()
2836            }
2837        }
2838    }
2839}
2840
2841unsafe extern "C" fn file_set_attributes_from_info<T: FileImpl>(
2842    file: *mut ffi::GFile,
2843    info: *mut ffi::GFileInfo,
2844    flags: ffi::GFileQueryInfoFlags,
2845    cancellable: *mut ffi::GCancellable,
2846    error: *mut *mut glib::ffi::GError,
2847) -> glib::ffi::gboolean {
2848    unsafe {
2849        let instance = &*(file as *mut T::Instance);
2850        let imp = instance.imp();
2851        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2852
2853        let res_ = imp.set_attributes_from_info(
2854            &from_glib_borrow(info),
2855            from_glib(flags),
2856            cancellable.as_ref(),
2857        );
2858        match res_ {
2859            Ok(_) => true.into_glib(),
2860            Err(err) => {
2861                if !error.is_null() {
2862                    *error = err.to_glib_full()
2863                }
2864                false.into_glib()
2865            }
2866        }
2867    }
2868}
2869
2870unsafe extern "C" fn file_read_fn<T: FileImpl>(
2871    file: *mut ffi::GFile,
2872    cancellable: *mut ffi::GCancellable,
2873    error: *mut *mut glib::ffi::GError,
2874) -> *mut ffi::GFileInputStream {
2875    unsafe {
2876        let instance = &*(file as *mut T::Instance);
2877        let imp = instance.imp();
2878        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2879
2880        let res_ = imp.read_fn(cancellable.as_ref());
2881        match res_ {
2882            Ok(input_stream) => input_stream.to_glib_full(),
2883            Err(err) => {
2884                if !error.is_null() {
2885                    *error = err.to_glib_full()
2886                }
2887                std::ptr::null_mut()
2888            }
2889        }
2890    }
2891}
2892
2893unsafe extern "C" fn file_append_to<T: FileImpl>(
2894    file: *mut ffi::GFile,
2895    flags: ffi::GFileCreateFlags,
2896    cancellable: *mut ffi::GCancellable,
2897    error: *mut *mut glib::ffi::GError,
2898) -> *mut ffi::GFileOutputStream {
2899    unsafe {
2900        let instance = &*(file as *mut T::Instance);
2901        let imp = instance.imp();
2902        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2903
2904        let res_ = imp.append_to(from_glib(flags), cancellable.as_ref());
2905        match res_ {
2906            Ok(output_stream) => output_stream.to_glib_full(),
2907            Err(err) => {
2908                if !error.is_null() {
2909                    *error = err.to_glib_full()
2910                }
2911                std::ptr::null_mut()
2912            }
2913        }
2914    }
2915}
2916
2917unsafe extern "C" fn file_create<T: FileImpl>(
2918    file: *mut ffi::GFile,
2919    flags: ffi::GFileCreateFlags,
2920    cancellable: *mut ffi::GCancellable,
2921    error: *mut *mut glib::ffi::GError,
2922) -> *mut ffi::GFileOutputStream {
2923    unsafe {
2924        let instance = &*(file as *mut T::Instance);
2925        let imp = instance.imp();
2926        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2927
2928        let res_ = imp.create(from_glib(flags), cancellable.as_ref());
2929        match res_ {
2930            Ok(output_stream) => output_stream.to_glib_full(),
2931            Err(err) => {
2932                if !error.is_null() {
2933                    *error = err.to_glib_full()
2934                }
2935                std::ptr::null_mut()
2936            }
2937        }
2938    }
2939}
2940
2941unsafe extern "C" fn file_replace<T: FileImpl>(
2942    file: *mut ffi::GFile,
2943    etag: *const c_char,
2944    make_backup: glib::ffi::gboolean,
2945    flags: ffi::GFileCreateFlags,
2946    cancellable: *mut ffi::GCancellable,
2947    error: *mut *mut glib::ffi::GError,
2948) -> *mut ffi::GFileOutputStream {
2949    unsafe {
2950        let instance = &*(file as *mut T::Instance);
2951        let imp = instance.imp();
2952        let etag = Option::<GString>::from_glib_none(etag);
2953        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2954
2955        let res_ = imp.replace(
2956            etag.as_ref().map(|etag| etag.as_str()),
2957            from_glib(make_backup),
2958            from_glib(flags),
2959            cancellable.as_ref(),
2960        );
2961        match res_ {
2962            Ok(output_stream) => output_stream.to_glib_full(),
2963            Err(err) => {
2964                if !error.is_null() {
2965                    *error = err.to_glib_full()
2966                }
2967                std::ptr::null_mut()
2968            }
2969        }
2970    }
2971}
2972
2973unsafe extern "C" fn file_delete_file<T: FileImpl>(
2974    file: *mut ffi::GFile,
2975    cancellable: *mut ffi::GCancellable,
2976    error: *mut *mut glib::ffi::GError,
2977) -> glib::ffi::gboolean {
2978    unsafe {
2979        let instance = &*(file as *mut T::Instance);
2980        let imp = instance.imp();
2981        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2982
2983        let res = imp.delete(cancellable.as_ref());
2984        match res {
2985            Ok(_) => true.into_glib(),
2986            Err(err) => {
2987                if !error.is_null() {
2988                    *error = err.to_glib_full()
2989                }
2990                false.into_glib()
2991            }
2992        }
2993    }
2994}
2995
2996unsafe extern "C" fn file_trash<T: FileImpl>(
2997    file: *mut ffi::GFile,
2998    cancellable: *mut ffi::GCancellable,
2999    error: *mut *mut glib::ffi::GError,
3000) -> glib::ffi::gboolean {
3001    unsafe {
3002        let instance = &*(file as *mut T::Instance);
3003        let imp = instance.imp();
3004        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3005
3006        let res = imp.trash(cancellable.as_ref());
3007        match res {
3008            Ok(_) => true.into_glib(),
3009            Err(err) => {
3010                if !error.is_null() {
3011                    *error = err.to_glib_full()
3012                }
3013                false.into_glib()
3014            }
3015        }
3016    }
3017}
3018
3019unsafe extern "C" fn file_make_directory<T: FileImpl>(
3020    file: *mut ffi::GFile,
3021    cancellable: *mut ffi::GCancellable,
3022    error: *mut *mut glib::ffi::GError,
3023) -> glib::ffi::gboolean {
3024    unsafe {
3025        let instance = &*(file as *mut T::Instance);
3026        let imp = instance.imp();
3027        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3028
3029        let res = imp.make_directory(cancellable.as_ref());
3030        match res {
3031            Ok(_) => true.into_glib(),
3032            Err(err) => {
3033                if !error.is_null() {
3034                    *error = err.to_glib_full()
3035                }
3036                false.into_glib()
3037            }
3038        }
3039    }
3040}
3041
3042unsafe extern "C" fn file_make_symbolic_link<T: FileImpl>(
3043    file: *mut ffi::GFile,
3044    symlink_value: *const c_char,
3045    cancellable: *mut ffi::GCancellable,
3046    error: *mut *mut glib::ffi::GError,
3047) -> glib::ffi::gboolean {
3048    unsafe {
3049        let instance = &*(file as *mut T::Instance);
3050        let imp = instance.imp();
3051        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3052
3053        let res = imp.make_symbolic_link(
3054            GString::from_glib_borrow(symlink_value).as_ref(),
3055            cancellable.as_ref(),
3056        );
3057        match res {
3058            Ok(_) => true.into_glib(),
3059            Err(err) => {
3060                if !error.is_null() {
3061                    *error = err.to_glib_full()
3062                }
3063                false.into_glib()
3064            }
3065        }
3066    }
3067}
3068
3069unsafe extern "C" fn file_copy<T: FileImpl>(
3070    source: *mut ffi::GFile,
3071    destination: *mut ffi::GFile,
3072    flags: ffi::GFileCopyFlags,
3073    cancellable: *mut ffi::GCancellable,
3074    progress_callback: ffi::GFileProgressCallback,
3075    progress_callback_data: glib::ffi::gpointer,
3076    error: *mut *mut glib::ffi::GError,
3077) -> glib::ffi::gboolean {
3078    unsafe {
3079        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3080        let mut progress_callback = progress_callback.map(|callback| {
3081            move |current_num_bytes, total_num_bytes| {
3082                callback(current_num_bytes, total_num_bytes, progress_callback_data)
3083            }
3084        });
3085        let progress_callback_ref = progress_callback
3086            .as_mut()
3087            .map(|f| f as &mut dyn FnMut(i64, i64));
3088
3089        let res = T::copy(
3090            &from_glib_borrow(source),
3091            &from_glib_borrow(destination),
3092            from_glib(flags),
3093            cancellable.as_ref(),
3094            progress_callback_ref,
3095        );
3096        match res {
3097            Ok(_) => true.into_glib(),
3098            Err(err) => {
3099                if !error.is_null() {
3100                    *error = err.to_glib_full()
3101                }
3102                false.into_glib()
3103            }
3104        }
3105    }
3106}
3107
3108unsafe extern "C" fn file_move<T: FileImpl>(
3109    source: *mut ffi::GFile,
3110    destination: *mut ffi::GFile,
3111    flags: ffi::GFileCopyFlags,
3112    cancellable: *mut ffi::GCancellable,
3113    progress_callback: ffi::GFileProgressCallback,
3114    progress_callback_data: glib::ffi::gpointer,
3115    error: *mut *mut glib::ffi::GError,
3116) -> glib::ffi::gboolean {
3117    unsafe {
3118        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3119        let mut progress_callback = progress_callback.map(|callback| {
3120            move |current_num_bytes, total_num_bytes| {
3121                callback(current_num_bytes, total_num_bytes, progress_callback_data)
3122            }
3123        });
3124        let progress_callback_ref = progress_callback
3125            .as_mut()
3126            .map(|f| f as &mut dyn FnMut(i64, i64));
3127
3128        let res = T::move_(
3129            &from_glib_borrow(source),
3130            &from_glib_borrow(destination),
3131            from_glib(flags),
3132            cancellable.as_ref(),
3133            progress_callback_ref,
3134        );
3135        match res {
3136            Ok(_) => true.into_glib(),
3137            Err(err) => {
3138                if !error.is_null() {
3139                    *error = err.to_glib_full()
3140                }
3141                false.into_glib()
3142            }
3143        }
3144    }
3145}
3146
3147unsafe extern "C" fn file_mount_mountable<T: FileImpl>(
3148    file: *mut ffi::GFile,
3149    flags: ffi::GMountMountFlags,
3150    mount_operation: *mut ffi::GMountOperation,
3151    cancellable: *mut ffi::GCancellable,
3152    callback: ffi::GAsyncReadyCallback,
3153    user_data: glib::ffi::gpointer,
3154) {
3155    unsafe {
3156        let instance = &*(file as *mut T::Instance);
3157        let imp = instance.imp();
3158        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3159        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3160        let callback = callback.map(|callback| {
3161            move |source: &T::Type, res: &AsyncResult| {
3162                callback(
3163                    source.upcast_ref::<Object>().to_glib_none().0,
3164                    res.to_glib_none().0,
3165                    user_data,
3166                )
3167            }
3168        });
3169
3170        imp.mount_mountable(
3171            from_glib(flags),
3172            mount_operation.as_ref(),
3173            cancellable.as_ref(),
3174            callback,
3175        );
3176    }
3177}
3178
3179unsafe extern "C" fn file_mount_mountable_finish<T: FileImpl>(
3180    file: *mut ffi::GFile,
3181    res: *mut ffi::GAsyncResult,
3182    error: *mut *mut glib::ffi::GError,
3183) -> *mut ffi::GFile {
3184    unsafe {
3185        let instance = &*(file as *mut T::Instance);
3186        let imp = instance.imp();
3187        let result: &AsyncResult = &from_glib_borrow(res);
3188
3189        let res_ = imp.mount_mountable_finish(result);
3190        match res_ {
3191            Ok(mounted) => mounted.to_glib_full(),
3192            Err(err) => {
3193                if !error.is_null() {
3194                    *error = err.to_glib_full()
3195                }
3196                std::ptr::null_mut()
3197            }
3198        }
3199    }
3200}
3201
3202unsafe extern "C" fn file_unmount_mountable<T: FileImpl>(
3203    file: *mut ffi::GFile,
3204    flags: ffi::GMountUnmountFlags,
3205    cancellable: *mut ffi::GCancellable,
3206    callback: ffi::GAsyncReadyCallback,
3207    user_data: glib::ffi::gpointer,
3208) {
3209    unsafe {
3210        let instance = &*(file as *mut T::Instance);
3211        let imp = instance.imp();
3212        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3213        let callback = callback.map(|callback| {
3214            move |source: &T::Type, res: &AsyncResult| {
3215                callback(
3216                    source.upcast_ref::<Object>().to_glib_none().0,
3217                    res.to_glib_none().0,
3218                    user_data,
3219                )
3220            }
3221        });
3222
3223        imp.unmount_mountable(from_glib(flags), cancellable.as_ref(), callback);
3224    }
3225}
3226
3227unsafe extern "C" fn file_unmount_mountable_finish<T: FileImpl>(
3228    file: *mut ffi::GFile,
3229    res: *mut ffi::GAsyncResult,
3230    error: *mut *mut glib::ffi::GError,
3231) -> glib::ffi::gboolean {
3232    unsafe {
3233        let instance = &*(file as *mut T::Instance);
3234        let imp = instance.imp();
3235        let result: &AsyncResult = &from_glib_borrow(res);
3236
3237        let res_ = imp.unmount_mountable_finish(result);
3238        match res_ {
3239            Ok(_) => true.into_glib(),
3240            Err(err) => {
3241                if !error.is_null() {
3242                    *error = err.to_glib_full()
3243                }
3244                false.into_glib()
3245            }
3246        }
3247    }
3248}
3249
3250unsafe extern "C" fn file_eject_mountable<T: FileImpl>(
3251    file: *mut ffi::GFile,
3252    flags: ffi::GMountUnmountFlags,
3253    cancellable: *mut ffi::GCancellable,
3254    callback: ffi::GAsyncReadyCallback,
3255    user_data: glib::ffi::gpointer,
3256) {
3257    unsafe {
3258        let instance = &*(file as *mut T::Instance);
3259        let imp = instance.imp();
3260        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3261        let callback = callback.map(|callback| {
3262            move |source: &T::Type, res: &AsyncResult| {
3263                callback(
3264                    source.upcast_ref::<Object>().to_glib_none().0,
3265                    res.to_glib_none().0,
3266                    user_data,
3267                )
3268            }
3269        });
3270
3271        imp.eject_mountable(from_glib(flags), cancellable.as_ref(), callback);
3272    }
3273}
3274
3275unsafe extern "C" fn file_eject_mountable_finish<T: FileImpl>(
3276    file: *mut ffi::GFile,
3277    res: *mut ffi::GAsyncResult,
3278    error: *mut *mut glib::ffi::GError,
3279) -> glib::ffi::gboolean {
3280    unsafe {
3281        let instance = &*(file as *mut T::Instance);
3282        let imp = instance.imp();
3283        let result: &AsyncResult = &from_glib_borrow(res);
3284
3285        let res_ = imp.eject_mountable_finish(result);
3286        match res_ {
3287            Ok(_) => true.into_glib(),
3288            Err(err) => {
3289                if !error.is_null() {
3290                    *error = err.to_glib_full()
3291                }
3292                false.into_glib()
3293            }
3294        }
3295    }
3296}
3297
3298unsafe extern "C" fn file_mount_enclosing_volume<T: FileImpl>(
3299    file: *mut ffi::GFile,
3300    flags: ffi::GMountMountFlags,
3301    mount_operation: *mut ffi::GMountOperation,
3302    cancellable: *mut ffi::GCancellable,
3303    callback: ffi::GAsyncReadyCallback,
3304    user_data: glib::ffi::gpointer,
3305) {
3306    unsafe {
3307        let instance = &*(file as *mut T::Instance);
3308        let imp = instance.imp();
3309        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3310        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3311        let callback = callback.map(|callback| {
3312            move |source: &T::Type, res: &AsyncResult| {
3313                callback(
3314                    source.upcast_ref::<Object>().to_glib_none().0,
3315                    res.to_glib_none().0,
3316                    user_data,
3317                )
3318            }
3319        });
3320
3321        imp.mount_enclosing_volume(
3322            from_glib(flags),
3323            mount_operation.as_ref(),
3324            cancellable.as_ref(),
3325            callback,
3326        );
3327    }
3328}
3329
3330unsafe extern "C" fn file_mount_enclosing_volume_finish<T: FileImpl>(
3331    file: *mut ffi::GFile,
3332    res: *mut ffi::GAsyncResult,
3333    error: *mut *mut glib::ffi::GError,
3334) -> glib::ffi::gboolean {
3335    unsafe {
3336        let instance = &*(file as *mut T::Instance);
3337        let imp = instance.imp();
3338        let result: &AsyncResult = &from_glib_borrow(res);
3339
3340        let res_ = imp.mount_enclosing_volume_finish(result);
3341        match res_ {
3342            Ok(_) => true.into_glib(),
3343            Err(err) => {
3344                if !error.is_null() {
3345                    *error = err.to_glib_full()
3346                }
3347                false.into_glib()
3348            }
3349        }
3350    }
3351}
3352
3353unsafe extern "C" fn file_monitor_dir<T: FileImpl>(
3354    file: *mut ffi::GFile,
3355    flags: ffi::GFileMonitorFlags,
3356    cancellable: *mut ffi::GCancellable,
3357    error: *mut *mut glib::ffi::GError,
3358) -> *mut ffi::GFileMonitor {
3359    unsafe {
3360        let instance = &*(file as *mut T::Instance);
3361        let imp = instance.imp();
3362        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3363
3364        let res = imp.monitor_dir(from_glib(flags), cancellable.as_ref());
3365        match res {
3366            Ok(monitor) => monitor.to_glib_full(),
3367            Err(err) => {
3368                if !error.is_null() {
3369                    *error = err.to_glib_full()
3370                }
3371                std::ptr::null_mut()
3372            }
3373        }
3374    }
3375}
3376
3377unsafe extern "C" fn file_monitor_file<T: FileImpl>(
3378    file: *mut ffi::GFile,
3379    flags: ffi::GFileMonitorFlags,
3380    cancellable: *mut ffi::GCancellable,
3381    error: *mut *mut glib::ffi::GError,
3382) -> *mut ffi::GFileMonitor {
3383    unsafe {
3384        let instance = &*(file as *mut T::Instance);
3385        let imp = instance.imp();
3386        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3387
3388        let res = imp.monitor_file(from_glib(flags), cancellable.as_ref());
3389        match res {
3390            Ok(monitor) => monitor.to_glib_full(),
3391            Err(err) => {
3392                if !error.is_null() {
3393                    *error = err.to_glib_full()
3394                }
3395                std::ptr::null_mut()
3396            }
3397        }
3398    }
3399}
3400
3401unsafe extern "C" fn file_open_readwrite<T: FileImpl>(
3402    file: *mut ffi::GFile,
3403    cancellable: *mut ffi::GCancellable,
3404    error: *mut *mut glib::ffi::GError,
3405) -> *mut ffi::GFileIOStream {
3406    unsafe {
3407        let instance = &*(file as *mut T::Instance);
3408        let imp = instance.imp();
3409        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3410
3411        let res = imp.open_readwrite(cancellable.as_ref());
3412        match res {
3413            Ok(io_stream) => io_stream.to_glib_full(),
3414            Err(err) => {
3415                if !error.is_null() {
3416                    *error = err.to_glib_full()
3417                }
3418                std::ptr::null_mut()
3419            }
3420        }
3421    }
3422}
3423
3424unsafe extern "C" fn file_create_readwrite<T: FileImpl>(
3425    file: *mut ffi::GFile,
3426    flags: ffi::GFileCreateFlags,
3427    cancellable: *mut ffi::GCancellable,
3428    error: *mut *mut glib::ffi::GError,
3429) -> *mut ffi::GFileIOStream {
3430    unsafe {
3431        let instance = &*(file as *mut T::Instance);
3432        let imp = instance.imp();
3433        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3434
3435        let res = imp.create_readwrite(from_glib(flags), cancellable.as_ref());
3436        match res {
3437            Ok(io_stream) => io_stream.to_glib_full(),
3438            Err(err) => {
3439                if !error.is_null() {
3440                    *error = err.to_glib_full()
3441                }
3442                std::ptr::null_mut()
3443            }
3444        }
3445    }
3446}
3447
3448unsafe extern "C" fn file_replace_readwrite<T: FileImpl>(
3449    file: *mut ffi::GFile,
3450    etag: *const c_char,
3451    make_backup: glib::ffi::gboolean,
3452    flags: ffi::GFileCreateFlags,
3453    cancellable: *mut ffi::GCancellable,
3454    error: *mut *mut glib::ffi::GError,
3455) -> *mut ffi::GFileIOStream {
3456    unsafe {
3457        let instance = &*(file as *mut T::Instance);
3458        let imp = instance.imp();
3459        let etag = Option::<GString>::from_glib_none(etag);
3460        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3461
3462        let res_ = imp.replace_readwrite(
3463            etag.as_ref().map(|etag| etag.as_str()),
3464            from_glib(make_backup),
3465            from_glib(flags),
3466            cancellable.as_ref(),
3467        );
3468        match res_ {
3469            Ok(io_stream) => io_stream.to_glib_full(),
3470            Err(err) => {
3471                if !error.is_null() {
3472                    *error = err.to_glib_full()
3473                }
3474                std::ptr::null_mut()
3475            }
3476        }
3477    }
3478}
3479
3480unsafe extern "C" fn file_start_mountable<T: FileImpl>(
3481    file: *mut ffi::GFile,
3482    flags: ffi::GDriveStartFlags,
3483    mount_operation: *mut ffi::GMountOperation,
3484    cancellable: *mut ffi::GCancellable,
3485    callback: ffi::GAsyncReadyCallback,
3486    user_data: glib::ffi::gpointer,
3487) {
3488    unsafe {
3489        let instance = &*(file as *mut T::Instance);
3490        let imp = instance.imp();
3491        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3492        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3493        let callback = callback.map(|callback| {
3494            move |source: &T::Type, res: &AsyncResult| {
3495                callback(
3496                    source.upcast_ref::<Object>().to_glib_none().0,
3497                    res.to_glib_none().0,
3498                    user_data,
3499                )
3500            }
3501        });
3502
3503        imp.start_mountable(
3504            from_glib(flags),
3505            mount_operation.as_ref(),
3506            cancellable.as_ref(),
3507            callback,
3508        );
3509    }
3510}
3511
3512unsafe extern "C" fn file_start_mountable_finish<T: FileImpl>(
3513    file: *mut ffi::GFile,
3514    res: *mut ffi::GAsyncResult,
3515    error: *mut *mut glib::ffi::GError,
3516) -> glib::ffi::gboolean {
3517    unsafe {
3518        let instance = &*(file as *mut T::Instance);
3519        let imp = instance.imp();
3520        let result: &AsyncResult = &from_glib_borrow(res);
3521
3522        let res_ = imp.start_mountable_finish(result);
3523        match res_ {
3524            Ok(_) => true.into_glib(),
3525            Err(err) => {
3526                if !error.is_null() {
3527                    *error = err.to_glib_full()
3528                }
3529                false.into_glib()
3530            }
3531        }
3532    }
3533}
3534
3535unsafe extern "C" fn file_stop_mountable<T: FileImpl>(
3536    file: *mut ffi::GFile,
3537    flags: ffi::GMountUnmountFlags,
3538    mount_operation: *mut ffi::GMountOperation,
3539    cancellable: *mut ffi::GCancellable,
3540    callback: ffi::GAsyncReadyCallback,
3541    user_data: glib::ffi::gpointer,
3542) {
3543    unsafe {
3544        let instance = &*(file as *mut T::Instance);
3545        let imp = instance.imp();
3546        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3547        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3548        let callback = callback.map(|callback| {
3549            move |source: &T::Type, res: &AsyncResult| {
3550                callback(
3551                    source.upcast_ref::<Object>().to_glib_none().0,
3552                    res.to_glib_none().0,
3553                    user_data,
3554                )
3555            }
3556        });
3557
3558        imp.stop_mountable(
3559            from_glib(flags),
3560            mount_operation.as_ref(),
3561            cancellable.as_ref(),
3562            callback,
3563        );
3564    }
3565}
3566
3567unsafe extern "C" fn file_stop_mountable_finish<T: FileImpl>(
3568    file: *mut ffi::GFile,
3569    res: *mut ffi::GAsyncResult,
3570    error: *mut *mut glib::ffi::GError,
3571) -> glib::ffi::gboolean {
3572    unsafe {
3573        let instance = &*(file as *mut T::Instance);
3574        let imp = instance.imp();
3575        let result: &AsyncResult = &from_glib_borrow(res);
3576
3577        let res_ = imp.stop_mountable_finish(result);
3578        match res_ {
3579            Ok(_) => true.into_glib(),
3580            Err(err) => {
3581                if !error.is_null() {
3582                    *error = err.to_glib_full()
3583                }
3584                false.into_glib()
3585            }
3586        }
3587    }
3588}
3589
3590unsafe extern "C" fn file_unmount_mountable_with_operation<T: FileImpl>(
3591    file: *mut ffi::GFile,
3592    flags: ffi::GMountUnmountFlags,
3593    mount_operation: *mut ffi::GMountOperation,
3594    cancellable: *mut ffi::GCancellable,
3595    callback: ffi::GAsyncReadyCallback,
3596    user_data: glib::ffi::gpointer,
3597) {
3598    unsafe {
3599        let instance = &*(file as *mut T::Instance);
3600        let imp = instance.imp();
3601        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3602        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3603        let callback = callback.map(|callback| {
3604            move |source: &T::Type, res: &AsyncResult| {
3605                callback(
3606                    source.upcast_ref::<Object>().to_glib_none().0,
3607                    res.to_glib_none().0,
3608                    user_data,
3609                )
3610            }
3611        });
3612
3613        imp.unmount_mountable_with_operation(
3614            from_glib(flags),
3615            mount_operation.as_ref(),
3616            cancellable.as_ref(),
3617            callback,
3618        );
3619    }
3620}
3621
3622unsafe extern "C" fn file_unmount_mountable_with_operation_finish<T: FileImpl>(
3623    file: *mut ffi::GFile,
3624    res: *mut ffi::GAsyncResult,
3625    error: *mut *mut glib::ffi::GError,
3626) -> glib::ffi::gboolean {
3627    unsafe {
3628        let instance = &*(file as *mut T::Instance);
3629        let imp = instance.imp();
3630        let result: &AsyncResult = &from_glib_borrow(res);
3631
3632        let res_ = imp.unmount_mountable_with_operation_finish(result);
3633        match res_ {
3634            Ok(_) => true.into_glib(),
3635            Err(err) => {
3636                if !error.is_null() {
3637                    *error = err.to_glib_full()
3638                }
3639                false.into_glib()
3640            }
3641        }
3642    }
3643}
3644
3645unsafe extern "C" fn file_eject_mountable_with_operation<T: FileImpl>(
3646    file: *mut ffi::GFile,
3647    flags: ffi::GMountUnmountFlags,
3648    mount_operation: *mut ffi::GMountOperation,
3649    cancellable: *mut ffi::GCancellable,
3650    callback: ffi::GAsyncReadyCallback,
3651    user_data: glib::ffi::gpointer,
3652) {
3653    unsafe {
3654        let instance = &*(file as *mut T::Instance);
3655        let imp = instance.imp();
3656        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3657        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3658        let callback = callback.map(|callback| {
3659            move |source: &T::Type, res: &AsyncResult| {
3660                callback(
3661                    source.upcast_ref::<Object>().to_glib_none().0,
3662                    res.to_glib_none().0,
3663                    user_data,
3664                )
3665            }
3666        });
3667
3668        imp.eject_mountable_with_operation(
3669            from_glib(flags),
3670            mount_operation.as_ref(),
3671            cancellable.as_ref(),
3672            callback,
3673        );
3674    }
3675}
3676
3677unsafe extern "C" fn file_eject_mountable_with_operation_finish<T: FileImpl>(
3678    file: *mut ffi::GFile,
3679    res: *mut ffi::GAsyncResult,
3680    error: *mut *mut glib::ffi::GError,
3681) -> glib::ffi::gboolean {
3682    unsafe {
3683        let instance = &*(file as *mut T::Instance);
3684        let imp = instance.imp();
3685        let result: &AsyncResult = &from_glib_borrow(res);
3686
3687        let res_ = imp.eject_mountable_with_operation_finish(result);
3688        match res_ {
3689            Ok(_) => true.into_glib(),
3690            Err(err) => {
3691                if !error.is_null() {
3692                    *error = err.to_glib_full()
3693                }
3694                false.into_glib()
3695            }
3696        }
3697    }
3698}
3699
3700unsafe extern "C" fn file_poll_mountable<T: FileImpl>(
3701    file: *mut ffi::GFile,
3702    cancellable: *mut ffi::GCancellable,
3703    callback: ffi::GAsyncReadyCallback,
3704    user_data: glib::ffi::gpointer,
3705) {
3706    unsafe {
3707        let instance = &*(file as *mut T::Instance);
3708        let imp = instance.imp();
3709        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3710        let callback = callback.map(|callback| {
3711            move |source: &T::Type, res: &AsyncResult| {
3712                callback(
3713                    source.upcast_ref::<Object>().to_glib_none().0,
3714                    res.to_glib_none().0,
3715                    user_data,
3716                )
3717            }
3718        });
3719
3720        imp.poll_mountable(cancellable.as_ref(), callback)
3721    }
3722}
3723
3724unsafe extern "C" fn file_poll_mountable_finish<T: FileImpl>(
3725    file: *mut ffi::GFile,
3726    res: *mut ffi::GAsyncResult,
3727    error: *mut *mut glib::ffi::GError,
3728) -> glib::ffi::gboolean {
3729    unsafe {
3730        let instance = &*(file as *mut T::Instance);
3731        let imp = instance.imp();
3732        let result: &AsyncResult = &from_glib_borrow(res);
3733
3734        let res_ = imp.poll_mountable_finish(result);
3735        match res_ {
3736            Ok(_) => true.into_glib(),
3737            Err(err) => {
3738                if !error.is_null() {
3739                    *error = err.to_glib_full()
3740                }
3741                false.into_glib()
3742            }
3743        }
3744    }
3745}
3746
3747unsafe extern "C" fn file_measure_disk_usage<T: FileImpl>(
3748    file: *mut ffi::GFile,
3749    flags: ffi::GFileMeasureFlags,
3750    cancellable: *mut ffi::GCancellable,
3751    progress_callback: ffi::GFileMeasureProgressCallback,
3752    progress_callback_data: glib::ffi::gpointer,
3753    disk_usage: *mut u64,
3754    num_dirs: *mut u64,
3755    num_files: *mut u64,
3756    error: *mut *mut glib::ffi::GError,
3757) -> glib::ffi::gboolean {
3758    unsafe {
3759        let instance = &*(file as *mut T::Instance);
3760        let imp = instance.imp();
3761        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3762        let mut progress_callback = progress_callback.map(|callback| {
3763            move |reporting: bool, current_size: u64, num_dirs: u64, num_files: u64| {
3764                callback(
3765                    reporting.into_glib(),
3766                    current_size,
3767                    num_dirs,
3768                    num_files,
3769                    progress_callback_data,
3770                )
3771            }
3772        });
3773        let progress_callback_ref = progress_callback
3774            .as_mut()
3775            .map(|f| f as &mut dyn FnMut(bool, u64, u64, u64));
3776
3777        let res = imp.measure_disk_usage(
3778            from_glib(flags),
3779            cancellable.as_ref(),
3780            progress_callback_ref,
3781        );
3782        match res {
3783            Ok((disk_usage_, num_dirs_, num_files_)) => {
3784                if !disk_usage.is_null() {
3785                    *disk_usage = disk_usage_
3786                }
3787                if !num_dirs.is_null() {
3788                    *num_dirs = num_dirs_
3789                }
3790                if !num_files.is_null() {
3791                    *num_files = num_files_
3792                }
3793                true.into_glib()
3794            }
3795            Err(err) => {
3796                if !error.is_null() {
3797                    *error = err.to_glib_full()
3798                }
3799                false.into_glib()
3800            }
3801        }
3802    }
3803}
3804
3805#[cfg(feature = "v2_84")]
3806unsafe extern "C" fn file_query_exists<T: FileImpl>(
3807    file: *mut ffi::GFile,
3808    cancellable: *mut ffi::GCancellable,
3809) -> glib::ffi::gboolean {
3810    let instance = &*(file as *mut T::Instance);
3811    let imp = instance.imp();
3812    let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3813
3814    let res = imp.query_exists(cancellable.as_ref());
3815    res.into_glib()
3816}
3817
3818#[cfg(test)]
3819mod tests;