1use crate::{
6 ffi, AsyncResult, Cancellable, DriveStartFlags, DriveStartStopType, Icon, MountOperation,
7 MountUnmountFlags, Volume,
8};
9use glib::{
10 object::ObjectType as _,
11 prelude::*,
12 signal::{connect_raw, SignalHandlerId},
13 translate::*,
14};
15use std::{boxed::Box as Box_, pin::Pin};
16
17glib::wrapper! {
18 #[doc(alias = "GDrive")]
80 pub struct Drive(Interface<ffi::GDrive, ffi::GDriveIface>);
81
82 match fn {
83 type_ => || ffi::g_drive_get_type(),
84 }
85}
86
87impl Drive {
88 pub const NONE: Option<&'static Drive> = None;
89}
90
91pub trait DriveExt: IsA<Drive> + 'static {
97 #[doc(alias = "g_drive_can_eject")]
103 fn can_eject(&self) -> bool {
104 unsafe { from_glib(ffi::g_drive_can_eject(self.as_ref().to_glib_none().0)) }
105 }
106
107 #[doc(alias = "g_drive_can_poll_for_media")]
114 fn can_poll_for_media(&self) -> bool {
115 unsafe {
116 from_glib(ffi::g_drive_can_poll_for_media(
117 self.as_ref().to_glib_none().0,
118 ))
119 }
120 }
121
122 #[doc(alias = "g_drive_can_start")]
128 fn can_start(&self) -> bool {
129 unsafe { from_glib(ffi::g_drive_can_start(self.as_ref().to_glib_none().0)) }
130 }
131
132 #[doc(alias = "g_drive_can_start_degraded")]
138 fn can_start_degraded(&self) -> bool {
139 unsafe {
140 from_glib(ffi::g_drive_can_start_degraded(
141 self.as_ref().to_glib_none().0,
142 ))
143 }
144 }
145
146 #[doc(alias = "g_drive_can_stop")]
152 fn can_stop(&self) -> bool {
153 unsafe { from_glib(ffi::g_drive_can_stop(self.as_ref().to_glib_none().0)) }
154 }
155
156 #[doc(alias = "g_drive_eject_with_operation")]
169 fn eject_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
170 &self,
171 flags: MountUnmountFlags,
172 mount_operation: Option<&impl IsA<MountOperation>>,
173 cancellable: Option<&impl IsA<Cancellable>>,
174 callback: P,
175 ) {
176 let main_context = glib::MainContext::ref_thread_default();
177 let is_main_context_owner = main_context.is_owner();
178 let has_acquired_main_context = (!is_main_context_owner)
179 .then(|| main_context.acquire().ok())
180 .flatten();
181 assert!(
182 is_main_context_owner || has_acquired_main_context.is_some(),
183 "Async operations only allowed if the thread is owning the MainContext"
184 );
185
186 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
187 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
188 unsafe extern "C" fn eject_with_operation_trampoline<
189 P: FnOnce(Result<(), glib::Error>) + 'static,
190 >(
191 _source_object: *mut glib::gobject_ffi::GObject,
192 res: *mut crate::ffi::GAsyncResult,
193 user_data: glib::ffi::gpointer,
194 ) {
195 let mut error = std::ptr::null_mut();
196 ffi::g_drive_eject_with_operation_finish(_source_object as *mut _, res, &mut error);
197 let result = if error.is_null() {
198 Ok(())
199 } else {
200 Err(from_glib_full(error))
201 };
202 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
203 Box_::from_raw(user_data as *mut _);
204 let callback: P = callback.into_inner();
205 callback(result);
206 }
207 let callback = eject_with_operation_trampoline::<P>;
208 unsafe {
209 ffi::g_drive_eject_with_operation(
210 self.as_ref().to_glib_none().0,
211 flags.into_glib(),
212 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
213 cancellable.map(|p| p.as_ref()).to_glib_none().0,
214 Some(callback),
215 Box_::into_raw(user_data) as *mut _,
216 );
217 }
218 }
219
220 fn eject_with_operation_future(
221 &self,
222 flags: MountUnmountFlags,
223 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
224 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
225 let mount_operation = mount_operation.map(ToOwned::to_owned);
226 Box_::pin(crate::GioFuture::new(
227 self,
228 move |obj, cancellable, send| {
229 obj.eject_with_operation(
230 flags,
231 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
232 Some(cancellable),
233 move |res| {
234 send.resolve(res);
235 },
236 );
237 },
238 ))
239 }
240
241 #[doc(alias = "g_drive_enumerate_identifiers")]
251 fn enumerate_identifiers(&self) -> Vec<glib::GString> {
252 unsafe {
253 FromGlibPtrContainer::from_glib_full(ffi::g_drive_enumerate_identifiers(
254 self.as_ref().to_glib_none().0,
255 ))
256 }
257 }
258
259 #[doc(alias = "g_drive_get_icon")]
266 #[doc(alias = "get_icon")]
267 fn icon(&self) -> Icon {
268 unsafe { from_glib_full(ffi::g_drive_get_icon(self.as_ref().to_glib_none().0)) }
269 }
270
271 #[doc(alias = "g_drive_get_identifier")]
283 #[doc(alias = "get_identifier")]
284 fn identifier(&self, kind: &str) -> Option<glib::GString> {
285 unsafe {
286 from_glib_full(ffi::g_drive_get_identifier(
287 self.as_ref().to_glib_none().0,
288 kind.to_glib_none().0,
289 ))
290 }
291 }
292
293 #[doc(alias = "g_drive_get_name")]
300 #[doc(alias = "get_name")]
301 fn name(&self) -> glib::GString {
302 unsafe { from_glib_full(ffi::g_drive_get_name(self.as_ref().to_glib_none().0)) }
303 }
304
305 #[doc(alias = "g_drive_get_sort_key")]
311 #[doc(alias = "get_sort_key")]
312 fn sort_key(&self) -> Option<glib::GString> {
313 unsafe { from_glib_none(ffi::g_drive_get_sort_key(self.as_ref().to_glib_none().0)) }
314 }
315
316 #[doc(alias = "g_drive_get_start_stop_type")]
322 #[doc(alias = "get_start_stop_type")]
323 fn start_stop_type(&self) -> DriveStartStopType {
324 unsafe {
325 from_glib(ffi::g_drive_get_start_stop_type(
326 self.as_ref().to_glib_none().0,
327 ))
328 }
329 }
330
331 #[doc(alias = "g_drive_get_symbolic_icon")]
338 #[doc(alias = "get_symbolic_icon")]
339 fn symbolic_icon(&self) -> Icon {
340 unsafe {
341 from_glib_full(ffi::g_drive_get_symbolic_icon(
342 self.as_ref().to_glib_none().0,
343 ))
344 }
345 }
346
347 #[doc(alias = "g_drive_get_volumes")]
356 #[doc(alias = "get_volumes")]
357 fn volumes(&self) -> Vec<Volume> {
358 unsafe {
359 FromGlibPtrContainer::from_glib_full(ffi::g_drive_get_volumes(
360 self.as_ref().to_glib_none().0,
361 ))
362 }
363 }
364
365 #[doc(alias = "g_drive_has_media")]
373 fn has_media(&self) -> bool {
374 unsafe { from_glib(ffi::g_drive_has_media(self.as_ref().to_glib_none().0)) }
375 }
376
377 #[doc(alias = "g_drive_has_volumes")]
383 fn has_volumes(&self) -> bool {
384 unsafe { from_glib(ffi::g_drive_has_volumes(self.as_ref().to_glib_none().0)) }
385 }
386
387 #[doc(alias = "g_drive_is_media_check_automatic")]
394 fn is_media_check_automatic(&self) -> bool {
395 unsafe {
396 from_glib(ffi::g_drive_is_media_check_automatic(
397 self.as_ref().to_glib_none().0,
398 ))
399 }
400 }
401
402 #[doc(alias = "g_drive_is_media_removable")]
408 fn is_media_removable(&self) -> bool {
409 unsafe {
410 from_glib(ffi::g_drive_is_media_removable(
411 self.as_ref().to_glib_none().0,
412 ))
413 }
414 }
415
416 #[doc(alias = "g_drive_is_removable")]
423 fn is_removable(&self) -> bool {
424 unsafe { from_glib(ffi::g_drive_is_removable(self.as_ref().to_glib_none().0)) }
425 }
426
427 #[doc(alias = "g_drive_poll_for_media")]
437 fn poll_for_media<P: FnOnce(Result<(), glib::Error>) + 'static>(
438 &self,
439 cancellable: Option<&impl IsA<Cancellable>>,
440 callback: P,
441 ) {
442 let main_context = glib::MainContext::ref_thread_default();
443 let is_main_context_owner = main_context.is_owner();
444 let has_acquired_main_context = (!is_main_context_owner)
445 .then(|| main_context.acquire().ok())
446 .flatten();
447 assert!(
448 is_main_context_owner || has_acquired_main_context.is_some(),
449 "Async operations only allowed if the thread is owning the MainContext"
450 );
451
452 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
453 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
454 unsafe extern "C" fn poll_for_media_trampoline<
455 P: FnOnce(Result<(), glib::Error>) + 'static,
456 >(
457 _source_object: *mut glib::gobject_ffi::GObject,
458 res: *mut crate::ffi::GAsyncResult,
459 user_data: glib::ffi::gpointer,
460 ) {
461 let mut error = std::ptr::null_mut();
462 ffi::g_drive_poll_for_media_finish(_source_object as *mut _, res, &mut error);
463 let result = if error.is_null() {
464 Ok(())
465 } else {
466 Err(from_glib_full(error))
467 };
468 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
469 Box_::from_raw(user_data as *mut _);
470 let callback: P = callback.into_inner();
471 callback(result);
472 }
473 let callback = poll_for_media_trampoline::<P>;
474 unsafe {
475 ffi::g_drive_poll_for_media(
476 self.as_ref().to_glib_none().0,
477 cancellable.map(|p| p.as_ref()).to_glib_none().0,
478 Some(callback),
479 Box_::into_raw(user_data) as *mut _,
480 );
481 }
482 }
483
484 fn poll_for_media_future(
485 &self,
486 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
487 Box_::pin(crate::GioFuture::new(
488 self,
489 move |obj, cancellable, send| {
490 obj.poll_for_media(Some(cancellable), move |res| {
491 send.resolve(res);
492 });
493 },
494 ))
495 }
496
497 #[doc(alias = "g_drive_start")]
512 fn start<P: FnOnce(Result<(), glib::Error>) + 'static>(
513 &self,
514 flags: DriveStartFlags,
515 mount_operation: Option<&impl IsA<MountOperation>>,
516 cancellable: Option<&impl IsA<Cancellable>>,
517 callback: P,
518 ) {
519 let main_context = glib::MainContext::ref_thread_default();
520 let is_main_context_owner = main_context.is_owner();
521 let has_acquired_main_context = (!is_main_context_owner)
522 .then(|| main_context.acquire().ok())
523 .flatten();
524 assert!(
525 is_main_context_owner || has_acquired_main_context.is_some(),
526 "Async operations only allowed if the thread is owning the MainContext"
527 );
528
529 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
530 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
531 unsafe extern "C" fn start_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
532 _source_object: *mut glib::gobject_ffi::GObject,
533 res: *mut crate::ffi::GAsyncResult,
534 user_data: glib::ffi::gpointer,
535 ) {
536 let mut error = std::ptr::null_mut();
537 ffi::g_drive_start_finish(_source_object as *mut _, res, &mut error);
538 let result = if error.is_null() {
539 Ok(())
540 } else {
541 Err(from_glib_full(error))
542 };
543 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
544 Box_::from_raw(user_data as *mut _);
545 let callback: P = callback.into_inner();
546 callback(result);
547 }
548 let callback = start_trampoline::<P>;
549 unsafe {
550 ffi::g_drive_start(
551 self.as_ref().to_glib_none().0,
552 flags.into_glib(),
553 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
554 cancellable.map(|p| p.as_ref()).to_glib_none().0,
555 Some(callback),
556 Box_::into_raw(user_data) as *mut _,
557 );
558 }
559 }
560
561 fn start_future(
562 &self,
563 flags: DriveStartFlags,
564 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
565 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
566 let mount_operation = mount_operation.map(ToOwned::to_owned);
567 Box_::pin(crate::GioFuture::new(
568 self,
569 move |obj, cancellable, send| {
570 obj.start(
571 flags,
572 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
573 Some(cancellable),
574 move |res| {
575 send.resolve(res);
576 },
577 );
578 },
579 ))
580 }
581
582 #[doc(alias = "g_drive_stop")]
597 fn stop<P: FnOnce(Result<(), glib::Error>) + 'static>(
598 &self,
599 flags: MountUnmountFlags,
600 mount_operation: Option<&impl IsA<MountOperation>>,
601 cancellable: Option<&impl IsA<Cancellable>>,
602 callback: P,
603 ) {
604 let main_context = glib::MainContext::ref_thread_default();
605 let is_main_context_owner = main_context.is_owner();
606 let has_acquired_main_context = (!is_main_context_owner)
607 .then(|| main_context.acquire().ok())
608 .flatten();
609 assert!(
610 is_main_context_owner || has_acquired_main_context.is_some(),
611 "Async operations only allowed if the thread is owning the MainContext"
612 );
613
614 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
615 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
616 unsafe extern "C" fn stop_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
617 _source_object: *mut glib::gobject_ffi::GObject,
618 res: *mut crate::ffi::GAsyncResult,
619 user_data: glib::ffi::gpointer,
620 ) {
621 let mut error = std::ptr::null_mut();
622 ffi::g_drive_stop_finish(_source_object as *mut _, res, &mut error);
623 let result = if error.is_null() {
624 Ok(())
625 } else {
626 Err(from_glib_full(error))
627 };
628 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
629 Box_::from_raw(user_data as *mut _);
630 let callback: P = callback.into_inner();
631 callback(result);
632 }
633 let callback = stop_trampoline::<P>;
634 unsafe {
635 ffi::g_drive_stop(
636 self.as_ref().to_glib_none().0,
637 flags.into_glib(),
638 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
639 cancellable.map(|p| p.as_ref()).to_glib_none().0,
640 Some(callback),
641 Box_::into_raw(user_data) as *mut _,
642 );
643 }
644 }
645
646 fn stop_future(
647 &self,
648 flags: MountUnmountFlags,
649 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
650 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
651 let mount_operation = mount_operation.map(ToOwned::to_owned);
652 Box_::pin(crate::GioFuture::new(
653 self,
654 move |obj, cancellable, send| {
655 obj.stop(
656 flags,
657 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
658 Some(cancellable),
659 move |res| {
660 send.resolve(res);
661 },
662 );
663 },
664 ))
665 }
666
667 #[doc(alias = "changed")]
669 fn connect_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
670 unsafe extern "C" fn changed_trampoline<P: IsA<Drive>, F: Fn(&P) + 'static>(
671 this: *mut ffi::GDrive,
672 f: glib::ffi::gpointer,
673 ) {
674 let f: &F = &*(f as *const F);
675 f(Drive::from_glib_borrow(this).unsafe_cast_ref())
676 }
677 unsafe {
678 let f: Box_<F> = Box_::new(f);
679 connect_raw(
680 self.as_ptr() as *mut _,
681 c"changed".as_ptr() as *const _,
682 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
683 changed_trampoline::<Self, F> as *const (),
684 )),
685 Box_::into_raw(f),
686 )
687 }
688 }
689
690 #[doc(alias = "disconnected")]
695 fn connect_disconnected<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
696 unsafe extern "C" fn disconnected_trampoline<P: IsA<Drive>, F: Fn(&P) + 'static>(
697 this: *mut ffi::GDrive,
698 f: glib::ffi::gpointer,
699 ) {
700 let f: &F = &*(f as *const F);
701 f(Drive::from_glib_borrow(this).unsafe_cast_ref())
702 }
703 unsafe {
704 let f: Box_<F> = Box_::new(f);
705 connect_raw(
706 self.as_ptr() as *mut _,
707 c"disconnected".as_ptr() as *const _,
708 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
709 disconnected_trampoline::<Self, F> as *const (),
710 )),
711 Box_::into_raw(f),
712 )
713 }
714 }
715
716 #[doc(alias = "eject-button")]
719 fn connect_eject_button<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
720 unsafe extern "C" fn eject_button_trampoline<P: IsA<Drive>, F: Fn(&P) + 'static>(
721 this: *mut ffi::GDrive,
722 f: glib::ffi::gpointer,
723 ) {
724 let f: &F = &*(f as *const F);
725 f(Drive::from_glib_borrow(this).unsafe_cast_ref())
726 }
727 unsafe {
728 let f: Box_<F> = Box_::new(f);
729 connect_raw(
730 self.as_ptr() as *mut _,
731 c"eject-button".as_ptr() as *const _,
732 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
733 eject_button_trampoline::<Self, F> as *const (),
734 )),
735 Box_::into_raw(f),
736 )
737 }
738 }
739
740 #[doc(alias = "stop-button")]
743 fn connect_stop_button<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
744 unsafe extern "C" fn stop_button_trampoline<P: IsA<Drive>, F: Fn(&P) + 'static>(
745 this: *mut ffi::GDrive,
746 f: glib::ffi::gpointer,
747 ) {
748 let f: &F = &*(f as *const F);
749 f(Drive::from_glib_borrow(this).unsafe_cast_ref())
750 }
751 unsafe {
752 let f: Box_<F> = Box_::new(f);
753 connect_raw(
754 self.as_ptr() as *mut _,
755 c"stop-button".as_ptr() as *const _,
756 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
757 stop_button_trampoline::<Self, F> as *const (),
758 )),
759 Box_::into_raw(f),
760 )
761 }
762 }
763}
764
765impl<O: IsA<Drive>> DriveExt for O {}