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