|  | 
|  | 1 | +// Take a look at the license at the top of the repository in the LICENSE file. | 
|  | 2 | + | 
|  | 3 | +use glib::{prelude::*, subclass::prelude::*, translate::*, GString}; | 
|  | 4 | + | 
|  | 5 | +use libc::c_char; | 
|  | 6 | + | 
|  | 7 | +use crate::{ffi, File, Vfs}; | 
|  | 8 | + | 
|  | 9 | +// Support custom implementation of virtual functions defined in `gio::ffi::GVfsClass`. | 
|  | 10 | +pub trait VfsImpl: ObjectImpl + ObjectSubclass<Type: IsA<Vfs>> { | 
|  | 11 | +    fn is_active(&self) -> bool { | 
|  | 12 | +        self.parent_is_active() | 
|  | 13 | +    } | 
|  | 14 | + | 
|  | 15 | +    fn get_file_for_path(&self, path: &str) -> File { | 
|  | 16 | +        self.parent_get_file_for_path(path) | 
|  | 17 | +    } | 
|  | 18 | + | 
|  | 19 | +    fn get_file_for_uri(&self, uri: &str) -> File { | 
|  | 20 | +        self.parent_get_file_for_uri(uri) | 
|  | 21 | +    } | 
|  | 22 | + | 
|  | 23 | +    fn get_supported_uri_schemes(&self) -> Vec<String> { | 
|  | 24 | +        self.parent_get_supported_uri_schemes() | 
|  | 25 | +    } | 
|  | 26 | + | 
|  | 27 | +    fn parse_name(&self, parse_name: &str) -> File { | 
|  | 28 | +        self.parent_parse_name(parse_name) | 
|  | 29 | +    } | 
|  | 30 | +} | 
|  | 31 | + | 
|  | 32 | +// Support parent implementation of virtual functions defined in `gio::ffi::GVfsClass`. | 
|  | 33 | +pub trait VfsImplExt: VfsImpl { | 
|  | 34 | +    fn parent_is_active(&self) -> bool { | 
|  | 35 | +        unsafe { | 
|  | 36 | +            let data = Self::type_data(); | 
|  | 37 | +            let parent_class = data.as_ref().parent_class() as *const ffi::GVfsClass; | 
|  | 38 | + | 
|  | 39 | +            let f = (*parent_class) | 
|  | 40 | +                .is_active | 
|  | 41 | +                .expect("No parent class implementation for \"is_active\""); | 
|  | 42 | + | 
|  | 43 | +            let res = f(self.obj().unsafe_cast_ref::<Vfs>().to_glib_none().0); | 
|  | 44 | +            from_glib(res) | 
|  | 45 | +        } | 
|  | 46 | +    } | 
|  | 47 | + | 
|  | 48 | +    fn parent_get_file_for_path(&self, path: &str) -> File { | 
|  | 49 | +        unsafe { | 
|  | 50 | +            let data = Self::type_data(); | 
|  | 51 | +            let parent_class = data.as_ref().parent_class() as *const ffi::GVfsClass; | 
|  | 52 | + | 
|  | 53 | +            let f = (*parent_class) | 
|  | 54 | +                .get_file_for_path | 
|  | 55 | +                .expect("No parent class implementation for \"get_file_for_path\""); | 
|  | 56 | + | 
|  | 57 | +            let res = f( | 
|  | 58 | +                self.obj().unsafe_cast_ref::<Vfs>().to_glib_none().0, | 
|  | 59 | +                path.to_glib_none().0, | 
|  | 60 | +            ); | 
|  | 61 | +            from_glib_full(res) | 
|  | 62 | +        } | 
|  | 63 | +    } | 
|  | 64 | + | 
|  | 65 | +    fn parent_get_file_for_uri(&self, uri: &str) -> File { | 
|  | 66 | +        unsafe { | 
|  | 67 | +            let data = Self::type_data(); | 
|  | 68 | +            let parent_class = data.as_ref().parent_class() as *const ffi::GVfsClass; | 
|  | 69 | + | 
|  | 70 | +            let f = (*parent_class) | 
|  | 71 | +                .get_file_for_uri | 
|  | 72 | +                .expect("No parent class implementation for \"get_file_for_uri\""); | 
|  | 73 | + | 
|  | 74 | +            let res = f( | 
|  | 75 | +                self.obj().unsafe_cast_ref::<Vfs>().to_glib_none().0, | 
|  | 76 | +                uri.to_glib_none().0, | 
|  | 77 | +            ); | 
|  | 78 | +            from_glib_full(res) | 
|  | 79 | +        } | 
|  | 80 | +    } | 
|  | 81 | + | 
|  | 82 | +    fn parent_get_supported_uri_schemes(&self) -> Vec<String> { | 
|  | 83 | +        unsafe { | 
|  | 84 | +            let data = Self::type_data(); | 
|  | 85 | +            let parent_class = data.as_ref().parent_class() as *const ffi::GVfsClass; | 
|  | 86 | + | 
|  | 87 | +            let f = (*parent_class) | 
|  | 88 | +                .get_supported_uri_schemes | 
|  | 89 | +                .expect("No parent class implementation for \"get_supported_uri_schemes\""); | 
|  | 90 | + | 
|  | 91 | +            let res = f(self.obj().unsafe_cast_ref::<Vfs>().to_glib_none().0); | 
|  | 92 | +            FromGlibPtrContainer::from_glib_none(res) | 
|  | 93 | +        } | 
|  | 94 | +    } | 
|  | 95 | + | 
|  | 96 | +    fn parent_parse_name(&self, parse_name: &str) -> File { | 
|  | 97 | +        unsafe { | 
|  | 98 | +            let data = Self::type_data(); | 
|  | 99 | +            let parent_class = data.as_ref().parent_class() as *const ffi::GVfsClass; | 
|  | 100 | + | 
|  | 101 | +            let f = (*parent_class) | 
|  | 102 | +                .parse_name | 
|  | 103 | +                .expect("No parent class implementation for \"parse_name\""); | 
|  | 104 | + | 
|  | 105 | +            let res = f( | 
|  | 106 | +                self.obj().unsafe_cast_ref::<Vfs>().to_glib_none().0, | 
|  | 107 | +                parse_name.to_glib_none().0, | 
|  | 108 | +            ); | 
|  | 109 | +            from_glib_full(res) | 
|  | 110 | +        } | 
|  | 111 | +    } | 
|  | 112 | +} | 
|  | 113 | + | 
|  | 114 | +impl<T: VfsImpl> VfsImplExt for T {} | 
|  | 115 | + | 
|  | 116 | +// Implement virtual functions defined in `gio::ffi::GVfsClass`. | 
|  | 117 | +unsafe impl<T: VfsImpl> IsSubclassable<T> for Vfs { | 
|  | 118 | +    fn class_init(class: &mut ::glib::Class<Self>) { | 
|  | 119 | +        Self::parent_class_init::<T>(class); | 
|  | 120 | + | 
|  | 121 | +        let klass = class.as_mut(); | 
|  | 122 | +        klass.is_active = Some(is_active::<T>); | 
|  | 123 | +        klass.get_file_for_path = Some(get_file_for_path::<T>); | 
|  | 124 | +        klass.get_file_for_uri = Some(get_file_for_uri::<T>); | 
|  | 125 | +        klass.get_supported_uri_schemes = Some(get_supported_uri_schemes::<T>); | 
|  | 126 | +        klass.parse_name = Some(parse_name::<T>); | 
|  | 127 | +    } | 
|  | 128 | +} | 
|  | 129 | + | 
|  | 130 | +unsafe extern "C" fn is_active<T: VfsImpl>(vfs: *mut ffi::GVfs) -> glib::ffi::gboolean { | 
|  | 131 | +    let instance = &*(vfs as *mut T::Instance); | 
|  | 132 | +    let imp = instance.imp(); | 
|  | 133 | + | 
|  | 134 | +    let res = imp.is_active(); | 
|  | 135 | + | 
|  | 136 | +    res.into_glib() | 
|  | 137 | +} | 
|  | 138 | + | 
|  | 139 | +unsafe extern "C" fn get_file_for_path<T: VfsImpl>( | 
|  | 140 | +    vfs: *mut ffi::GVfs, | 
|  | 141 | +    path: *const c_char, | 
|  | 142 | +) -> *mut ffi::GFile { | 
|  | 143 | +    let instance = &*(vfs as *mut T::Instance); | 
|  | 144 | +    let imp = instance.imp(); | 
|  | 145 | + | 
|  | 146 | +    let file = imp.get_file_for_path(&GString::from_glib_borrow(path)); | 
|  | 147 | + | 
|  | 148 | +    file.to_glib_full() | 
|  | 149 | +} | 
|  | 150 | + | 
|  | 151 | +unsafe extern "C" fn get_file_for_uri<T: VfsImpl>( | 
|  | 152 | +    vfs: *mut ffi::GVfs, | 
|  | 153 | +    uri: *const c_char, | 
|  | 154 | +) -> *mut ffi::GFile { | 
|  | 155 | +    let instance = &*(vfs as *mut T::Instance); | 
|  | 156 | +    let imp = instance.imp(); | 
|  | 157 | + | 
|  | 158 | +    let file = imp.get_file_for_uri(&GString::from_glib_borrow(uri)); | 
|  | 159 | + | 
|  | 160 | +    file.to_glib_full() | 
|  | 161 | +} | 
|  | 162 | + | 
|  | 163 | +unsafe extern "C" fn get_supported_uri_schemes<T: VfsImpl>( | 
|  | 164 | +    vfs: *mut ffi::GVfs, | 
|  | 165 | +) -> *const *const c_char { | 
|  | 166 | +    let instance = &*(vfs as *mut T::Instance); | 
|  | 167 | +    let imp = instance.imp(); | 
|  | 168 | + | 
|  | 169 | +    let supported_uri_schemes = imp.get_supported_uri_schemes(); | 
|  | 170 | + | 
|  | 171 | +    supported_uri_schemes.to_glib_full() | 
|  | 172 | +} | 
|  | 173 | + | 
|  | 174 | +unsafe extern "C" fn parse_name<T: VfsImpl>( | 
|  | 175 | +    vfs: *mut ffi::GVfs, | 
|  | 176 | +    parse_name: *const c_char, | 
|  | 177 | +) -> *mut ffi::GFile { | 
|  | 178 | +    let instance = &*(vfs as *mut T::Instance); | 
|  | 179 | +    let imp = instance.imp(); | 
|  | 180 | + | 
|  | 181 | +    let file = imp.parse_name(&GString::from_glib_borrow(parse_name)); | 
|  | 182 | + | 
|  | 183 | +    file.to_glib_full() | 
|  | 184 | +} | 
0 commit comments