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_sys;
14use gobject_sys;
15use std::boxed::Box as Box_;
16use std::fmt;
17use std::mem::transmute;
18use std::ptr;
19use Cancellable;
20use Error;
21
22glib_wrapper! {
23 pub struct Permission(Object<gio_sys::GPermission, gio_sys::GPermissionClass, PermissionClass>);
24
25 match fn {
26 get_type => || gio_sys::g_permission_get_type(),
27 }
28}
29
30pub const NONE_PERMISSION: Option<&Permission> = None;
31
32pub trait PermissionExt: 'static {
33 fn acquire<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error>;
34
35 fn acquire_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
36 &self,
37 cancellable: Option<&P>,
38 callback: Q,
39 );
40
41 #[cfg(feature = "futures")]
42 fn acquire_async_future(
43 &self,
44 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
45
46 fn get_allowed(&self) -> bool;
47
48 fn get_can_acquire(&self) -> bool;
49
50 fn get_can_release(&self) -> bool;
51
52 fn impl_update(&self, allowed: bool, can_acquire: bool, can_release: bool);
53
54 fn release<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error>;
55
56 fn release_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
57 &self,
58 cancellable: Option<&P>,
59 callback: Q,
60 );
61
62 #[cfg(feature = "futures")]
63 fn release_async_future(
64 &self,
65 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
66
67 fn connect_property_allowed_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
68
69 fn connect_property_can_acquire_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
70
71 fn connect_property_can_release_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
72}
73
74impl<O: IsA<Permission>> PermissionExt for O {
75 fn acquire<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error> {
76 unsafe {
77 let mut error = ptr::null_mut();
78 let _ = gio_sys::g_permission_acquire(
79 self.as_ref().to_glib_none().0,
80 cancellable.map(|p| p.as_ref()).to_glib_none().0,
81 &mut error,
82 );
83 if error.is_null() {
84 Ok(())
85 } else {
86 Err(from_glib_full(error))
87 }
88 }
89 }
90
91 fn acquire_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
92 &self,
93 cancellable: Option<&P>,
94 callback: Q,
95 ) {
96 let user_data: Box<Q> = Box::new(callback);
97 unsafe extern "C" fn acquire_async_trampoline<
98 Q: FnOnce(Result<(), Error>) + Send + 'static,
99 >(
100 _source_object: *mut gobject_sys::GObject,
101 res: *mut gio_sys::GAsyncResult,
102 user_data: glib_sys::gpointer,
103 ) {
104 let mut error = ptr::null_mut();
105 let _ = gio_sys::g_permission_acquire_finish(_source_object as *mut _, res, &mut error);
106 let result = if error.is_null() {
107 Ok(())
108 } else {
109 Err(from_glib_full(error))
110 };
111 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
112 callback(result);
113 }
114 let callback = acquire_async_trampoline::<Q>;
115 unsafe {
116 gio_sys::g_permission_acquire_async(
117 self.as_ref().to_glib_none().0,
118 cancellable.map(|p| p.as_ref()).to_glib_none().0,
119 Some(callback),
120 Box::into_raw(user_data) as *mut _,
121 );
122 }
123 }
124
125 #[cfg(feature = "futures")]
126 fn acquire_async_future(
127 &self,
128 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
129 use fragile::Fragile;
130 use GioFuture;
131
132 GioFuture::new(self, move |obj, send| {
133 let cancellable = Cancellable::new();
134 let send = Fragile::new(send);
135 obj.acquire_async(Some(&cancellable), move |res| {
136 let _ = send.into_inner().send(res);
137 });
138
139 cancellable
140 })
141 }
142
143 fn get_allowed(&self) -> bool {
144 unsafe {
145 from_glib(gio_sys::g_permission_get_allowed(
146 self.as_ref().to_glib_none().0,
147 ))
148 }
149 }
150
151 fn get_can_acquire(&self) -> bool {
152 unsafe {
153 from_glib(gio_sys::g_permission_get_can_acquire(
154 self.as_ref().to_glib_none().0,
155 ))
156 }
157 }
158
159 fn get_can_release(&self) -> bool {
160 unsafe {
161 from_glib(gio_sys::g_permission_get_can_release(
162 self.as_ref().to_glib_none().0,
163 ))
164 }
165 }
166
167 fn impl_update(&self, allowed: bool, can_acquire: bool, can_release: bool) {
168 unsafe {
169 gio_sys::g_permission_impl_update(
170 self.as_ref().to_glib_none().0,
171 allowed.to_glib(),
172 can_acquire.to_glib(),
173 can_release.to_glib(),
174 );
175 }
176 }
177
178 fn release<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error> {
179 unsafe {
180 let mut error = ptr::null_mut();
181 let _ = gio_sys::g_permission_release(
182 self.as_ref().to_glib_none().0,
183 cancellable.map(|p| p.as_ref()).to_glib_none().0,
184 &mut error,
185 );
186 if error.is_null() {
187 Ok(())
188 } else {
189 Err(from_glib_full(error))
190 }
191 }
192 }
193
194 fn release_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
195 &self,
196 cancellable: Option<&P>,
197 callback: Q,
198 ) {
199 let user_data: Box<Q> = Box::new(callback);
200 unsafe extern "C" fn release_async_trampoline<
201 Q: FnOnce(Result<(), Error>) + Send + 'static,
202 >(
203 _source_object: *mut gobject_sys::GObject,
204 res: *mut gio_sys::GAsyncResult,
205 user_data: glib_sys::gpointer,
206 ) {
207 let mut error = ptr::null_mut();
208 let _ = gio_sys::g_permission_release_finish(_source_object as *mut _, res, &mut error);
209 let result = if error.is_null() {
210 Ok(())
211 } else {
212 Err(from_glib_full(error))
213 };
214 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
215 callback(result);
216 }
217 let callback = release_async_trampoline::<Q>;
218 unsafe {
219 gio_sys::g_permission_release_async(
220 self.as_ref().to_glib_none().0,
221 cancellable.map(|p| p.as_ref()).to_glib_none().0,
222 Some(callback),
223 Box::into_raw(user_data) as *mut _,
224 );
225 }
226 }
227
228 #[cfg(feature = "futures")]
229 fn release_async_future(
230 &self,
231 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
232 use fragile::Fragile;
233 use GioFuture;
234
235 GioFuture::new(self, move |obj, send| {
236 let cancellable = Cancellable::new();
237 let send = Fragile::new(send);
238 obj.release_async(Some(&cancellable), move |res| {
239 let _ = send.into_inner().send(res);
240 });
241
242 cancellable
243 })
244 }
245
246 fn connect_property_allowed_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
247 unsafe extern "C" fn notify_allowed_trampoline<P, F: Fn(&P) + 'static>(
248 this: *mut gio_sys::GPermission,
249 _param_spec: glib_sys::gpointer,
250 f: glib_sys::gpointer,
251 ) where
252 P: IsA<Permission>,
253 {
254 let f: &F = &*(f as *const F);
255 f(&Permission::from_glib_borrow(this).unsafe_cast())
256 }
257 unsafe {
258 let f: Box_<F> = Box_::new(f);
259 connect_raw(
260 self.as_ptr() as *mut _,
261 b"notify::allowed\0".as_ptr() as *const _,
262 Some(transmute(notify_allowed_trampoline::<Self, F> as usize)),
263 Box_::into_raw(f),
264 )
265 }
266 }
267
268 fn connect_property_can_acquire_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
269 unsafe extern "C" fn notify_can_acquire_trampoline<P, F: Fn(&P) + 'static>(
270 this: *mut gio_sys::GPermission,
271 _param_spec: glib_sys::gpointer,
272 f: glib_sys::gpointer,
273 ) where
274 P: IsA<Permission>,
275 {
276 let f: &F = &*(f as *const F);
277 f(&Permission::from_glib_borrow(this).unsafe_cast())
278 }
279 unsafe {
280 let f: Box_<F> = Box_::new(f);
281 connect_raw(
282 self.as_ptr() as *mut _,
283 b"notify::can-acquire\0".as_ptr() as *const _,
284 Some(transmute(notify_can_acquire_trampoline::<Self, F> as usize)),
285 Box_::into_raw(f),
286 )
287 }
288 }
289
290 fn connect_property_can_release_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
291 unsafe extern "C" fn notify_can_release_trampoline<P, F: Fn(&P) + 'static>(
292 this: *mut gio_sys::GPermission,
293 _param_spec: glib_sys::gpointer,
294 f: glib_sys::gpointer,
295 ) where
296 P: IsA<Permission>,
297 {
298 let f: &F = &*(f as *const F);
299 f(&Permission::from_glib_borrow(this).unsafe_cast())
300 }
301 unsafe {
302 let f: Box_<F> = Box_::new(f);
303 connect_raw(
304 self.as_ptr() as *mut _,
305 b"notify::can-release\0".as_ptr() as *const _,
306 Some(transmute(notify_can_release_trampoline::<Self, F> as usize)),
307 Box_::into_raw(f),
308 )
309 }
310 }
311}
312
313impl fmt::Display for Permission {
314 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
315 write!(f, "Permission")
316 }
317}