1use crate::{ffi, AsyncResult, Cancellable, IOStream, ProxyAddress};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10 #[doc(alias = "GProxy")]
11 pub struct Proxy(Interface<ffi::GProxy, ffi::GProxyInterface>);
12
13 match fn {
14 type_ => || ffi::g_proxy_get_type(),
15 }
16}
17
18impl Proxy {
19 pub const NONE: Option<&'static Proxy> = None;
20
21 #[doc(alias = "g_proxy_get_default_for_protocol")]
22 #[doc(alias = "get_default_for_protocol")]
23 pub fn default_for_protocol(protocol: &str) -> Option<Proxy> {
24 unsafe {
25 from_glib_full(ffi::g_proxy_get_default_for_protocol(
26 protocol.to_glib_none().0,
27 ))
28 }
29 }
30}
31
32pub trait ProxyExt: IsA<Proxy> + 'static {
33 #[doc(alias = "g_proxy_connect")]
34 fn connect(
35 &self,
36 connection: &impl IsA<IOStream>,
37 proxy_address: &impl IsA<ProxyAddress>,
38 cancellable: Option<&impl IsA<Cancellable>>,
39 ) -> Result<IOStream, glib::Error> {
40 unsafe {
41 let mut error = std::ptr::null_mut();
42 let ret = ffi::g_proxy_connect(
43 self.as_ref().to_glib_none().0,
44 connection.as_ref().to_glib_none().0,
45 proxy_address.as_ref().to_glib_none().0,
46 cancellable.map(|p| p.as_ref()).to_glib_none().0,
47 &mut error,
48 );
49 if error.is_null() {
50 Ok(from_glib_full(ret))
51 } else {
52 Err(from_glib_full(error))
53 }
54 }
55 }
56
57 #[doc(alias = "g_proxy_connect_async")]
58 fn connect_async<P: FnOnce(Result<IOStream, glib::Error>) + 'static>(
59 &self,
60 connection: &impl IsA<IOStream>,
61 proxy_address: &impl IsA<ProxyAddress>,
62 cancellable: Option<&impl IsA<Cancellable>>,
63 callback: P,
64 ) {
65 let main_context = glib::MainContext::ref_thread_default();
66 let is_main_context_owner = main_context.is_owner();
67 let has_acquired_main_context = (!is_main_context_owner)
68 .then(|| main_context.acquire().ok())
69 .flatten();
70 assert!(
71 is_main_context_owner || has_acquired_main_context.is_some(),
72 "Async operations only allowed if the thread is owning the MainContext"
73 );
74
75 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
76 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
77 unsafe extern "C" fn connect_async_trampoline<
78 P: FnOnce(Result<IOStream, glib::Error>) + 'static,
79 >(
80 _source_object: *mut glib::gobject_ffi::GObject,
81 res: *mut crate::ffi::GAsyncResult,
82 user_data: glib::ffi::gpointer,
83 ) {
84 let mut error = std::ptr::null_mut();
85 let ret = ffi::g_proxy_connect_finish(_source_object as *mut _, res, &mut error);
86 let result = if error.is_null() {
87 Ok(from_glib_full(ret))
88 } else {
89 Err(from_glib_full(error))
90 };
91 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
92 Box_::from_raw(user_data as *mut _);
93 let callback: P = callback.into_inner();
94 callback(result);
95 }
96 let callback = connect_async_trampoline::<P>;
97 unsafe {
98 ffi::g_proxy_connect_async(
99 self.as_ref().to_glib_none().0,
100 connection.as_ref().to_glib_none().0,
101 proxy_address.as_ref().to_glib_none().0,
102 cancellable.map(|p| p.as_ref()).to_glib_none().0,
103 Some(callback),
104 Box_::into_raw(user_data) as *mut _,
105 );
106 }
107 }
108
109 fn connect_future(
110 &self,
111 connection: &(impl IsA<IOStream> + Clone + 'static),
112 proxy_address: &(impl IsA<ProxyAddress> + Clone + 'static),
113 ) -> Pin<Box_<dyn std::future::Future<Output = Result<IOStream, glib::Error>> + 'static>> {
114 let connection = connection.clone();
115 let proxy_address = proxy_address.clone();
116 Box_::pin(crate::GioFuture::new(
117 self,
118 move |obj, cancellable, send| {
119 obj.connect_async(&connection, &proxy_address, Some(cancellable), move |res| {
120 send.resolve(res);
121 });
122 },
123 ))
124 }
125
126 #[doc(alias = "g_proxy_supports_hostname")]
127 fn supports_hostname(&self) -> bool {
128 unsafe {
129 from_glib(ffi::g_proxy_supports_hostname(
130 self.as_ref().to_glib_none().0,
131 ))
132 }
133 }
134}
135
136impl<O: IsA<Proxy>> ProxyExt for O {}