1#[cfg(feature = "futures")]
6use futures::future;
7use gio_sys;
8use glib::object::Cast;
9use glib::object::IsA;
10use glib::signal::connect_raw;
11use glib::signal::SignalHandlerId;
12use glib::translate::*;
13use glib::GString;
14use glib_sys;
15use gobject_sys;
16use std::boxed::Box as Box_;
17use std::fmt;
18use std::mem::transmute;
19use std::ptr;
20use Cancellable;
21use Drive;
22use Error;
23use File;
24use Icon;
25use Mount;
26use MountMountFlags;
27use MountOperation;
28use MountUnmountFlags;
29
30glib_wrapper! {
31 pub struct Volume(Interface<gio_sys::GVolume>);
32
33 match fn {
34 get_type => || gio_sys::g_volume_get_type(),
35 }
36}
37
38pub const NONE_VOLUME: Option<&Volume> = None;
39
40pub trait VolumeExt: 'static {
41 fn can_eject(&self) -> bool;
42
43 fn can_mount(&self) -> bool;
44
45 fn eject_with_operation<
46 P: IsA<MountOperation>,
47 Q: IsA<Cancellable>,
48 R: FnOnce(Result<(), Error>) + Send + 'static,
49 >(
50 &self,
51 flags: MountUnmountFlags,
52 mount_operation: Option<&P>,
53 cancellable: Option<&Q>,
54 callback: R,
55 );
56
57 #[cfg(feature = "futures")]
58 fn eject_with_operation_future<P: IsA<MountOperation> + Clone + 'static>(
59 &self,
60 flags: MountUnmountFlags,
61 mount_operation: Option<&P>,
62 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
63
64 fn enumerate_identifiers(&self) -> Vec<GString>;
65
66 fn get_activation_root(&self) -> Option<File>;
67
68 fn get_drive(&self) -> Option<Drive>;
69
70 fn get_icon(&self) -> Option<Icon>;
71
72 fn get_identifier(&self, kind: &str) -> Option<GString>;
73
74 fn get_mount(&self) -> Option<Mount>;
75
76 fn get_name(&self) -> Option<GString>;
77
78 fn get_sort_key(&self) -> Option<GString>;
79
80 fn get_symbolic_icon(&self) -> Option<Icon>;
81
82 fn get_uuid(&self) -> Option<GString>;
83
84 fn mount<
85 P: IsA<MountOperation>,
86 Q: IsA<Cancellable>,
87 R: FnOnce(Result<(), Error>) + Send + 'static,
88 >(
89 &self,
90 flags: MountMountFlags,
91 mount_operation: Option<&P>,
92 cancellable: Option<&Q>,
93 callback: R,
94 );
95
96 #[cfg(feature = "futures")]
97 fn mount_future<P: IsA<MountOperation> + Clone + 'static>(
98 &self,
99 flags: MountMountFlags,
100 mount_operation: Option<&P>,
101 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
102
103 fn should_automount(&self) -> bool;
104
105 fn connect_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
106
107 fn connect_removed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
108}
109
110impl<O: IsA<Volume>> VolumeExt for O {
111 fn can_eject(&self) -> bool {
112 unsafe { from_glib(gio_sys::g_volume_can_eject(self.as_ref().to_glib_none().0)) }
113 }
114
115 fn can_mount(&self) -> bool {
116 unsafe { from_glib(gio_sys::g_volume_can_mount(self.as_ref().to_glib_none().0)) }
117 }
118
119 fn eject_with_operation<
120 P: IsA<MountOperation>,
121 Q: IsA<Cancellable>,
122 R: FnOnce(Result<(), Error>) + Send + 'static,
123 >(
124 &self,
125 flags: MountUnmountFlags,
126 mount_operation: Option<&P>,
127 cancellable: Option<&Q>,
128 callback: R,
129 ) {
130 let user_data: Box<R> = Box::new(callback);
131 unsafe extern "C" fn eject_with_operation_trampoline<
132 R: FnOnce(Result<(), Error>) + Send + 'static,
133 >(
134 _source_object: *mut gobject_sys::GObject,
135 res: *mut gio_sys::GAsyncResult,
136 user_data: glib_sys::gpointer,
137 ) {
138 let mut error = ptr::null_mut();
139 let _ = gio_sys::g_volume_eject_with_operation_finish(
140 _source_object as *mut _,
141 res,
142 &mut error,
143 );
144 let result = if error.is_null() {
145 Ok(())
146 } else {
147 Err(from_glib_full(error))
148 };
149 let callback: Box<R> = Box::from_raw(user_data as *mut _);
150 callback(result);
151 }
152 let callback = eject_with_operation_trampoline::<R>;
153 unsafe {
154 gio_sys::g_volume_eject_with_operation(
155 self.as_ref().to_glib_none().0,
156 flags.to_glib(),
157 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
158 cancellable.map(|p| p.as_ref()).to_glib_none().0,
159 Some(callback),
160 Box::into_raw(user_data) as *mut _,
161 );
162 }
163 }
164
165 #[cfg(feature = "futures")]
166 fn eject_with_operation_future<P: IsA<MountOperation> + Clone + 'static>(
167 &self,
168 flags: MountUnmountFlags,
169 mount_operation: Option<&P>,
170 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
171 use fragile::Fragile;
172 use GioFuture;
173
174 let mount_operation = mount_operation.map(ToOwned::to_owned);
175 GioFuture::new(self, move |obj, send| {
176 let cancellable = Cancellable::new();
177 let send = Fragile::new(send);
178 obj.eject_with_operation(
179 flags,
180 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
181 Some(&cancellable),
182 move |res| {
183 let _ = send.into_inner().send(res);
184 },
185 );
186
187 cancellable
188 })
189 }
190
191 fn enumerate_identifiers(&self) -> Vec<GString> {
192 unsafe {
193 FromGlibPtrContainer::from_glib_full(gio_sys::g_volume_enumerate_identifiers(
194 self.as_ref().to_glib_none().0,
195 ))
196 }
197 }
198
199 fn get_activation_root(&self) -> Option<File> {
200 unsafe {
201 from_glib_full(gio_sys::g_volume_get_activation_root(
202 self.as_ref().to_glib_none().0,
203 ))
204 }
205 }
206
207 fn get_drive(&self) -> Option<Drive> {
208 unsafe { from_glib_full(gio_sys::g_volume_get_drive(self.as_ref().to_glib_none().0)) }
209 }
210
211 fn get_icon(&self) -> Option<Icon> {
212 unsafe { from_glib_full(gio_sys::g_volume_get_icon(self.as_ref().to_glib_none().0)) }
213 }
214
215 fn get_identifier(&self, kind: &str) -> Option<GString> {
216 unsafe {
217 from_glib_full(gio_sys::g_volume_get_identifier(
218 self.as_ref().to_glib_none().0,
219 kind.to_glib_none().0,
220 ))
221 }
222 }
223
224 fn get_mount(&self) -> Option<Mount> {
225 unsafe { from_glib_full(gio_sys::g_volume_get_mount(self.as_ref().to_glib_none().0)) }
226 }
227
228 fn get_name(&self) -> Option<GString> {
229 unsafe { from_glib_full(gio_sys::g_volume_get_name(self.as_ref().to_glib_none().0)) }
230 }
231
232 fn get_sort_key(&self) -> Option<GString> {
233 unsafe {
234 from_glib_none(gio_sys::g_volume_get_sort_key(
235 self.as_ref().to_glib_none().0,
236 ))
237 }
238 }
239
240 fn get_symbolic_icon(&self) -> Option<Icon> {
241 unsafe {
242 from_glib_full(gio_sys::g_volume_get_symbolic_icon(
243 self.as_ref().to_glib_none().0,
244 ))
245 }
246 }
247
248 fn get_uuid(&self) -> Option<GString> {
249 unsafe { from_glib_full(gio_sys::g_volume_get_uuid(self.as_ref().to_glib_none().0)) }
250 }
251
252 fn mount<
253 P: IsA<MountOperation>,
254 Q: IsA<Cancellable>,
255 R: FnOnce(Result<(), Error>) + Send + 'static,
256 >(
257 &self,
258 flags: MountMountFlags,
259 mount_operation: Option<&P>,
260 cancellable: Option<&Q>,
261 callback: R,
262 ) {
263 let user_data: Box<R> = Box::new(callback);
264 unsafe extern "C" fn mount_trampoline<R: FnOnce(Result<(), Error>) + Send + 'static>(
265 _source_object: *mut gobject_sys::GObject,
266 res: *mut gio_sys::GAsyncResult,
267 user_data: glib_sys::gpointer,
268 ) {
269 let mut error = ptr::null_mut();
270 let _ = gio_sys::g_volume_mount_finish(_source_object as *mut _, res, &mut error);
271 let result = if error.is_null() {
272 Ok(())
273 } else {
274 Err(from_glib_full(error))
275 };
276 let callback: Box<R> = Box::from_raw(user_data as *mut _);
277 callback(result);
278 }
279 let callback = mount_trampoline::<R>;
280 unsafe {
281 gio_sys::g_volume_mount(
282 self.as_ref().to_glib_none().0,
283 flags.to_glib(),
284 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
285 cancellable.map(|p| p.as_ref()).to_glib_none().0,
286 Some(callback),
287 Box::into_raw(user_data) as *mut _,
288 );
289 }
290 }
291
292 #[cfg(feature = "futures")]
293 fn mount_future<P: IsA<MountOperation> + Clone + 'static>(
294 &self,
295 flags: MountMountFlags,
296 mount_operation: Option<&P>,
297 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
298 use fragile::Fragile;
299 use GioFuture;
300
301 let mount_operation = mount_operation.map(ToOwned::to_owned);
302 GioFuture::new(self, move |obj, send| {
303 let cancellable = Cancellable::new();
304 let send = Fragile::new(send);
305 obj.mount(
306 flags,
307 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
308 Some(&cancellable),
309 move |res| {
310 let _ = send.into_inner().send(res);
311 },
312 );
313
314 cancellable
315 })
316 }
317
318 fn should_automount(&self) -> bool {
319 unsafe {
320 from_glib(gio_sys::g_volume_should_automount(
321 self.as_ref().to_glib_none().0,
322 ))
323 }
324 }
325
326 fn connect_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
327 unsafe extern "C" fn changed_trampoline<P, F: Fn(&P) + 'static>(
328 this: *mut gio_sys::GVolume,
329 f: glib_sys::gpointer,
330 ) where
331 P: IsA<Volume>,
332 {
333 let f: &F = &*(f as *const F);
334 f(&Volume::from_glib_borrow(this).unsafe_cast())
335 }
336 unsafe {
337 let f: Box_<F> = Box_::new(f);
338 connect_raw(
339 self.as_ptr() as *mut _,
340 b"changed\0".as_ptr() as *const _,
341 Some(transmute(changed_trampoline::<Self, F> as usize)),
342 Box_::into_raw(f),
343 )
344 }
345 }
346
347 fn connect_removed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
348 unsafe extern "C" fn removed_trampoline<P, F: Fn(&P) + 'static>(
349 this: *mut gio_sys::GVolume,
350 f: glib_sys::gpointer,
351 ) where
352 P: IsA<Volume>,
353 {
354 let f: &F = &*(f as *const F);
355 f(&Volume::from_glib_borrow(this).unsafe_cast())
356 }
357 unsafe {
358 let f: Box_<F> = Box_::new(f);
359 connect_raw(
360 self.as_ptr() as *mut _,
361 b"removed\0".as_ptr() as *const _,
362 Some(transmute(removed_trampoline::<Self, F> as usize)),
363 Box_::into_raw(f),
364 )
365 }
366 }
367}
368
369impl fmt::Display for Volume {
370 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
371 write!(f, "Volume")
372 }
373}