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