nm_rs/
remote_connection.rs1use std::pin::Pin;
2
3use glib::object::IsA;
4use glib::translate::FromGlibPtrFull;
5use glib::translate::ToGlibPtr;
6use glib::translate::from_glib_full;
7
8use crate::RemoteConnection;
9use crate::ffi;
10
11pub trait RemoteConnectionExtManual:
12 IsA<RemoteConnection, GlibType = crate::ffi::NMRemoteConnection>
13{
14 #[doc(alias = "nm_remote_connection_get_secrets")]
15 #[doc(alias = "get_secrets")]
16 fn secrets(
17 &self,
18 setting_name: &str,
19 cancellable: Option<&impl IsA<gio::Cancellable>>,
20 ) -> Result<glib::Variant, glib::Error> {
21 unsafe {
22 let mut error = std::ptr::null_mut();
23 let res = ffi::nm_remote_connection_get_secrets(
24 self.to_glib_none().0,
25 setting_name.to_glib_none().0,
26 cancellable.map(|p| p.as_ref()).to_glib_none().0,
27 &mut error,
28 );
29
30 if error.is_null() {
31 Ok(glib::Variant::from_glib_full(res))
32 } else {
33 Err(glib::Error::from_glib_full(error))
34 }
35 }
36 }
37
38 #[doc(alias = "nm_remote_connection_get_secrets_async")]
39 #[doc(alias = "get_secrets_async")]
40 fn secrets_async<P: FnOnce(Result<glib::Variant, glib::Error>) + 'static>(
41 &self,
42 setting_name: &str,
43 cancellable: Option<&impl IsA<gio::Cancellable>>,
44 callback: P,
45 ) {
46 let main_context = glib::MainContext::ref_thread_default();
47 let is_main_context_owner = main_context.is_owner();
48 let has_acquired_main_context = (!is_main_context_owner)
49 .then(|| main_context.acquire().ok())
50 .flatten();
51 assert!(
52 is_main_context_owner || has_acquired_main_context.is_some(),
53 "Async operations only allowed if the thread is owning the MainContext"
54 );
55
56 let user_data: Box<glib::thread_guard::ThreadGuard<P>> =
57 Box::new(glib::thread_guard::ThreadGuard::new(callback));
58
59 unsafe extern "C" fn secrets_async_trampoline<
60 P: FnOnce(Result<glib::Variant, glib::Error>) + 'static,
61 >(
62 _connection: *mut glib::gobject_ffi::GObject,
63 res: *mut gio::ffi::GAsyncResult,
64 user_data: glib::ffi::gpointer,
65 ) {
66 let mut error = std::ptr::null_mut();
67 let ret = ffi::nm_remote_connection_get_secrets_finish(
68 _connection as *mut _,
69 res,
70 &mut error,
71 );
72 let result = if error.is_null() {
73 Ok(from_glib_full(ret))
74 } else {
75 Err(from_glib_full(error))
76 };
77 let callback: Box<glib::thread_guard::ThreadGuard<P>> =
78 Box::from_raw(user_data as *mut _);
79 let callback: P = callback.into_inner();
80 callback(result);
81 }
82 let callback = secrets_async_trampoline::<P>;
83 unsafe {
84 ffi::nm_remote_connection_get_secrets_async(
85 self.as_ref().to_glib_none().0,
86 setting_name.to_glib_none().0,
87 cancellable.map(|p| p.as_ref()).to_glib_none().0,
88 Some(callback),
89 Box::into_raw(user_data) as *mut _,
90 );
91 }
92 }
93
94 fn secrets_future(
95 &self,
96 setting_name: &str,
97 ) -> Pin<Box<dyn std::future::Future<Output = Result<glib::Variant, glib::Error>> + 'static>>
98 {
99 let setting_name = String::from(setting_name);
100 Box::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
101 obj.secrets_async(&setting_name, Some(cancellable), move |res| {
102 send.resolve(res);
103 });
104 }))
105 }
106}
107
108impl<T: IsA<RemoteConnection, GlibType = ffi::NMRemoteConnection>> RemoteConnectionExtManual for T {}