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 DriveStartFlags;
22use DriveStartStopType;
23use Error;
24use Icon;
25use MountOperation;
26use MountUnmountFlags;
27use Volume;
28
29glib_wrapper! {
30 pub struct Drive(Interface<gio_sys::GDrive>);
31
32 match fn {
33 get_type => || gio_sys::g_drive_get_type(),
34 }
35}
36
37pub const NONE_DRIVE: Option<&Drive> = None;
38
39pub trait DriveExt: 'static {
40 fn can_eject(&self) -> bool;
41
42 fn can_poll_for_media(&self) -> bool;
43
44 fn can_start(&self) -> bool;
45
46 fn can_start_degraded(&self) -> bool;
47
48 fn can_stop(&self) -> bool;
49
50 fn eject_with_operation<
51 P: IsA<MountOperation>,
52 Q: IsA<Cancellable>,
53 R: FnOnce(Result<(), Error>) + Send + 'static,
54 >(
55 &self,
56 flags: MountUnmountFlags,
57 mount_operation: Option<&P>,
58 cancellable: Option<&Q>,
59 callback: R,
60 );
61
62 #[cfg(feature = "futures")]
63 fn eject_with_operation_future<P: IsA<MountOperation> + Clone + 'static>(
64 &self,
65 flags: MountUnmountFlags,
66 mount_operation: Option<&P>,
67 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
68
69 fn enumerate_identifiers(&self) -> Vec<GString>;
70
71 fn get_icon(&self) -> Option<Icon>;
72
73 fn get_identifier(&self, kind: &str) -> Option<GString>;
74
75 fn get_name(&self) -> Option<GString>;
76
77 fn get_sort_key(&self) -> Option<GString>;
78
79 fn get_start_stop_type(&self) -> DriveStartStopType;
80
81 fn get_symbolic_icon(&self) -> Option<Icon>;
82
83 fn get_volumes(&self) -> Vec<Volume>;
84
85 fn has_media(&self) -> bool;
86
87 fn has_volumes(&self) -> bool;
88
89 fn is_media_check_automatic(&self) -> bool;
90
91 fn is_media_removable(&self) -> bool;
92
93 #[cfg(any(feature = "v2_50", feature = "dox"))]
94 fn is_removable(&self) -> bool;
95
96 fn poll_for_media<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
97 &self,
98 cancellable: Option<&P>,
99 callback: Q,
100 );
101
102 #[cfg(feature = "futures")]
103 fn poll_for_media_future(
104 &self,
105 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
106
107 fn start<
108 P: IsA<MountOperation>,
109 Q: IsA<Cancellable>,
110 R: FnOnce(Result<(), Error>) + Send + 'static,
111 >(
112 &self,
113 flags: DriveStartFlags,
114 mount_operation: Option<&P>,
115 cancellable: Option<&Q>,
116 callback: R,
117 );
118
119 #[cfg(feature = "futures")]
120 fn start_future<P: IsA<MountOperation> + Clone + 'static>(
121 &self,
122 flags: DriveStartFlags,
123 mount_operation: Option<&P>,
124 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
125
126 fn stop<
127 P: IsA<MountOperation>,
128 Q: IsA<Cancellable>,
129 R: FnOnce(Result<(), Error>) + Send + 'static,
130 >(
131 &self,
132 flags: MountUnmountFlags,
133 mount_operation: Option<&P>,
134 cancellable: Option<&Q>,
135 callback: R,
136 );
137
138 #[cfg(feature = "futures")]
139 fn stop_future<P: IsA<MountOperation> + Clone + 'static>(
140 &self,
141 flags: MountUnmountFlags,
142 mount_operation: Option<&P>,
143 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
144
145 fn connect_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
146
147 fn connect_disconnected<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
148
149 fn connect_eject_button<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
150
151 fn connect_stop_button<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
152}
153
154impl<O: IsA<Drive>> DriveExt for O {
155 fn can_eject(&self) -> bool {
156 unsafe { from_glib(gio_sys::g_drive_can_eject(self.as_ref().to_glib_none().0)) }
157 }
158
159 fn can_poll_for_media(&self) -> bool {
160 unsafe {
161 from_glib(gio_sys::g_drive_can_poll_for_media(
162 self.as_ref().to_glib_none().0,
163 ))
164 }
165 }
166
167 fn can_start(&self) -> bool {
168 unsafe { from_glib(gio_sys::g_drive_can_start(self.as_ref().to_glib_none().0)) }
169 }
170
171 fn can_start_degraded(&self) -> bool {
172 unsafe {
173 from_glib(gio_sys::g_drive_can_start_degraded(
174 self.as_ref().to_glib_none().0,
175 ))
176 }
177 }
178
179 fn can_stop(&self) -> bool {
180 unsafe { from_glib(gio_sys::g_drive_can_stop(self.as_ref().to_glib_none().0)) }
181 }
182
183 fn eject_with_operation<
184 P: IsA<MountOperation>,
185 Q: IsA<Cancellable>,
186 R: FnOnce(Result<(), Error>) + Send + 'static,
187 >(
188 &self,
189 flags: MountUnmountFlags,
190 mount_operation: Option<&P>,
191 cancellable: Option<&Q>,
192 callback: R,
193 ) {
194 let user_data: Box<R> = Box::new(callback);
195 unsafe extern "C" fn eject_with_operation_trampoline<
196 R: FnOnce(Result<(), Error>) + Send + 'static,
197 >(
198 _source_object: *mut gobject_sys::GObject,
199 res: *mut gio_sys::GAsyncResult,
200 user_data: glib_sys::gpointer,
201 ) {
202 let mut error = ptr::null_mut();
203 let _ = gio_sys::g_drive_eject_with_operation_finish(
204 _source_object as *mut _,
205 res,
206 &mut error,
207 );
208 let result = if error.is_null() {
209 Ok(())
210 } else {
211 Err(from_glib_full(error))
212 };
213 let callback: Box<R> = Box::from_raw(user_data as *mut _);
214 callback(result);
215 }
216 let callback = eject_with_operation_trampoline::<R>;
217 unsafe {
218 gio_sys::g_drive_eject_with_operation(
219 self.as_ref().to_glib_none().0,
220 flags.to_glib(),
221 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
222 cancellable.map(|p| p.as_ref()).to_glib_none().0,
223 Some(callback),
224 Box::into_raw(user_data) as *mut _,
225 );
226 }
227 }
228
229 #[cfg(feature = "futures")]
230 fn eject_with_operation_future<P: IsA<MountOperation> + Clone + 'static>(
231 &self,
232 flags: MountUnmountFlags,
233 mount_operation: Option<&P>,
234 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
235 use fragile::Fragile;
236 use GioFuture;
237
238 let mount_operation = mount_operation.map(ToOwned::to_owned);
239 GioFuture::new(self, move |obj, send| {
240 let cancellable = Cancellable::new();
241 let send = Fragile::new(send);
242 obj.eject_with_operation(
243 flags,
244 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
245 Some(&cancellable),
246 move |res| {
247 let _ = send.into_inner().send(res);
248 },
249 );
250
251 cancellable
252 })
253 }
254
255 fn enumerate_identifiers(&self) -> Vec<GString> {
256 unsafe {
257 FromGlibPtrContainer::from_glib_full(gio_sys::g_drive_enumerate_identifiers(
258 self.as_ref().to_glib_none().0,
259 ))
260 }
261 }
262
263 fn get_icon(&self) -> Option<Icon> {
264 unsafe { from_glib_full(gio_sys::g_drive_get_icon(self.as_ref().to_glib_none().0)) }
265 }
266
267 fn get_identifier(&self, kind: &str) -> Option<GString> {
268 unsafe {
269 from_glib_full(gio_sys::g_drive_get_identifier(
270 self.as_ref().to_glib_none().0,
271 kind.to_glib_none().0,
272 ))
273 }
274 }
275
276 fn get_name(&self) -> Option<GString> {
277 unsafe { from_glib_full(gio_sys::g_drive_get_name(self.as_ref().to_glib_none().0)) }
278 }
279
280 fn get_sort_key(&self) -> Option<GString> {
281 unsafe {
282 from_glib_none(gio_sys::g_drive_get_sort_key(
283 self.as_ref().to_glib_none().0,
284 ))
285 }
286 }
287
288 fn get_start_stop_type(&self) -> DriveStartStopType {
289 unsafe {
290 from_glib(gio_sys::g_drive_get_start_stop_type(
291 self.as_ref().to_glib_none().0,
292 ))
293 }
294 }
295
296 fn get_symbolic_icon(&self) -> Option<Icon> {
297 unsafe {
298 from_glib_full(gio_sys::g_drive_get_symbolic_icon(
299 self.as_ref().to_glib_none().0,
300 ))
301 }
302 }
303
304 fn get_volumes(&self) -> Vec<Volume> {
305 unsafe {
306 FromGlibPtrContainer::from_glib_full(gio_sys::g_drive_get_volumes(
307 self.as_ref().to_glib_none().0,
308 ))
309 }
310 }
311
312 fn has_media(&self) -> bool {
313 unsafe { from_glib(gio_sys::g_drive_has_media(self.as_ref().to_glib_none().0)) }
314 }
315
316 fn has_volumes(&self) -> bool {
317 unsafe { from_glib(gio_sys::g_drive_has_volumes(self.as_ref().to_glib_none().0)) }
318 }
319
320 fn is_media_check_automatic(&self) -> bool {
321 unsafe {
322 from_glib(gio_sys::g_drive_is_media_check_automatic(
323 self.as_ref().to_glib_none().0,
324 ))
325 }
326 }
327
328 fn is_media_removable(&self) -> bool {
329 unsafe {
330 from_glib(gio_sys::g_drive_is_media_removable(
331 self.as_ref().to_glib_none().0,
332 ))
333 }
334 }
335
336 #[cfg(any(feature = "v2_50", feature = "dox"))]
337 fn is_removable(&self) -> bool {
338 unsafe {
339 from_glib(gio_sys::g_drive_is_removable(
340 self.as_ref().to_glib_none().0,
341 ))
342 }
343 }
344
345 fn poll_for_media<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
346 &self,
347 cancellable: Option<&P>,
348 callback: Q,
349 ) {
350 let user_data: Box<Q> = Box::new(callback);
351 unsafe extern "C" fn poll_for_media_trampoline<
352 Q: FnOnce(Result<(), Error>) + Send + 'static,
353 >(
354 _source_object: *mut gobject_sys::GObject,
355 res: *mut gio_sys::GAsyncResult,
356 user_data: glib_sys::gpointer,
357 ) {
358 let mut error = ptr::null_mut();
359 let _ =
360 gio_sys::g_drive_poll_for_media_finish(_source_object as *mut _, res, &mut error);
361 let result = if error.is_null() {
362 Ok(())
363 } else {
364 Err(from_glib_full(error))
365 };
366 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
367 callback(result);
368 }
369 let callback = poll_for_media_trampoline::<Q>;
370 unsafe {
371 gio_sys::g_drive_poll_for_media(
372 self.as_ref().to_glib_none().0,
373 cancellable.map(|p| p.as_ref()).to_glib_none().0,
374 Some(callback),
375 Box::into_raw(user_data) as *mut _,
376 );
377 }
378 }
379
380 #[cfg(feature = "futures")]
381 fn poll_for_media_future(
382 &self,
383 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
384 use fragile::Fragile;
385 use GioFuture;
386
387 GioFuture::new(self, move |obj, send| {
388 let cancellable = Cancellable::new();
389 let send = Fragile::new(send);
390 obj.poll_for_media(Some(&cancellable), move |res| {
391 let _ = send.into_inner().send(res);
392 });
393
394 cancellable
395 })
396 }
397
398 fn start<
399 P: IsA<MountOperation>,
400 Q: IsA<Cancellable>,
401 R: FnOnce(Result<(), Error>) + Send + 'static,
402 >(
403 &self,
404 flags: DriveStartFlags,
405 mount_operation: Option<&P>,
406 cancellable: Option<&Q>,
407 callback: R,
408 ) {
409 let user_data: Box<R> = Box::new(callback);
410 unsafe extern "C" fn start_trampoline<R: FnOnce(Result<(), Error>) + Send + 'static>(
411 _source_object: *mut gobject_sys::GObject,
412 res: *mut gio_sys::GAsyncResult,
413 user_data: glib_sys::gpointer,
414 ) {
415 let mut error = ptr::null_mut();
416 let _ = gio_sys::g_drive_start_finish(_source_object as *mut _, res, &mut error);
417 let result = if error.is_null() {
418 Ok(())
419 } else {
420 Err(from_glib_full(error))
421 };
422 let callback: Box<R> = Box::from_raw(user_data as *mut _);
423 callback(result);
424 }
425 let callback = start_trampoline::<R>;
426 unsafe {
427 gio_sys::g_drive_start(
428 self.as_ref().to_glib_none().0,
429 flags.to_glib(),
430 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
431 cancellable.map(|p| p.as_ref()).to_glib_none().0,
432 Some(callback),
433 Box::into_raw(user_data) as *mut _,
434 );
435 }
436 }
437
438 #[cfg(feature = "futures")]
439 fn start_future<P: IsA<MountOperation> + Clone + 'static>(
440 &self,
441 flags: DriveStartFlags,
442 mount_operation: Option<&P>,
443 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
444 use fragile::Fragile;
445 use GioFuture;
446
447 let mount_operation = mount_operation.map(ToOwned::to_owned);
448 GioFuture::new(self, move |obj, send| {
449 let cancellable = Cancellable::new();
450 let send = Fragile::new(send);
451 obj.start(
452 flags,
453 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
454 Some(&cancellable),
455 move |res| {
456 let _ = send.into_inner().send(res);
457 },
458 );
459
460 cancellable
461 })
462 }
463
464 fn stop<
465 P: IsA<MountOperation>,
466 Q: IsA<Cancellable>,
467 R: FnOnce(Result<(), Error>) + Send + 'static,
468 >(
469 &self,
470 flags: MountUnmountFlags,
471 mount_operation: Option<&P>,
472 cancellable: Option<&Q>,
473 callback: R,
474 ) {
475 let user_data: Box<R> = Box::new(callback);
476 unsafe extern "C" fn stop_trampoline<R: FnOnce(Result<(), Error>) + Send + 'static>(
477 _source_object: *mut gobject_sys::GObject,
478 res: *mut gio_sys::GAsyncResult,
479 user_data: glib_sys::gpointer,
480 ) {
481 let mut error = ptr::null_mut();
482 let _ = gio_sys::g_drive_stop_finish(_source_object as *mut _, res, &mut error);
483 let result = if error.is_null() {
484 Ok(())
485 } else {
486 Err(from_glib_full(error))
487 };
488 let callback: Box<R> = Box::from_raw(user_data as *mut _);
489 callback(result);
490 }
491 let callback = stop_trampoline::<R>;
492 unsafe {
493 gio_sys::g_drive_stop(
494 self.as_ref().to_glib_none().0,
495 flags.to_glib(),
496 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
497 cancellable.map(|p| p.as_ref()).to_glib_none().0,
498 Some(callback),
499 Box::into_raw(user_data) as *mut _,
500 );
501 }
502 }
503
504 #[cfg(feature = "futures")]
505 fn stop_future<P: IsA<MountOperation> + Clone + 'static>(
506 &self,
507 flags: MountUnmountFlags,
508 mount_operation: Option<&P>,
509 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
510 use fragile::Fragile;
511 use GioFuture;
512
513 let mount_operation = mount_operation.map(ToOwned::to_owned);
514 GioFuture::new(self, move |obj, send| {
515 let cancellable = Cancellable::new();
516 let send = Fragile::new(send);
517 obj.stop(
518 flags,
519 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
520 Some(&cancellable),
521 move |res| {
522 let _ = send.into_inner().send(res);
523 },
524 );
525
526 cancellable
527 })
528 }
529
530 fn connect_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
531 unsafe extern "C" fn changed_trampoline<P, F: Fn(&P) + 'static>(
532 this: *mut gio_sys::GDrive,
533 f: glib_sys::gpointer,
534 ) where
535 P: IsA<Drive>,
536 {
537 let f: &F = &*(f as *const F);
538 f(&Drive::from_glib_borrow(this).unsafe_cast())
539 }
540 unsafe {
541 let f: Box_<F> = Box_::new(f);
542 connect_raw(
543 self.as_ptr() as *mut _,
544 b"changed\0".as_ptr() as *const _,
545 Some(transmute(changed_trampoline::<Self, F> as usize)),
546 Box_::into_raw(f),
547 )
548 }
549 }
550
551 fn connect_disconnected<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
552 unsafe extern "C" fn disconnected_trampoline<P, F: Fn(&P) + 'static>(
553 this: *mut gio_sys::GDrive,
554 f: glib_sys::gpointer,
555 ) where
556 P: IsA<Drive>,
557 {
558 let f: &F = &*(f as *const F);
559 f(&Drive::from_glib_borrow(this).unsafe_cast())
560 }
561 unsafe {
562 let f: Box_<F> = Box_::new(f);
563 connect_raw(
564 self.as_ptr() as *mut _,
565 b"disconnected\0".as_ptr() as *const _,
566 Some(transmute(disconnected_trampoline::<Self, F> as usize)),
567 Box_::into_raw(f),
568 )
569 }
570 }
571
572 fn connect_eject_button<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
573 unsafe extern "C" fn eject_button_trampoline<P, F: Fn(&P) + 'static>(
574 this: *mut gio_sys::GDrive,
575 f: glib_sys::gpointer,
576 ) where
577 P: IsA<Drive>,
578 {
579 let f: &F = &*(f as *const F);
580 f(&Drive::from_glib_borrow(this).unsafe_cast())
581 }
582 unsafe {
583 let f: Box_<F> = Box_::new(f);
584 connect_raw(
585 self.as_ptr() as *mut _,
586 b"eject-button\0".as_ptr() as *const _,
587 Some(transmute(eject_button_trampoline::<Self, F> as usize)),
588 Box_::into_raw(f),
589 )
590 }
591 }
592
593 fn connect_stop_button<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
594 unsafe extern "C" fn stop_button_trampoline<P, F: Fn(&P) + 'static>(
595 this: *mut gio_sys::GDrive,
596 f: glib_sys::gpointer,
597 ) where
598 P: IsA<Drive>,
599 {
600 let f: &F = &*(f as *const F);
601 f(&Drive::from_glib_borrow(this).unsafe_cast())
602 }
603 unsafe {
604 let f: Box_<F> = Box_::new(f);
605 connect_raw(
606 self.as_ptr() as *mut _,
607 b"stop-button\0".as_ptr() as *const _,
608 Some(transmute(stop_button_trampoline::<Self, F> as usize)),
609 Box_::into_raw(f),
610 )
611 }
612 }
613}
614
615impl fmt::Display for Drive {
616 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
617 write!(f, "Drive")
618 }
619}