1use crate::{AsyncResult, Cancellable, ffi};
6use glib::{
7 prelude::*,
8 signal::{SignalHandlerId, connect_raw},
9 translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "GPermission")]
46 pub struct Permission(Object<ffi::GPermission, ffi::GPermissionClass>);
47
48 match fn {
49 type_ => || ffi::g_permission_get_type(),
50 }
51}
52
53impl Permission {
54 pub const NONE: Option<&'static Permission> = None;
55}
56
57pub trait PermissionExt: IsA<Permission> + 'static {
63 #[doc(alias = "g_permission_acquire")]
85 fn acquire(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
86 unsafe {
87 let mut error = std::ptr::null_mut();
88 let is_ok = ffi::g_permission_acquire(
89 self.as_ref().to_glib_none().0,
90 cancellable.map(|p| p.as_ref()).to_glib_none().0,
91 &mut error,
92 );
93 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
94 if error.is_null() {
95 Ok(())
96 } else {
97 Err(from_glib_full(error))
98 }
99 }
100 }
101
102 #[doc(alias = "g_permission_acquire_async")]
111 fn acquire_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
112 &self,
113 cancellable: Option<&impl IsA<Cancellable>>,
114 callback: P,
115 ) {
116 let main_context = glib::MainContext::ref_thread_default();
117 let is_main_context_owner = main_context.is_owner();
118 let has_acquired_main_context = (!is_main_context_owner)
119 .then(|| main_context.acquire().ok())
120 .flatten();
121 assert!(
122 is_main_context_owner || has_acquired_main_context.is_some(),
123 "Async operations only allowed if the thread is owning the MainContext"
124 );
125
126 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
127 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
128 unsafe extern "C" fn acquire_async_trampoline<
129 P: FnOnce(Result<(), glib::Error>) + 'static,
130 >(
131 _source_object: *mut glib::gobject_ffi::GObject,
132 res: *mut crate::ffi::GAsyncResult,
133 user_data: glib::ffi::gpointer,
134 ) {
135 unsafe {
136 let mut error = std::ptr::null_mut();
137 ffi::g_permission_acquire_finish(_source_object as *mut _, res, &mut error);
138 let result = if error.is_null() {
139 Ok(())
140 } else {
141 Err(from_glib_full(error))
142 };
143 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
144 Box_::from_raw(user_data as *mut _);
145 let callback: P = callback.into_inner();
146 callback(result);
147 }
148 }
149 let callback = acquire_async_trampoline::<P>;
150 unsafe {
151 ffi::g_permission_acquire_async(
152 self.as_ref().to_glib_none().0,
153 cancellable.map(|p| p.as_ref()).to_glib_none().0,
154 Some(callback),
155 Box_::into_raw(user_data) as *mut _,
156 );
157 }
158 }
159
160 fn acquire_future(
161 &self,
162 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
163 Box_::pin(crate::GioFuture::new(
164 self,
165 move |obj, cancellable, send| {
166 obj.acquire_async(Some(cancellable), move |res| {
167 send.resolve(res);
168 });
169 },
170 ))
171 }
172
173 #[doc(alias = "g_permission_get_allowed")]
181 #[doc(alias = "get_allowed")]
182 #[doc(alias = "allowed")]
183 fn is_allowed(&self) -> bool {
184 unsafe {
185 from_glib(ffi::g_permission_get_allowed(
186 self.as_ref().to_glib_none().0,
187 ))
188 }
189 }
190
191 #[doc(alias = "g_permission_get_can_acquire")]
199 #[doc(alias = "get_can_acquire")]
200 #[doc(alias = "can-acquire")]
201 fn can_acquire(&self) -> bool {
202 unsafe {
203 from_glib(ffi::g_permission_get_can_acquire(
204 self.as_ref().to_glib_none().0,
205 ))
206 }
207 }
208
209 #[doc(alias = "g_permission_get_can_release")]
217 #[doc(alias = "get_can_release")]
218 #[doc(alias = "can-release")]
219 fn can_release(&self) -> bool {
220 unsafe {
221 from_glib(ffi::g_permission_get_can_release(
222 self.as_ref().to_glib_none().0,
223 ))
224 }
225 }
226
227 #[doc(alias = "g_permission_impl_update")]
239 fn impl_update(&self, allowed: bool, can_acquire: bool, can_release: bool) {
240 unsafe {
241 ffi::g_permission_impl_update(
242 self.as_ref().to_glib_none().0,
243 allowed.into_glib(),
244 can_acquire.into_glib(),
245 can_release.into_glib(),
246 );
247 }
248 }
249
250 #[doc(alias = "g_permission_release")]
272 fn release(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
273 unsafe {
274 let mut error = std::ptr::null_mut();
275 let is_ok = ffi::g_permission_release(
276 self.as_ref().to_glib_none().0,
277 cancellable.map(|p| p.as_ref()).to_glib_none().0,
278 &mut error,
279 );
280 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
281 if error.is_null() {
282 Ok(())
283 } else {
284 Err(from_glib_full(error))
285 }
286 }
287 }
288
289 #[doc(alias = "g_permission_release_async")]
298 fn release_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
299 &self,
300 cancellable: Option<&impl IsA<Cancellable>>,
301 callback: P,
302 ) {
303 let main_context = glib::MainContext::ref_thread_default();
304 let is_main_context_owner = main_context.is_owner();
305 let has_acquired_main_context = (!is_main_context_owner)
306 .then(|| main_context.acquire().ok())
307 .flatten();
308 assert!(
309 is_main_context_owner || has_acquired_main_context.is_some(),
310 "Async operations only allowed if the thread is owning the MainContext"
311 );
312
313 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
314 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
315 unsafe extern "C" fn release_async_trampoline<
316 P: FnOnce(Result<(), glib::Error>) + 'static,
317 >(
318 _source_object: *mut glib::gobject_ffi::GObject,
319 res: *mut crate::ffi::GAsyncResult,
320 user_data: glib::ffi::gpointer,
321 ) {
322 unsafe {
323 let mut error = std::ptr::null_mut();
324 ffi::g_permission_release_finish(_source_object as *mut _, res, &mut error);
325 let result = if error.is_null() {
326 Ok(())
327 } else {
328 Err(from_glib_full(error))
329 };
330 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
331 Box_::from_raw(user_data as *mut _);
332 let callback: P = callback.into_inner();
333 callback(result);
334 }
335 }
336 let callback = release_async_trampoline::<P>;
337 unsafe {
338 ffi::g_permission_release_async(
339 self.as_ref().to_glib_none().0,
340 cancellable.map(|p| p.as_ref()).to_glib_none().0,
341 Some(callback),
342 Box_::into_raw(user_data) as *mut _,
343 );
344 }
345 }
346
347 fn release_future(
348 &self,
349 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
350 Box_::pin(crate::GioFuture::new(
351 self,
352 move |obj, cancellable, send| {
353 obj.release_async(Some(cancellable), move |res| {
354 send.resolve(res);
355 });
356 },
357 ))
358 }
359
360 #[doc(alias = "allowed")]
361 fn connect_allowed_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
362 unsafe extern "C" fn notify_allowed_trampoline<P: IsA<Permission>, F: Fn(&P) + 'static>(
363 this: *mut ffi::GPermission,
364 _param_spec: glib::ffi::gpointer,
365 f: glib::ffi::gpointer,
366 ) {
367 unsafe {
368 let f: &F = &*(f as *const F);
369 f(Permission::from_glib_borrow(this).unsafe_cast_ref())
370 }
371 }
372 unsafe {
373 let f: Box_<F> = Box_::new(f);
374 connect_raw(
375 self.as_ptr() as *mut _,
376 c"notify::allowed".as_ptr(),
377 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
378 notify_allowed_trampoline::<Self, F> as *const (),
379 )),
380 Box_::into_raw(f),
381 )
382 }
383 }
384
385 #[doc(alias = "can-acquire")]
386 fn connect_can_acquire_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
387 unsafe extern "C" fn notify_can_acquire_trampoline<
388 P: IsA<Permission>,
389 F: Fn(&P) + 'static,
390 >(
391 this: *mut ffi::GPermission,
392 _param_spec: glib::ffi::gpointer,
393 f: glib::ffi::gpointer,
394 ) {
395 unsafe {
396 let f: &F = &*(f as *const F);
397 f(Permission::from_glib_borrow(this).unsafe_cast_ref())
398 }
399 }
400 unsafe {
401 let f: Box_<F> = Box_::new(f);
402 connect_raw(
403 self.as_ptr() as *mut _,
404 c"notify::can-acquire".as_ptr(),
405 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
406 notify_can_acquire_trampoline::<Self, F> as *const (),
407 )),
408 Box_::into_raw(f),
409 )
410 }
411 }
412
413 #[doc(alias = "can-release")]
414 fn connect_can_release_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
415 unsafe extern "C" fn notify_can_release_trampoline<
416 P: IsA<Permission>,
417 F: Fn(&P) + 'static,
418 >(
419 this: *mut ffi::GPermission,
420 _param_spec: glib::ffi::gpointer,
421 f: glib::ffi::gpointer,
422 ) {
423 unsafe {
424 let f: &F = &*(f as *const F);
425 f(Permission::from_glib_borrow(this).unsafe_cast_ref())
426 }
427 }
428 unsafe {
429 let f: Box_<F> = Box_::new(f);
430 connect_raw(
431 self.as_ptr() as *mut _,
432 c"notify::can-release".as_ptr(),
433 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
434 notify_can_release_trampoline::<Self, F> as *const (),
435 )),
436 Box_::into_raw(f),
437 )
438 }
439 }
440}
441
442impl<O: IsA<Permission>> PermissionExt for O {}