1use crate::{
6 AsyncResult, Cancellable, Drive, File, Icon, Mount, MountMountFlags, MountOperation,
7 MountUnmountFlags, ffi,
8};
9use glib::{
10 object::ObjectType as _,
11 prelude::*,
12 signal::{SignalHandlerId, connect_raw},
13 translate::*,
14};
15use std::{boxed::Box as Box_, pin::Pin};
16
17glib::wrapper! {
18 #[doc(alias = "GVolume")]
51 pub struct Volume(Interface<ffi::GVolume, ffi::GVolumeIface>);
52
53 match fn {
54 type_ => || ffi::g_volume_get_type(),
55 }
56}
57
58impl Volume {
59 pub const NONE: Option<&'static Volume> = None;
60}
61
62pub trait VolumeExt: IsA<Volume> + 'static {
68 #[doc(alias = "g_volume_can_eject")]
74 fn can_eject(&self) -> bool {
75 unsafe { from_glib(ffi::g_volume_can_eject(self.as_ref().to_glib_none().0)) }
76 }
77
78 #[doc(alias = "g_volume_can_mount")]
84 fn can_mount(&self) -> bool {
85 unsafe { from_glib(ffi::g_volume_can_mount(self.as_ref().to_glib_none().0)) }
86 }
87
88 #[doc(alias = "g_volume_eject_with_operation")]
101 fn eject_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
102 &self,
103 flags: MountUnmountFlags,
104 mount_operation: Option<&impl IsA<MountOperation>>,
105 cancellable: Option<&impl IsA<Cancellable>>,
106 callback: P,
107 ) {
108 let main_context = glib::MainContext::ref_thread_default();
109 let is_main_context_owner = main_context.is_owner();
110 let has_acquired_main_context = (!is_main_context_owner)
111 .then(|| main_context.acquire().ok())
112 .flatten();
113 assert!(
114 is_main_context_owner || has_acquired_main_context.is_some(),
115 "Async operations only allowed if the thread is owning the MainContext"
116 );
117
118 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
119 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
120 unsafe extern "C" fn eject_with_operation_trampoline<
121 P: FnOnce(Result<(), glib::Error>) + 'static,
122 >(
123 _source_object: *mut glib::gobject_ffi::GObject,
124 res: *mut crate::ffi::GAsyncResult,
125 user_data: glib::ffi::gpointer,
126 ) {
127 unsafe {
128 let mut error = std::ptr::null_mut();
129 ffi::g_volume_eject_with_operation_finish(
130 _source_object as *mut _,
131 res,
132 &mut error,
133 );
134 let result = if error.is_null() {
135 Ok(())
136 } else {
137 Err(from_glib_full(error))
138 };
139 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
140 Box_::from_raw(user_data as *mut _);
141 let callback: P = callback.into_inner();
142 callback(result);
143 }
144 }
145 let callback = eject_with_operation_trampoline::<P>;
146 unsafe {
147 ffi::g_volume_eject_with_operation(
148 self.as_ref().to_glib_none().0,
149 flags.into_glib(),
150 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
151 cancellable.map(|p| p.as_ref()).to_glib_none().0,
152 Some(callback),
153 Box_::into_raw(user_data) as *mut _,
154 );
155 }
156 }
157
158 fn eject_with_operation_future(
159 &self,
160 flags: MountUnmountFlags,
161 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
162 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
163 let mount_operation = mount_operation.map(ToOwned::to_owned);
164 Box_::pin(crate::GioFuture::new(
165 self,
166 move |obj, cancellable, send| {
167 obj.eject_with_operation(
168 flags,
169 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
170 Some(cancellable),
171 move |res| {
172 send.resolve(res);
173 },
174 );
175 },
176 ))
177 }
178
179 #[doc(alias = "g_volume_enumerate_identifiers")]
187 fn enumerate_identifiers(&self) -> Vec<glib::GString> {
188 unsafe {
189 FromGlibPtrContainer::from_glib_full(ffi::g_volume_enumerate_identifiers(
190 self.as_ref().to_glib_none().0,
191 ))
192 }
193 }
194
195 #[doc(alias = "g_volume_get_activation_root")]
210 #[doc(alias = "get_activation_root")]
211 fn activation_root(&self) -> Option<File> {
212 unsafe {
213 from_glib_full(ffi::g_volume_get_activation_root(
214 self.as_ref().to_glib_none().0,
215 ))
216 }
217 }
218
219 #[doc(alias = "g_volume_get_drive")]
227 #[doc(alias = "get_drive")]
228 fn drive(&self) -> Option<Drive> {
229 unsafe { from_glib_full(ffi::g_volume_get_drive(self.as_ref().to_glib_none().0)) }
230 }
231
232 #[doc(alias = "g_volume_get_icon")]
240 #[doc(alias = "get_icon")]
241 fn icon(&self) -> Icon {
242 unsafe { from_glib_full(ffi::g_volume_get_icon(self.as_ref().to_glib_none().0)) }
243 }
244
245 #[doc(alias = "g_volume_get_identifier")]
257 #[doc(alias = "get_identifier")]
258 fn identifier(&self, kind: &str) -> Option<glib::GString> {
259 unsafe {
260 from_glib_full(ffi::g_volume_get_identifier(
261 self.as_ref().to_glib_none().0,
262 kind.to_glib_none().0,
263 ))
264 }
265 }
266
267 #[doc(alias = "g_volume_get_mount")]
275 fn get_mount(&self) -> Option<Mount> {
276 unsafe { from_glib_full(ffi::g_volume_get_mount(self.as_ref().to_glib_none().0)) }
277 }
278
279 #[doc(alias = "g_volume_get_name")]
286 #[doc(alias = "get_name")]
287 fn name(&self) -> glib::GString {
288 unsafe { from_glib_full(ffi::g_volume_get_name(self.as_ref().to_glib_none().0)) }
289 }
290
291 #[doc(alias = "g_volume_get_sort_key")]
297 #[doc(alias = "get_sort_key")]
298 fn sort_key(&self) -> Option<glib::GString> {
299 unsafe { from_glib_none(ffi::g_volume_get_sort_key(self.as_ref().to_glib_none().0)) }
300 }
301
302 #[doc(alias = "g_volume_get_symbolic_icon")]
310 #[doc(alias = "get_symbolic_icon")]
311 fn symbolic_icon(&self) -> Icon {
312 unsafe {
313 from_glib_full(ffi::g_volume_get_symbolic_icon(
314 self.as_ref().to_glib_none().0,
315 ))
316 }
317 }
318
319 #[doc(alias = "g_volume_get_uuid")]
331 #[doc(alias = "get_uuid")]
332 fn uuid(&self) -> Option<glib::GString> {
333 unsafe { from_glib_full(ffi::g_volume_get_uuid(self.as_ref().to_glib_none().0)) }
334 }
335
336 #[doc(alias = "g_volume_mount")]
348 fn mount<P: FnOnce(Result<(), glib::Error>) + 'static>(
349 &self,
350 flags: MountMountFlags,
351 mount_operation: Option<&impl IsA<MountOperation>>,
352 cancellable: Option<&impl IsA<Cancellable>>,
353 callback: P,
354 ) {
355 let main_context = glib::MainContext::ref_thread_default();
356 let is_main_context_owner = main_context.is_owner();
357 let has_acquired_main_context = (!is_main_context_owner)
358 .then(|| main_context.acquire().ok())
359 .flatten();
360 assert!(
361 is_main_context_owner || has_acquired_main_context.is_some(),
362 "Async operations only allowed if the thread is owning the MainContext"
363 );
364
365 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
366 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
367 unsafe extern "C" fn mount_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
368 _source_object: *mut glib::gobject_ffi::GObject,
369 res: *mut crate::ffi::GAsyncResult,
370 user_data: glib::ffi::gpointer,
371 ) {
372 unsafe {
373 let mut error = std::ptr::null_mut();
374 ffi::g_volume_mount_finish(_source_object as *mut _, res, &mut error);
375 let result = if error.is_null() {
376 Ok(())
377 } else {
378 Err(from_glib_full(error))
379 };
380 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
381 Box_::from_raw(user_data as *mut _);
382 let callback: P = callback.into_inner();
383 callback(result);
384 }
385 }
386 let callback = mount_trampoline::<P>;
387 unsafe {
388 ffi::g_volume_mount(
389 self.as_ref().to_glib_none().0,
390 flags.into_glib(),
391 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
392 cancellable.map(|p| p.as_ref()).to_glib_none().0,
393 Some(callback),
394 Box_::into_raw(user_data) as *mut _,
395 );
396 }
397 }
398
399 fn mount_future(
400 &self,
401 flags: MountMountFlags,
402 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
403 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
404 let mount_operation = mount_operation.map(ToOwned::to_owned);
405 Box_::pin(crate::GioFuture::new(
406 self,
407 move |obj, cancellable, send| {
408 obj.mount(
409 flags,
410 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
411 Some(cancellable),
412 move |res| {
413 send.resolve(res);
414 },
415 );
416 },
417 ))
418 }
419
420 #[doc(alias = "g_volume_should_automount")]
426 fn should_automount(&self) -> bool {
427 unsafe {
428 from_glib(ffi::g_volume_should_automount(
429 self.as_ref().to_glib_none().0,
430 ))
431 }
432 }
433
434 #[doc(alias = "changed")]
436 fn connect_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
437 unsafe extern "C" fn changed_trampoline<P: IsA<Volume>, F: Fn(&P) + 'static>(
438 this: *mut ffi::GVolume,
439 f: glib::ffi::gpointer,
440 ) {
441 unsafe {
442 let f: &F = &*(f as *const F);
443 f(Volume::from_glib_borrow(this).unsafe_cast_ref())
444 }
445 }
446 unsafe {
447 let f: Box_<F> = Box_::new(f);
448 connect_raw(
449 self.as_ptr() as *mut _,
450 c"changed".as_ptr(),
451 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
452 changed_trampoline::<Self, F> as *const (),
453 )),
454 Box_::into_raw(f),
455 )
456 }
457 }
458
459 #[doc(alias = "removed")]
463 fn connect_removed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
464 unsafe extern "C" fn removed_trampoline<P: IsA<Volume>, F: Fn(&P) + 'static>(
465 this: *mut ffi::GVolume,
466 f: glib::ffi::gpointer,
467 ) {
468 unsafe {
469 let f: &F = &*(f as *const F);
470 f(Volume::from_glib_borrow(this).unsafe_cast_ref())
471 }
472 }
473 unsafe {
474 let f: Box_<F> = Box_::new(f);
475 connect_raw(
476 self.as_ptr() as *mut _,
477 c"removed".as_ptr(),
478 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
479 removed_trampoline::<Self, F> as *const (),
480 )),
481 Box_::into_raw(f),
482 )
483 }
484 }
485}
486
487impl<O: IsA<Volume>> VolumeExt for O {}