gio/auto/
socket_connection.rs1use crate::{
6 ffi, AsyncResult, Cancellable, IOStream, Socket, SocketAddress, SocketFamily, SocketType,
7};
8use glib::{prelude::*, translate::*};
9use std::{boxed::Box as Box_, pin::Pin};
10
11glib::wrapper! {
12 #[doc(alias = "GSocketConnection")]
13 pub struct SocketConnection(Object<ffi::GSocketConnection, ffi::GSocketConnectionClass>) @extends IOStream;
14
15 match fn {
16 type_ => || ffi::g_socket_connection_get_type(),
17 }
18}
19
20impl SocketConnection {
21 pub const NONE: Option<&'static SocketConnection> = None;
22
23 #[doc(alias = "g_socket_connection_factory_lookup_type")]
24 pub fn factory_lookup_type(
25 family: SocketFamily,
26 type_: SocketType,
27 protocol_id: i32,
28 ) -> glib::types::Type {
29 unsafe {
30 from_glib(ffi::g_socket_connection_factory_lookup_type(
31 family.into_glib(),
32 type_.into_glib(),
33 protocol_id,
34 ))
35 }
36 }
37
38 #[doc(alias = "g_socket_connection_factory_register_type")]
39 pub fn factory_register_type(
40 g_type: glib::types::Type,
41 family: SocketFamily,
42 type_: SocketType,
43 protocol: i32,
44 ) {
45 unsafe {
46 ffi::g_socket_connection_factory_register_type(
47 g_type.into_glib(),
48 family.into_glib(),
49 type_.into_glib(),
50 protocol,
51 );
52 }
53 }
54}
55
56mod sealed {
57 pub trait Sealed {}
58 impl<T: super::IsA<super::SocketConnection>> Sealed for T {}
59}
60
61pub trait SocketConnectionExt: IsA<SocketConnection> + sealed::Sealed + 'static {
62 #[doc(alias = "g_socket_connection_connect")]
63 fn connect(
64 &self,
65 address: &impl IsA<SocketAddress>,
66 cancellable: Option<&impl IsA<Cancellable>>,
67 ) -> Result<(), glib::Error> {
68 unsafe {
69 let mut error = std::ptr::null_mut();
70 let is_ok = ffi::g_socket_connection_connect(
71 self.as_ref().to_glib_none().0,
72 address.as_ref().to_glib_none().0,
73 cancellable.map(|p| p.as_ref()).to_glib_none().0,
74 &mut error,
75 );
76 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
77 if error.is_null() {
78 Ok(())
79 } else {
80 Err(from_glib_full(error))
81 }
82 }
83 }
84
85 #[doc(alias = "g_socket_connection_connect_async")]
86 fn connect_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
87 &self,
88 address: &impl IsA<SocketAddress>,
89 cancellable: Option<&impl IsA<Cancellable>>,
90 callback: P,
91 ) {
92 let main_context = glib::MainContext::ref_thread_default();
93 let is_main_context_owner = main_context.is_owner();
94 let has_acquired_main_context = (!is_main_context_owner)
95 .then(|| main_context.acquire().ok())
96 .flatten();
97 assert!(
98 is_main_context_owner || has_acquired_main_context.is_some(),
99 "Async operations only allowed if the thread is owning the MainContext"
100 );
101
102 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
103 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
104 unsafe extern "C" fn connect_async_trampoline<
105 P: FnOnce(Result<(), glib::Error>) + 'static,
106 >(
107 _source_object: *mut glib::gobject_ffi::GObject,
108 res: *mut crate::ffi::GAsyncResult,
109 user_data: glib::ffi::gpointer,
110 ) {
111 let mut error = std::ptr::null_mut();
112 ffi::g_socket_connection_connect_finish(_source_object as *mut _, res, &mut error);
113 let result = if error.is_null() {
114 Ok(())
115 } else {
116 Err(from_glib_full(error))
117 };
118 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
119 Box_::from_raw(user_data as *mut _);
120 let callback: P = callback.into_inner();
121 callback(result);
122 }
123 let callback = connect_async_trampoline::<P>;
124 unsafe {
125 ffi::g_socket_connection_connect_async(
126 self.as_ref().to_glib_none().0,
127 address.as_ref().to_glib_none().0,
128 cancellable.map(|p| p.as_ref()).to_glib_none().0,
129 Some(callback),
130 Box_::into_raw(user_data) as *mut _,
131 );
132 }
133 }
134
135 fn connect_future(
136 &self,
137 address: &(impl IsA<SocketAddress> + Clone + 'static),
138 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
139 let address = address.clone();
140 Box_::pin(crate::GioFuture::new(
141 self,
142 move |obj, cancellable, send| {
143 obj.connect_async(&address, Some(cancellable), move |res| {
144 send.resolve(res);
145 });
146 },
147 ))
148 }
149
150 #[doc(alias = "g_socket_connection_get_local_address")]
151 #[doc(alias = "get_local_address")]
152 fn local_address(&self) -> Result<SocketAddress, glib::Error> {
153 unsafe {
154 let mut error = std::ptr::null_mut();
155 let ret = ffi::g_socket_connection_get_local_address(
156 self.as_ref().to_glib_none().0,
157 &mut error,
158 );
159 if error.is_null() {
160 Ok(from_glib_full(ret))
161 } else {
162 Err(from_glib_full(error))
163 }
164 }
165 }
166
167 #[doc(alias = "g_socket_connection_get_remote_address")]
168 #[doc(alias = "get_remote_address")]
169 fn remote_address(&self) -> Result<SocketAddress, glib::Error> {
170 unsafe {
171 let mut error = std::ptr::null_mut();
172 let ret = ffi::g_socket_connection_get_remote_address(
173 self.as_ref().to_glib_none().0,
174 &mut error,
175 );
176 if error.is_null() {
177 Ok(from_glib_full(ret))
178 } else {
179 Err(from_glib_full(error))
180 }
181 }
182 }
183
184 #[doc(alias = "g_socket_connection_get_socket")]
185 #[doc(alias = "get_socket")]
186 fn socket(&self) -> Socket {
187 unsafe {
188 from_glib_none(ffi::g_socket_connection_get_socket(
189 self.as_ref().to_glib_none().0,
190 ))
191 }
192 }
193
194 #[doc(alias = "g_socket_connection_is_connected")]
195 fn is_connected(&self) -> bool {
196 unsafe {
197 from_glib(ffi::g_socket_connection_is_connected(
198 self.as_ref().to_glib_none().0,
199 ))
200 }
201 }
202}
203
204impl<O: IsA<SocketConnection>> SocketConnectionExt for O {}