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        glib::ffi::g_free(basename as *mut _);
2617
2618        let res = imp.child_for_display_name(&GString::from_glib_borrow(display_name));
2619        match res {
2620            Ok(child) => child.to_glib_full(),
2621            Err(err) => {
2622                if !error.is_null() {
2623                    *error = err.to_glib_full()
2624                }
2625                std::ptr::null_mut()
2626            }
2627        }
2628    }
2629}
2630
2631unsafe extern "C" fn file_enumerate_children<T: FileImpl>(
2632    file: *mut ffi::GFile,
2633    attributes: *const c_char,
2634    flags: ffi::GFileQueryInfoFlags,
2635    cancellable: *mut ffi::GCancellable,
2636    error: *mut *mut glib::ffi::GError,
2637) -> *mut ffi::GFileEnumerator {
2638    unsafe {
2639        let instance = &*(file as *mut T::Instance);
2640        let imp = instance.imp();
2641        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2642
2643        let res = imp.enumerate_children(
2644            &GString::from_glib_borrow(attributes),
2645            from_glib(flags),
2646            cancellable.as_ref(),
2647        );
2648        match res {
2649            Ok(enumerator) => enumerator.to_glib_full(),
2650            Err(err) => {
2651                if !error.is_null() {
2652                    *error = err.to_glib_full()
2653                }
2654                std::ptr::null_mut()
2655            }
2656        }
2657    }
2658}
2659
2660unsafe extern "C" fn file_query_info<T: FileImpl>(
2661    file: *mut ffi::GFile,
2662    attributes: *const c_char,
2663    flags: ffi::GFileQueryInfoFlags,
2664    cancellable: *mut ffi::GCancellable,
2665    error: *mut *mut glib::ffi::GError,
2666) -> *mut ffi::GFileInfo {
2667    unsafe {
2668        let instance = &*(file as *mut T::Instance);
2669        let imp = instance.imp();
2670        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2671
2672        let res = imp.query_info(
2673            &GString::from_glib_borrow(attributes),
2674            from_glib(flags),
2675            cancellable.as_ref(),
2676        );
2677        match res {
2678            Ok(file_info) => file_info.to_glib_full(),
2679            Err(err) => {
2680                if !error.is_null() {
2681                    *error = err.to_glib_full()
2682                }
2683                std::ptr::null_mut()
2684            }
2685        }
2686    }
2687}
2688
2689unsafe extern "C" fn file_query_filesystem_info<T: FileImpl>(
2690    file: *mut ffi::GFile,
2691    attributes: *const c_char,
2692    cancellable: *mut ffi::GCancellable,
2693    error: *mut *mut glib::ffi::GError,
2694) -> *mut ffi::GFileInfo {
2695    unsafe {
2696        let instance = &*(file as *mut T::Instance);
2697        let imp = instance.imp();
2698        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2699
2700        let res =
2701            imp.query_filesystem_info(&GString::from_glib_borrow(attributes), cancellable.as_ref());
2702        match res {
2703            Ok(file_info) => file_info.to_glib_full(),
2704            Err(err) => {
2705                if !error.is_null() {
2706                    *error = err.to_glib_full()
2707                }
2708                std::ptr::null_mut()
2709            }
2710        }
2711    }
2712}
2713
2714unsafe extern "C" fn file_find_enclosing_mount<T: FileImpl>(
2715    file: *mut ffi::GFile,
2716    cancellable: *mut ffi::GCancellable,
2717    error: *mut *mut glib::ffi::GError,
2718) -> *mut ffi::GMount {
2719    unsafe {
2720        let instance = &*(file as *mut T::Instance);
2721        let imp = instance.imp();
2722        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2723
2724        let res = imp.find_enclosing_mount(cancellable.as_ref());
2725        match res {
2726            Ok(mount) => mount.to_glib_full(),
2727            Err(err) => {
2728                if !error.is_null() {
2729                    *error = err.to_glib_full()
2730                }
2731                std::ptr::null_mut()
2732            }
2733        }
2734    }
2735}
2736
2737unsafe extern "C" fn file_set_display_name<T: FileImpl>(
2738    file: *mut ffi::GFile,
2739    display_name: *const c_char,
2740    cancellable: *mut ffi::GCancellable,
2741    error: *mut *mut glib::ffi::GError,
2742) -> *mut ffi::GFile {
2743    unsafe {
2744        let instance = &*(file as *mut T::Instance);
2745        let imp = instance.imp();
2746        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2747
2748        let res = imp.set_display_name(
2749            &GString::from_glib_borrow(display_name),
2750            cancellable.as_ref(),
2751        );
2752        match res {
2753            Ok(renamed_file) => renamed_file.to_glib_full(),
2754            Err(err) => {
2755                if !error.is_null() {
2756                    *error = err.to_glib_full()
2757                }
2758                std::ptr::null_mut()
2759            }
2760        }
2761    }
2762}
2763
2764unsafe extern "C" fn file_query_settable_attributes<T: FileImpl>(
2765    file: *mut ffi::GFile,
2766    cancellable: *mut ffi::GCancellable,
2767    error: *mut *mut glib::ffi::GError,
2768) -> *mut ffi::GFileAttributeInfoList {
2769    unsafe {
2770        let instance = &*(file as *mut T::Instance);
2771        let imp = instance.imp();
2772        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2773
2774        let res = imp.query_settable_attributes(cancellable.as_ref());
2775        match res {
2776            Ok(settable_attributes) => settable_attributes.to_glib_full(),
2777            Err(err) => {
2778                if !error.is_null() {
2779                    *error = err.to_glib_full()
2780                }
2781                std::ptr::null_mut()
2782            }
2783        }
2784    }
2785}
2786
2787unsafe extern "C" fn file_query_writable_namespaces<T: FileImpl>(
2788    file: *mut ffi::GFile,
2789    cancellable: *mut ffi::GCancellable,
2790    error: *mut *mut glib::ffi::GError,
2791) -> *mut ffi::GFileAttributeInfoList {
2792    unsafe {
2793        let instance = &*(file as *mut T::Instance);
2794        let imp = instance.imp();
2795        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2796
2797        let res = imp.query_writable_namespaces(cancellable.as_ref());
2798        match res {
2799            Ok(writable_namespaces) => writable_namespaces.to_glib_full(),
2800            Err(err) => {
2801                if !error.is_null() {
2802                    *error = err.to_glib_full()
2803                }
2804                std::ptr::null_mut()
2805            }
2806        }
2807    }
2808}
2809
2810unsafe extern "C" fn file_set_attribute<T: FileImpl>(
2811    file: *mut ffi::GFile,
2812    attribute: *const c_char,
2813    type_: ffi::GFileAttributeType,
2814    value_p: glib::ffi::gpointer,
2815    flags: ffi::GFileQueryInfoFlags,
2816    cancellable: *mut ffi::GCancellable,
2817    error: *mut *mut glib::ffi::GError,
2818) -> glib::ffi::gboolean {
2819    unsafe {
2820        let instance = &*(file as *mut T::Instance);
2821        let imp = instance.imp();
2822        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2823
2824        let res_ = imp.set_attribute(
2825            &GString::from_glib_borrow(attribute),
2826            FileAttributeValue::for_pointer(from_glib(type_), value_p),
2827            from_glib(flags),
2828            cancellable.as_ref(),
2829        );
2830
2831        match res_ {
2832            Ok(_) => true.into_glib(),
2833            Err(err) => {
2834                if !error.is_null() {
2835                    *error = err.to_glib_full()
2836                }
2837                false.into_glib()
2838            }
2839        }
2840    }
2841}
2842
2843unsafe extern "C" fn file_set_attributes_from_info<T: FileImpl>(
2844    file: *mut ffi::GFile,
2845    info: *mut ffi::GFileInfo,
2846    flags: ffi::GFileQueryInfoFlags,
2847    cancellable: *mut ffi::GCancellable,
2848    error: *mut *mut glib::ffi::GError,
2849) -> glib::ffi::gboolean {
2850    unsafe {
2851        let instance = &*(file as *mut T::Instance);
2852        let imp = instance.imp();
2853        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2854
2855        let res_ = imp.set_attributes_from_info(
2856            &from_glib_borrow(info),
2857            from_glib(flags),
2858            cancellable.as_ref(),
2859        );
2860        match res_ {
2861            Ok(_) => true.into_glib(),
2862            Err(err) => {
2863                if !error.is_null() {
2864                    *error = err.to_glib_full()
2865                }
2866                false.into_glib()
2867            }
2868        }
2869    }
2870}
2871
2872unsafe extern "C" fn file_read_fn<T: FileImpl>(
2873    file: *mut ffi::GFile,
2874    cancellable: *mut ffi::GCancellable,
2875    error: *mut *mut glib::ffi::GError,
2876) -> *mut ffi::GFileInputStream {
2877    unsafe {
2878        let instance = &*(file as *mut T::Instance);
2879        let imp = instance.imp();
2880        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2881
2882        let res_ = imp.read_fn(cancellable.as_ref());
2883        match res_ {
2884            Ok(input_stream) => input_stream.to_glib_full(),
2885            Err(err) => {
2886                if !error.is_null() {
2887                    *error = err.to_glib_full()
2888                }
2889                std::ptr::null_mut()
2890            }
2891        }
2892    }
2893}
2894
2895unsafe extern "C" fn file_append_to<T: FileImpl>(
2896    file: *mut ffi::GFile,
2897    flags: ffi::GFileCreateFlags,
2898    cancellable: *mut ffi::GCancellable,
2899    error: *mut *mut glib::ffi::GError,
2900) -> *mut ffi::GFileOutputStream {
2901    unsafe {
2902        let instance = &*(file as *mut T::Instance);
2903        let imp = instance.imp();
2904        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2905
2906        let res_ = imp.append_to(from_glib(flags), cancellable.as_ref());
2907        match res_ {
2908            Ok(output_stream) => output_stream.to_glib_full(),
2909            Err(err) => {
2910                if !error.is_null() {
2911                    *error = err.to_glib_full()
2912                }
2913                std::ptr::null_mut()
2914            }
2915        }
2916    }
2917}
2918
2919unsafe extern "C" fn file_create<T: FileImpl>(
2920    file: *mut ffi::GFile,
2921    flags: ffi::GFileCreateFlags,
2922    cancellable: *mut ffi::GCancellable,
2923    error: *mut *mut glib::ffi::GError,
2924) -> *mut ffi::GFileOutputStream {
2925    unsafe {
2926        let instance = &*(file as *mut T::Instance);
2927        let imp = instance.imp();
2928        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2929
2930        let res_ = imp.create(from_glib(flags), cancellable.as_ref());
2931        match res_ {
2932            Ok(output_stream) => output_stream.to_glib_full(),
2933            Err(err) => {
2934                if !error.is_null() {
2935                    *error = err.to_glib_full()
2936                }
2937                std::ptr::null_mut()
2938            }
2939        }
2940    }
2941}
2942
2943unsafe extern "C" fn file_replace<T: FileImpl>(
2944    file: *mut ffi::GFile,
2945    etag: *const c_char,
2946    make_backup: glib::ffi::gboolean,
2947    flags: ffi::GFileCreateFlags,
2948    cancellable: *mut ffi::GCancellable,
2949    error: *mut *mut glib::ffi::GError,
2950) -> *mut ffi::GFileOutputStream {
2951    unsafe {
2952        let instance = &*(file as *mut T::Instance);
2953        let imp = instance.imp();
2954        let etag = Option::<GString>::from_glib_none(etag);
2955        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2956
2957        let res_ = imp.replace(
2958            etag.as_ref().map(|etag| etag.as_str()),
2959            from_glib(make_backup),
2960            from_glib(flags),
2961            cancellable.as_ref(),
2962        );
2963        match res_ {
2964            Ok(output_stream) => output_stream.to_glib_full(),
2965            Err(err) => {
2966                if !error.is_null() {
2967                    *error = err.to_glib_full()
2968                }
2969                std::ptr::null_mut()
2970            }
2971        }
2972    }
2973}
2974
2975unsafe extern "C" fn file_delete_file<T: FileImpl>(
2976    file: *mut ffi::GFile,
2977    cancellable: *mut ffi::GCancellable,
2978    error: *mut *mut glib::ffi::GError,
2979) -> glib::ffi::gboolean {
2980    unsafe {
2981        let instance = &*(file as *mut T::Instance);
2982        let imp = instance.imp();
2983        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
2984
2985        let res = imp.delete(cancellable.as_ref());
2986        match res {
2987            Ok(_) => true.into_glib(),
2988            Err(err) => {
2989                if !error.is_null() {
2990                    *error = err.to_glib_full()
2991                }
2992                false.into_glib()
2993            }
2994        }
2995    }
2996}
2997
2998unsafe extern "C" fn file_trash<T: FileImpl>(
2999    file: *mut ffi::GFile,
3000    cancellable: *mut ffi::GCancellable,
3001    error: *mut *mut glib::ffi::GError,
3002) -> glib::ffi::gboolean {
3003    unsafe {
3004        let instance = &*(file as *mut T::Instance);
3005        let imp = instance.imp();
3006        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3007
3008        let res = imp.trash(cancellable.as_ref());
3009        match res {
3010            Ok(_) => true.into_glib(),
3011            Err(err) => {
3012                if !error.is_null() {
3013                    *error = err.to_glib_full()
3014                }
3015                false.into_glib()
3016            }
3017        }
3018    }
3019}
3020
3021unsafe extern "C" fn file_make_directory<T: FileImpl>(
3022    file: *mut ffi::GFile,
3023    cancellable: *mut ffi::GCancellable,
3024    error: *mut *mut glib::ffi::GError,
3025) -> glib::ffi::gboolean {
3026    unsafe {
3027        let instance = &*(file as *mut T::Instance);
3028        let imp = instance.imp();
3029        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3030
3031        let res = imp.make_directory(cancellable.as_ref());
3032        match res {
3033            Ok(_) => true.into_glib(),
3034            Err(err) => {
3035                if !error.is_null() {
3036                    *error = err.to_glib_full()
3037                }
3038                false.into_glib()
3039            }
3040        }
3041    }
3042}
3043
3044unsafe extern "C" fn file_make_symbolic_link<T: FileImpl>(
3045    file: *mut ffi::GFile,
3046    symlink_value: *const c_char,
3047    cancellable: *mut ffi::GCancellable,
3048    error: *mut *mut glib::ffi::GError,
3049) -> glib::ffi::gboolean {
3050    unsafe {
3051        let instance = &*(file as *mut T::Instance);
3052        let imp = instance.imp();
3053        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3054
3055        let res = imp.make_symbolic_link(
3056            GString::from_glib_borrow(symlink_value).as_ref(),
3057            cancellable.as_ref(),
3058        );
3059        match res {
3060            Ok(_) => true.into_glib(),
3061            Err(err) => {
3062                if !error.is_null() {
3063                    *error = err.to_glib_full()
3064                }
3065                false.into_glib()
3066            }
3067        }
3068    }
3069}
3070
3071unsafe extern "C" fn file_copy<T: FileImpl>(
3072    source: *mut ffi::GFile,
3073    destination: *mut ffi::GFile,
3074    flags: ffi::GFileCopyFlags,
3075    cancellable: *mut ffi::GCancellable,
3076    progress_callback: ffi::GFileProgressCallback,
3077    progress_callback_data: glib::ffi::gpointer,
3078    error: *mut *mut glib::ffi::GError,
3079) -> glib::ffi::gboolean {
3080    unsafe {
3081        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3082        let mut progress_callback = progress_callback.map(|callback| {
3083            move |current_num_bytes, total_num_bytes| {
3084                callback(current_num_bytes, total_num_bytes, progress_callback_data)
3085            }
3086        });
3087        let progress_callback_ref = progress_callback
3088            .as_mut()
3089            .map(|f| f as &mut dyn FnMut(i64, i64));
3090
3091        let res = T::copy(
3092            &from_glib_borrow(source),
3093            &from_glib_borrow(destination),
3094            from_glib(flags),
3095            cancellable.as_ref(),
3096            progress_callback_ref,
3097        );
3098        match res {
3099            Ok(_) => true.into_glib(),
3100            Err(err) => {
3101                if !error.is_null() {
3102                    *error = err.to_glib_full()
3103                }
3104                false.into_glib()
3105            }
3106        }
3107    }
3108}
3109
3110unsafe extern "C" fn file_move<T: FileImpl>(
3111    source: *mut ffi::GFile,
3112    destination: *mut ffi::GFile,
3113    flags: ffi::GFileCopyFlags,
3114    cancellable: *mut ffi::GCancellable,
3115    progress_callback: ffi::GFileProgressCallback,
3116    progress_callback_data: glib::ffi::gpointer,
3117    error: *mut *mut glib::ffi::GError,
3118) -> glib::ffi::gboolean {
3119    unsafe {
3120        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3121        let mut progress_callback = progress_callback.map(|callback| {
3122            move |current_num_bytes, total_num_bytes| {
3123                callback(current_num_bytes, total_num_bytes, progress_callback_data)
3124            }
3125        });
3126        let progress_callback_ref = progress_callback
3127            .as_mut()
3128            .map(|f| f as &mut dyn FnMut(i64, i64));
3129
3130        let res = T::move_(
3131            &from_glib_borrow(source),
3132            &from_glib_borrow(destination),
3133            from_glib(flags),
3134            cancellable.as_ref(),
3135            progress_callback_ref,
3136        );
3137        match res {
3138            Ok(_) => true.into_glib(),
3139            Err(err) => {
3140                if !error.is_null() {
3141                    *error = err.to_glib_full()
3142                }
3143                false.into_glib()
3144            }
3145        }
3146    }
3147}
3148
3149unsafe extern "C" fn file_mount_mountable<T: FileImpl>(
3150    file: *mut ffi::GFile,
3151    flags: ffi::GMountMountFlags,
3152    mount_operation: *mut ffi::GMountOperation,
3153    cancellable: *mut ffi::GCancellable,
3154    callback: ffi::GAsyncReadyCallback,
3155    user_data: glib::ffi::gpointer,
3156) {
3157    unsafe {
3158        let instance = &*(file as *mut T::Instance);
3159        let imp = instance.imp();
3160        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3161        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3162        let callback = callback.map(|callback| {
3163            move |source: &T::Type, res: &AsyncResult| {
3164                callback(
3165                    source.upcast_ref::<Object>().to_glib_none().0,
3166                    res.to_glib_none().0,
3167                    user_data,
3168                )
3169            }
3170        });
3171
3172        imp.mount_mountable(
3173            from_glib(flags),
3174            mount_operation.as_ref(),
3175            cancellable.as_ref(),
3176            callback,
3177        );
3178    }
3179}
3180
3181unsafe extern "C" fn file_mount_mountable_finish<T: FileImpl>(
3182    file: *mut ffi::GFile,
3183    res: *mut ffi::GAsyncResult,
3184    error: *mut *mut glib::ffi::GError,
3185) -> *mut ffi::GFile {
3186    unsafe {
3187        let instance = &*(file as *mut T::Instance);
3188        let imp = instance.imp();
3189        let result: &AsyncResult = &from_glib_borrow(res);
3190
3191        let res_ = imp.mount_mountable_finish(result);
3192        match res_ {
3193            Ok(mounted) => mounted.to_glib_full(),
3194            Err(err) => {
3195                if !error.is_null() {
3196                    *error = err.to_glib_full()
3197                }
3198                std::ptr::null_mut()
3199            }
3200        }
3201    }
3202}
3203
3204unsafe extern "C" fn file_unmount_mountable<T: FileImpl>(
3205    file: *mut ffi::GFile,
3206    flags: ffi::GMountUnmountFlags,
3207    cancellable: *mut ffi::GCancellable,
3208    callback: ffi::GAsyncReadyCallback,
3209    user_data: glib::ffi::gpointer,
3210) {
3211    unsafe {
3212        let instance = &*(file as *mut T::Instance);
3213        let imp = instance.imp();
3214        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3215        let callback = callback.map(|callback| {
3216            move |source: &T::Type, res: &AsyncResult| {
3217                callback(
3218                    source.upcast_ref::<Object>().to_glib_none().0,
3219                    res.to_glib_none().0,
3220                    user_data,
3221                )
3222            }
3223        });
3224
3225        imp.unmount_mountable(from_glib(flags), cancellable.as_ref(), callback);
3226    }
3227}
3228
3229unsafe extern "C" fn file_unmount_mountable_finish<T: FileImpl>(
3230    file: *mut ffi::GFile,
3231    res: *mut ffi::GAsyncResult,
3232    error: *mut *mut glib::ffi::GError,
3233) -> glib::ffi::gboolean {
3234    unsafe {
3235        let instance = &*(file as *mut T::Instance);
3236        let imp = instance.imp();
3237        let result: &AsyncResult = &from_glib_borrow(res);
3238
3239        let res_ = imp.unmount_mountable_finish(result);
3240        match res_ {
3241            Ok(_) => true.into_glib(),
3242            Err(err) => {
3243                if !error.is_null() {
3244                    *error = err.to_glib_full()
3245                }
3246                false.into_glib()
3247            }
3248        }
3249    }
3250}
3251
3252unsafe extern "C" fn file_eject_mountable<T: FileImpl>(
3253    file: *mut ffi::GFile,
3254    flags: ffi::GMountUnmountFlags,
3255    cancellable: *mut ffi::GCancellable,
3256    callback: ffi::GAsyncReadyCallback,
3257    user_data: glib::ffi::gpointer,
3258) {
3259    unsafe {
3260        let instance = &*(file as *mut T::Instance);
3261        let imp = instance.imp();
3262        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3263        let callback = callback.map(|callback| {
3264            move |source: &T::Type, res: &AsyncResult| {
3265                callback(
3266                    source.upcast_ref::<Object>().to_glib_none().0,
3267                    res.to_glib_none().0,
3268                    user_data,
3269                )
3270            }
3271        });
3272
3273        imp.eject_mountable(from_glib(flags), cancellable.as_ref(), callback);
3274    }
3275}
3276
3277unsafe extern "C" fn file_eject_mountable_finish<T: FileImpl>(
3278    file: *mut ffi::GFile,
3279    res: *mut ffi::GAsyncResult,
3280    error: *mut *mut glib::ffi::GError,
3281) -> glib::ffi::gboolean {
3282    unsafe {
3283        let instance = &*(file as *mut T::Instance);
3284        let imp = instance.imp();
3285        let result: &AsyncResult = &from_glib_borrow(res);
3286
3287        let res_ = imp.eject_mountable_finish(result);
3288        match res_ {
3289            Ok(_) => true.into_glib(),
3290            Err(err) => {
3291                if !error.is_null() {
3292                    *error = err.to_glib_full()
3293                }
3294                false.into_glib()
3295            }
3296        }
3297    }
3298}
3299
3300unsafe extern "C" fn file_mount_enclosing_volume<T: FileImpl>(
3301    file: *mut ffi::GFile,
3302    flags: ffi::GMountMountFlags,
3303    mount_operation: *mut ffi::GMountOperation,
3304    cancellable: *mut ffi::GCancellable,
3305    callback: ffi::GAsyncReadyCallback,
3306    user_data: glib::ffi::gpointer,
3307) {
3308    unsafe {
3309        let instance = &*(file as *mut T::Instance);
3310        let imp = instance.imp();
3311        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3312        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3313        let callback = callback.map(|callback| {
3314            move |source: &T::Type, res: &AsyncResult| {
3315                callback(
3316                    source.upcast_ref::<Object>().to_glib_none().0,
3317                    res.to_glib_none().0,
3318                    user_data,
3319                )
3320            }
3321        });
3322
3323        imp.mount_enclosing_volume(
3324            from_glib(flags),
3325            mount_operation.as_ref(),
3326            cancellable.as_ref(),
3327            callback,
3328        );
3329    }
3330}
3331
3332unsafe extern "C" fn file_mount_enclosing_volume_finish<T: FileImpl>(
3333    file: *mut ffi::GFile,
3334    res: *mut ffi::GAsyncResult,
3335    error: *mut *mut glib::ffi::GError,
3336) -> glib::ffi::gboolean {
3337    unsafe {
3338        let instance = &*(file as *mut T::Instance);
3339        let imp = instance.imp();
3340        let result: &AsyncResult = &from_glib_borrow(res);
3341
3342        let res_ = imp.mount_enclosing_volume_finish(result);
3343        match res_ {
3344            Ok(_) => true.into_glib(),
3345            Err(err) => {
3346                if !error.is_null() {
3347                    *error = err.to_glib_full()
3348                }
3349                false.into_glib()
3350            }
3351        }
3352    }
3353}
3354
3355unsafe extern "C" fn file_monitor_dir<T: FileImpl>(
3356    file: *mut ffi::GFile,
3357    flags: ffi::GFileMonitorFlags,
3358    cancellable: *mut ffi::GCancellable,
3359    error: *mut *mut glib::ffi::GError,
3360) -> *mut ffi::GFileMonitor {
3361    unsafe {
3362        let instance = &*(file as *mut T::Instance);
3363        let imp = instance.imp();
3364        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3365
3366        let res = imp.monitor_dir(from_glib(flags), cancellable.as_ref());
3367        match res {
3368            Ok(monitor) => monitor.to_glib_full(),
3369            Err(err) => {
3370                if !error.is_null() {
3371                    *error = err.to_glib_full()
3372                }
3373                std::ptr::null_mut()
3374            }
3375        }
3376    }
3377}
3378
3379unsafe extern "C" fn file_monitor_file<T: FileImpl>(
3380    file: *mut ffi::GFile,
3381    flags: ffi::GFileMonitorFlags,
3382    cancellable: *mut ffi::GCancellable,
3383    error: *mut *mut glib::ffi::GError,
3384) -> *mut ffi::GFileMonitor {
3385    unsafe {
3386        let instance = &*(file as *mut T::Instance);
3387        let imp = instance.imp();
3388        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3389
3390        let res = imp.monitor_file(from_glib(flags), cancellable.as_ref());
3391        match res {
3392            Ok(monitor) => monitor.to_glib_full(),
3393            Err(err) => {
3394                if !error.is_null() {
3395                    *error = err.to_glib_full()
3396                }
3397                std::ptr::null_mut()
3398            }
3399        }
3400    }
3401}
3402
3403unsafe extern "C" fn file_open_readwrite<T: FileImpl>(
3404    file: *mut ffi::GFile,
3405    cancellable: *mut ffi::GCancellable,
3406    error: *mut *mut glib::ffi::GError,
3407) -> *mut ffi::GFileIOStream {
3408    unsafe {
3409        let instance = &*(file as *mut T::Instance);
3410        let imp = instance.imp();
3411        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3412
3413        let res = imp.open_readwrite(cancellable.as_ref());
3414        match res {
3415            Ok(io_stream) => io_stream.to_glib_full(),
3416            Err(err) => {
3417                if !error.is_null() {
3418                    *error = err.to_glib_full()
3419                }
3420                std::ptr::null_mut()
3421            }
3422        }
3423    }
3424}
3425
3426unsafe extern "C" fn file_create_readwrite<T: FileImpl>(
3427    file: *mut ffi::GFile,
3428    flags: ffi::GFileCreateFlags,
3429    cancellable: *mut ffi::GCancellable,
3430    error: *mut *mut glib::ffi::GError,
3431) -> *mut ffi::GFileIOStream {
3432    unsafe {
3433        let instance = &*(file as *mut T::Instance);
3434        let imp = instance.imp();
3435        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3436
3437        let res = imp.create_readwrite(from_glib(flags), cancellable.as_ref());
3438        match res {
3439            Ok(io_stream) => io_stream.to_glib_full(),
3440            Err(err) => {
3441                if !error.is_null() {
3442                    *error = err.to_glib_full()
3443                }
3444                std::ptr::null_mut()
3445            }
3446        }
3447    }
3448}
3449
3450unsafe extern "C" fn file_replace_readwrite<T: FileImpl>(
3451    file: *mut ffi::GFile,
3452    etag: *const c_char,
3453    make_backup: glib::ffi::gboolean,
3454    flags: ffi::GFileCreateFlags,
3455    cancellable: *mut ffi::GCancellable,
3456    error: *mut *mut glib::ffi::GError,
3457) -> *mut ffi::GFileIOStream {
3458    unsafe {
3459        let instance = &*(file as *mut T::Instance);
3460        let imp = instance.imp();
3461        let etag = Option::<GString>::from_glib_none(etag);
3462        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3463
3464        let res_ = imp.replace_readwrite(
3465            etag.as_ref().map(|etag| etag.as_str()),
3466            from_glib(make_backup),
3467            from_glib(flags),
3468            cancellable.as_ref(),
3469        );
3470        match res_ {
3471            Ok(io_stream) => io_stream.to_glib_full(),
3472            Err(err) => {
3473                if !error.is_null() {
3474                    *error = err.to_glib_full()
3475                }
3476                std::ptr::null_mut()
3477            }
3478        }
3479    }
3480}
3481
3482unsafe extern "C" fn file_start_mountable<T: FileImpl>(
3483    file: *mut ffi::GFile,
3484    flags: ffi::GDriveStartFlags,
3485    mount_operation: *mut ffi::GMountOperation,
3486    cancellable: *mut ffi::GCancellable,
3487    callback: ffi::GAsyncReadyCallback,
3488    user_data: glib::ffi::gpointer,
3489) {
3490    unsafe {
3491        let instance = &*(file as *mut T::Instance);
3492        let imp = instance.imp();
3493        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3494        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3495        let callback = callback.map(|callback| {
3496            move |source: &T::Type, res: &AsyncResult| {
3497                callback(
3498                    source.upcast_ref::<Object>().to_glib_none().0,
3499                    res.to_glib_none().0,
3500                    user_data,
3501                )
3502            }
3503        });
3504
3505        imp.start_mountable(
3506            from_glib(flags),
3507            mount_operation.as_ref(),
3508            cancellable.as_ref(),
3509            callback,
3510        );
3511    }
3512}
3513
3514unsafe extern "C" fn file_start_mountable_finish<T: FileImpl>(
3515    file: *mut ffi::GFile,
3516    res: *mut ffi::GAsyncResult,
3517    error: *mut *mut glib::ffi::GError,
3518) -> glib::ffi::gboolean {
3519    unsafe {
3520        let instance = &*(file as *mut T::Instance);
3521        let imp = instance.imp();
3522        let result: &AsyncResult = &from_glib_borrow(res);
3523
3524        let res_ = imp.start_mountable_finish(result);
3525        match res_ {
3526            Ok(_) => true.into_glib(),
3527            Err(err) => {
3528                if !error.is_null() {
3529                    *error = err.to_glib_full()
3530                }
3531                false.into_glib()
3532            }
3533        }
3534    }
3535}
3536
3537unsafe extern "C" fn file_stop_mountable<T: FileImpl>(
3538    file: *mut ffi::GFile,
3539    flags: ffi::GMountUnmountFlags,
3540    mount_operation: *mut ffi::GMountOperation,
3541    cancellable: *mut ffi::GCancellable,
3542    callback: ffi::GAsyncReadyCallback,
3543    user_data: glib::ffi::gpointer,
3544) {
3545    unsafe {
3546        let instance = &*(file as *mut T::Instance);
3547        let imp = instance.imp();
3548        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3549        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3550        let callback = callback.map(|callback| {
3551            move |source: &T::Type, res: &AsyncResult| {
3552                callback(
3553                    source.upcast_ref::<Object>().to_glib_none().0,
3554                    res.to_glib_none().0,
3555                    user_data,
3556                )
3557            }
3558        });
3559
3560        imp.stop_mountable(
3561            from_glib(flags),
3562            mount_operation.as_ref(),
3563            cancellable.as_ref(),
3564            callback,
3565        );
3566    }
3567}
3568
3569unsafe extern "C" fn file_stop_mountable_finish<T: FileImpl>(
3570    file: *mut ffi::GFile,
3571    res: *mut ffi::GAsyncResult,
3572    error: *mut *mut glib::ffi::GError,
3573) -> glib::ffi::gboolean {
3574    unsafe {
3575        let instance = &*(file as *mut T::Instance);
3576        let imp = instance.imp();
3577        let result: &AsyncResult = &from_glib_borrow(res);
3578
3579        let res_ = imp.stop_mountable_finish(result);
3580        match res_ {
3581            Ok(_) => true.into_glib(),
3582            Err(err) => {
3583                if !error.is_null() {
3584                    *error = err.to_glib_full()
3585                }
3586                false.into_glib()
3587            }
3588        }
3589    }
3590}
3591
3592unsafe extern "C" fn file_unmount_mountable_with_operation<T: FileImpl>(
3593    file: *mut ffi::GFile,
3594    flags: ffi::GMountUnmountFlags,
3595    mount_operation: *mut ffi::GMountOperation,
3596    cancellable: *mut ffi::GCancellable,
3597    callback: ffi::GAsyncReadyCallback,
3598    user_data: glib::ffi::gpointer,
3599) {
3600    unsafe {
3601        let instance = &*(file as *mut T::Instance);
3602        let imp = instance.imp();
3603        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3604        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3605        let callback = callback.map(|callback| {
3606            move |source: &T::Type, res: &AsyncResult| {
3607                callback(
3608                    source.upcast_ref::<Object>().to_glib_none().0,
3609                    res.to_glib_none().0,
3610                    user_data,
3611                )
3612            }
3613        });
3614
3615        imp.unmount_mountable_with_operation(
3616            from_glib(flags),
3617            mount_operation.as_ref(),
3618            cancellable.as_ref(),
3619            callback,
3620        );
3621    }
3622}
3623
3624unsafe extern "C" fn file_unmount_mountable_with_operation_finish<T: FileImpl>(
3625    file: *mut ffi::GFile,
3626    res: *mut ffi::GAsyncResult,
3627    error: *mut *mut glib::ffi::GError,
3628) -> glib::ffi::gboolean {
3629    unsafe {
3630        let instance = &*(file as *mut T::Instance);
3631        let imp = instance.imp();
3632        let result: &AsyncResult = &from_glib_borrow(res);
3633
3634        let res_ = imp.unmount_mountable_with_operation_finish(result);
3635        match res_ {
3636            Ok(_) => true.into_glib(),
3637            Err(err) => {
3638                if !error.is_null() {
3639                    *error = err.to_glib_full()
3640                }
3641                false.into_glib()
3642            }
3643        }
3644    }
3645}
3646
3647unsafe extern "C" fn file_eject_mountable_with_operation<T: FileImpl>(
3648    file: *mut ffi::GFile,
3649    flags: ffi::GMountUnmountFlags,
3650    mount_operation: *mut ffi::GMountOperation,
3651    cancellable: *mut ffi::GCancellable,
3652    callback: ffi::GAsyncReadyCallback,
3653    user_data: glib::ffi::gpointer,
3654) {
3655    unsafe {
3656        let instance = &*(file as *mut T::Instance);
3657        let imp = instance.imp();
3658        let mount_operation = Option::<MountOperation>::from_glib_none(mount_operation);
3659        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3660        let callback = callback.map(|callback| {
3661            move |source: &T::Type, res: &AsyncResult| {
3662                callback(
3663                    source.upcast_ref::<Object>().to_glib_none().0,
3664                    res.to_glib_none().0,
3665                    user_data,
3666                )
3667            }
3668        });
3669
3670        imp.eject_mountable_with_operation(
3671            from_glib(flags),
3672            mount_operation.as_ref(),
3673            cancellable.as_ref(),
3674            callback,
3675        );
3676    }
3677}
3678
3679unsafe extern "C" fn file_eject_mountable_with_operation_finish<T: FileImpl>(
3680    file: *mut ffi::GFile,
3681    res: *mut ffi::GAsyncResult,
3682    error: *mut *mut glib::ffi::GError,
3683) -> glib::ffi::gboolean {
3684    unsafe {
3685        let instance = &*(file as *mut T::Instance);
3686        let imp = instance.imp();
3687        let result: &AsyncResult = &from_glib_borrow(res);
3688
3689        let res_ = imp.eject_mountable_with_operation_finish(result);
3690        match res_ {
3691            Ok(_) => true.into_glib(),
3692            Err(err) => {
3693                if !error.is_null() {
3694                    *error = err.to_glib_full()
3695                }
3696                false.into_glib()
3697            }
3698        }
3699    }
3700}
3701
3702unsafe extern "C" fn file_poll_mountable<T: FileImpl>(
3703    file: *mut ffi::GFile,
3704    cancellable: *mut ffi::GCancellable,
3705    callback: ffi::GAsyncReadyCallback,
3706    user_data: glib::ffi::gpointer,
3707) {
3708    unsafe {
3709        let instance = &*(file as *mut T::Instance);
3710        let imp = instance.imp();
3711        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3712        let callback = callback.map(|callback| {
3713            move |source: &T::Type, res: &AsyncResult| {
3714                callback(
3715                    source.upcast_ref::<Object>().to_glib_none().0,
3716                    res.to_glib_none().0,
3717                    user_data,
3718                )
3719            }
3720        });
3721
3722        imp.poll_mountable(cancellable.as_ref(), callback)
3723    }
3724}
3725
3726unsafe extern "C" fn file_poll_mountable_finish<T: FileImpl>(
3727    file: *mut ffi::GFile,
3728    res: *mut ffi::GAsyncResult,
3729    error: *mut *mut glib::ffi::GError,
3730) -> glib::ffi::gboolean {
3731    unsafe {
3732        let instance = &*(file as *mut T::Instance);
3733        let imp = instance.imp();
3734        let result: &AsyncResult = &from_glib_borrow(res);
3735
3736        let res_ = imp.poll_mountable_finish(result);
3737        match res_ {
3738            Ok(_) => true.into_glib(),
3739            Err(err) => {
3740                if !error.is_null() {
3741                    *error = err.to_glib_full()
3742                }
3743                false.into_glib()
3744            }
3745        }
3746    }
3747}
3748
3749unsafe extern "C" fn file_measure_disk_usage<T: FileImpl>(
3750    file: *mut ffi::GFile,
3751    flags: ffi::GFileMeasureFlags,
3752    cancellable: *mut ffi::GCancellable,
3753    progress_callback: ffi::GFileMeasureProgressCallback,
3754    progress_callback_data: glib::ffi::gpointer,
3755    disk_usage: *mut u64,
3756    num_dirs: *mut u64,
3757    num_files: *mut u64,
3758    error: *mut *mut glib::ffi::GError,
3759) -> glib::ffi::gboolean {
3760    unsafe {
3761        let instance = &*(file as *mut T::Instance);
3762        let imp = instance.imp();
3763        let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3764        let mut progress_callback = progress_callback.map(|callback| {
3765            move |reporting: bool, current_size: u64, num_dirs: u64, num_files: u64| {
3766                callback(
3767                    reporting.into_glib(),
3768                    current_size,
3769                    num_dirs,
3770                    num_files,
3771                    progress_callback_data,
3772                )
3773            }
3774        });
3775        let progress_callback_ref = progress_callback
3776            .as_mut()
3777            .map(|f| f as &mut dyn FnMut(bool, u64, u64, u64));
3778
3779        let res = imp.measure_disk_usage(
3780            from_glib(flags),
3781            cancellable.as_ref(),
3782            progress_callback_ref,
3783        );
3784        match res {
3785            Ok((disk_usage_, num_dirs_, num_files_)) => {
3786                if !disk_usage.is_null() {
3787                    *disk_usage = disk_usage_
3788                }
3789                if !num_dirs.is_null() {
3790                    *num_dirs = num_dirs_
3791                }
3792                if !num_files.is_null() {
3793                    *num_files = num_files_
3794                }
3795                true.into_glib()
3796            }
3797            Err(err) => {
3798                if !error.is_null() {
3799                    *error = err.to_glib_full()
3800                }
3801                false.into_glib()
3802            }
3803        }
3804    }
3805}
3806
3807#[cfg(feature = "v2_84")]
3808unsafe extern "C" fn file_query_exists<T: FileImpl>(
3809    file: *mut ffi::GFile,
3810    cancellable: *mut ffi::GCancellable,
3811) -> glib::ffi::gboolean {
3812    let instance = &*(file as *mut T::Instance);
3813    let imp = instance.imp();
3814    let cancellable = Option::<Cancellable>::from_glib_none(cancellable);
3815
3816    let res = imp.query_exists(cancellable.as_ref());
3817    res.into_glib()
3818}
3819
3820#[cfg(test)]
3821mod tests;