1use crate::{
6 AsyncResult, Cancellable, TlsCertificateRequestFlags, TlsConnection, TlsInteractionResult,
7 TlsPassword, ffi,
8};
9use glib::{prelude::*, translate::*};
10use std::{boxed::Box as Box_, pin::Pin};
11
12glib::wrapper! {
13 #[doc(alias = "GTlsInteraction")]
14 pub struct TlsInteraction(Object<ffi::GTlsInteraction, ffi::GTlsInteractionClass>);
15
16 match fn {
17 type_ => || ffi::g_tls_interaction_get_type(),
18 }
19}
20
21impl TlsInteraction {
22 pub const NONE: Option<&'static TlsInteraction> = None;
23}
24
25pub trait TlsInteractionExt: IsA<TlsInteraction> + 'static {
26 #[doc(alias = "g_tls_interaction_ask_password")]
27 fn ask_password(
28 &self,
29 password: &impl IsA<TlsPassword>,
30 cancellable: Option<&impl IsA<Cancellable>>,
31 ) -> Result<TlsInteractionResult, glib::Error> {
32 unsafe {
33 let mut error = std::ptr::null_mut();
34 let ret = ffi::g_tls_interaction_ask_password(
35 self.as_ref().to_glib_none().0,
36 password.as_ref().to_glib_none().0,
37 cancellable.map(|p| p.as_ref()).to_glib_none().0,
38 &mut error,
39 );
40 if error.is_null() {
41 Ok(from_glib(ret))
42 } else {
43 Err(from_glib_full(error))
44 }
45 }
46 }
47
48 #[doc(alias = "g_tls_interaction_ask_password_async")]
49 fn ask_password_async<P: FnOnce(Result<TlsInteractionResult, glib::Error>) + 'static>(
50 &self,
51 password: &impl IsA<TlsPassword>,
52 cancellable: Option<&impl IsA<Cancellable>>,
53 callback: P,
54 ) {
55 let main_context = glib::MainContext::ref_thread_default();
56 let is_main_context_owner = main_context.is_owner();
57 let has_acquired_main_context = (!is_main_context_owner)
58 .then(|| main_context.acquire().ok())
59 .flatten();
60 assert!(
61 is_main_context_owner || has_acquired_main_context.is_some(),
62 "Async operations only allowed if the thread is owning the MainContext"
63 );
64
65 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
66 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
67 unsafe extern "C" fn ask_password_async_trampoline<
68 P: FnOnce(Result<TlsInteractionResult, glib::Error>) + 'static,
69 >(
70 _source_object: *mut glib::gobject_ffi::GObject,
71 res: *mut crate::ffi::GAsyncResult,
72 user_data: glib::ffi::gpointer,
73 ) {
74 unsafe {
75 let mut error = std::ptr::null_mut();
76 let ret = ffi::g_tls_interaction_ask_password_finish(
77 _source_object as *mut _,
78 res,
79 &mut error,
80 );
81 let result = if error.is_null() {
82 Ok(from_glib(ret))
83 } else {
84 Err(from_glib_full(error))
85 };
86 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
87 Box_::from_raw(user_data as *mut _);
88 let callback: P = callback.into_inner();
89 callback(result);
90 }
91 }
92 let callback = ask_password_async_trampoline::<P>;
93 unsafe {
94 ffi::g_tls_interaction_ask_password_async(
95 self.as_ref().to_glib_none().0,
96 password.as_ref().to_glib_none().0,
97 cancellable.map(|p| p.as_ref()).to_glib_none().0,
98 Some(callback),
99 Box_::into_raw(user_data) as *mut _,
100 );
101 }
102 }
103
104 fn ask_password_future(
105 &self,
106 password: &(impl IsA<TlsPassword> + Clone + 'static),
107 ) -> Pin<
108 Box_<dyn std::future::Future<Output = Result<TlsInteractionResult, glib::Error>> + 'static>,
109 > {
110 let password = password.clone();
111 Box_::pin(crate::GioFuture::new(
112 self,
113 move |obj, cancellable, send| {
114 obj.ask_password_async(&password, Some(cancellable), move |res| {
115 send.resolve(res);
116 });
117 },
118 ))
119 }
120
121 #[doc(alias = "g_tls_interaction_invoke_ask_password")]
122 fn invoke_ask_password(
123 &self,
124 password: &impl IsA<TlsPassword>,
125 cancellable: Option<&impl IsA<Cancellable>>,
126 ) -> Result<TlsInteractionResult, glib::Error> {
127 unsafe {
128 let mut error = std::ptr::null_mut();
129 let ret = ffi::g_tls_interaction_invoke_ask_password(
130 self.as_ref().to_glib_none().0,
131 password.as_ref().to_glib_none().0,
132 cancellable.map(|p| p.as_ref()).to_glib_none().0,
133 &mut error,
134 );
135 if error.is_null() {
136 Ok(from_glib(ret))
137 } else {
138 Err(from_glib_full(error))
139 }
140 }
141 }
142
143 #[doc(alias = "g_tls_interaction_invoke_request_certificate")]
144 fn invoke_request_certificate(
145 &self,
146 connection: &impl IsA<TlsConnection>,
147 flags: TlsCertificateRequestFlags,
148 cancellable: Option<&impl IsA<Cancellable>>,
149 ) -> Result<TlsInteractionResult, glib::Error> {
150 unsafe {
151 let mut error = std::ptr::null_mut();
152 let ret = ffi::g_tls_interaction_invoke_request_certificate(
153 self.as_ref().to_glib_none().0,
154 connection.as_ref().to_glib_none().0,
155 flags.into_glib(),
156 cancellable.map(|p| p.as_ref()).to_glib_none().0,
157 &mut error,
158 );
159 if error.is_null() {
160 Ok(from_glib(ret))
161 } else {
162 Err(from_glib_full(error))
163 }
164 }
165 }
166
167 #[doc(alias = "g_tls_interaction_request_certificate")]
168 fn request_certificate(
169 &self,
170 connection: &impl IsA<TlsConnection>,
171 flags: TlsCertificateRequestFlags,
172 cancellable: Option<&impl IsA<Cancellable>>,
173 ) -> Result<TlsInteractionResult, glib::Error> {
174 unsafe {
175 let mut error = std::ptr::null_mut();
176 let ret = ffi::g_tls_interaction_request_certificate(
177 self.as_ref().to_glib_none().0,
178 connection.as_ref().to_glib_none().0,
179 flags.into_glib(),
180 cancellable.map(|p| p.as_ref()).to_glib_none().0,
181 &mut error,
182 );
183 if error.is_null() {
184 Ok(from_glib(ret))
185 } else {
186 Err(from_glib_full(error))
187 }
188 }
189 }
190
191 #[doc(alias = "g_tls_interaction_request_certificate_async")]
192 fn request_certificate_async<P: FnOnce(Result<TlsInteractionResult, glib::Error>) + 'static>(
193 &self,
194 connection: &impl IsA<TlsConnection>,
195 flags: TlsCertificateRequestFlags,
196 cancellable: Option<&impl IsA<Cancellable>>,
197 callback: P,
198 ) {
199 let main_context = glib::MainContext::ref_thread_default();
200 let is_main_context_owner = main_context.is_owner();
201 let has_acquired_main_context = (!is_main_context_owner)
202 .then(|| main_context.acquire().ok())
203 .flatten();
204 assert!(
205 is_main_context_owner || has_acquired_main_context.is_some(),
206 "Async operations only allowed if the thread is owning the MainContext"
207 );
208
209 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
210 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
211 unsafe extern "C" fn request_certificate_async_trampoline<
212 P: FnOnce(Result<TlsInteractionResult, glib::Error>) + 'static,
213 >(
214 _source_object: *mut glib::gobject_ffi::GObject,
215 res: *mut crate::ffi::GAsyncResult,
216 user_data: glib::ffi::gpointer,
217 ) {
218 unsafe {
219 let mut error = std::ptr::null_mut();
220 let ret = ffi::g_tls_interaction_request_certificate_finish(
221 _source_object as *mut _,
222 res,
223 &mut error,
224 );
225 let result = if error.is_null() {
226 Ok(from_glib(ret))
227 } else {
228 Err(from_glib_full(error))
229 };
230 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
231 Box_::from_raw(user_data as *mut _);
232 let callback: P = callback.into_inner();
233 callback(result);
234 }
235 }
236 let callback = request_certificate_async_trampoline::<P>;
237 unsafe {
238 ffi::g_tls_interaction_request_certificate_async(
239 self.as_ref().to_glib_none().0,
240 connection.as_ref().to_glib_none().0,
241 flags.into_glib(),
242 cancellable.map(|p| p.as_ref()).to_glib_none().0,
243 Some(callback),
244 Box_::into_raw(user_data) as *mut _,
245 );
246 }
247 }
248
249 fn request_certificate_future(
250 &self,
251 connection: &(impl IsA<TlsConnection> + Clone + 'static),
252 flags: TlsCertificateRequestFlags,
253 ) -> Pin<
254 Box_<dyn std::future::Future<Output = Result<TlsInteractionResult, glib::Error>> + 'static>,
255 > {
256 let connection = connection.clone();
257 Box_::pin(crate::GioFuture::new(
258 self,
259 move |obj, cancellable, send| {
260 obj.request_certificate_async(&connection, flags, Some(cancellable), move |res| {
261 send.resolve(res);
262 });
263 },
264 ))
265 }
266}
267
268impl<O: IsA<TlsInteraction>> TlsInteractionExt for O {}