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
56pub trait SocketConnectionExt: IsA<SocketConnection> + 'static {
57 #[doc(alias = "g_socket_connection_connect")]
58 fn connect(
59 &self,
60 address: &impl IsA<SocketAddress>,
61 cancellable: Option<&impl IsA<Cancellable>>,
62 ) -> Result<(), glib::Error> {
63 unsafe {
64 let mut error = std::ptr::null_mut();
65 let is_ok = ffi::g_socket_connection_connect(
66 self.as_ref().to_glib_none().0,
67 address.as_ref().to_glib_none().0,
68 cancellable.map(|p| p.as_ref()).to_glib_none().0,
69 &mut error,
70 );
71 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
72 if error.is_null() {
73 Ok(())
74 } else {
75 Err(from_glib_full(error))
76 }
77 }
78 }
79
80 #[doc(alias = "g_socket_connection_connect_async")]
81 fn connect_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
82 &self,
83 address: &impl IsA<SocketAddress>,
84 cancellable: Option<&impl IsA<Cancellable>>,
85 callback: P,
86 ) {
87 let main_context = glib::MainContext::ref_thread_default();
88 let is_main_context_owner = main_context.is_owner();
89 let has_acquired_main_context = (!is_main_context_owner)
90 .then(|| main_context.acquire().ok())
91 .flatten();
92 assert!(
93 is_main_context_owner || has_acquired_main_context.is_some(),
94 "Async operations only allowed if the thread is owning the MainContext"
95 );
96
97 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
98 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
99 unsafe extern "C" fn connect_async_trampoline<
100 P: FnOnce(Result<(), glib::Error>) + 'static,
101 >(
102 _source_object: *mut glib::gobject_ffi::GObject,
103 res: *mut crate::ffi::GAsyncResult,
104 user_data: glib::ffi::gpointer,
105 ) {
106 let mut error = std::ptr::null_mut();
107 ffi::g_socket_connection_connect_finish(_source_object as *mut _, res, &mut error);
108 let result = if error.is_null() {
109 Ok(())
110 } else {
111 Err(from_glib_full(error))
112 };
113 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
114 Box_::from_raw(user_data as *mut _);
115 let callback: P = callback.into_inner();
116 callback(result);
117 }
118 let callback = connect_async_trampoline::<P>;
119 unsafe {
120 ffi::g_socket_connection_connect_async(
121 self.as_ref().to_glib_none().0,
122 address.as_ref().to_glib_none().0,
123 cancellable.map(|p| p.as_ref()).to_glib_none().0,
124 Some(callback),
125 Box_::into_raw(user_data) as *mut _,
126 );
127 }
128 }
129
130 fn connect_future(
131 &self,
132 address: &(impl IsA<SocketAddress> + Clone + 'static),
133 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
134 let address = address.clone();
135 Box_::pin(crate::GioFuture::new(
136 self,
137 move |obj, cancellable, send| {
138 obj.connect_async(&address, Some(cancellable), move |res| {
139 send.resolve(res);
140 });
141 },
142 ))
143 }
144
145 #[doc(alias = "g_socket_connection_get_local_address")]
146 #[doc(alias = "get_local_address")]
147 fn local_address(&self) -> Result<SocketAddress, glib::Error> {
148 unsafe {
149 let mut error = std::ptr::null_mut();
150 let ret = ffi::g_socket_connection_get_local_address(
151 self.as_ref().to_glib_none().0,
152 &mut error,
153 );
154 if error.is_null() {
155 Ok(from_glib_full(ret))
156 } else {
157 Err(from_glib_full(error))
158 }
159 }
160 }
161
162 #[doc(alias = "g_socket_connection_get_remote_address")]
163 #[doc(alias = "get_remote_address")]
164 fn remote_address(&self) -> Result<SocketAddress, glib::Error> {
165 unsafe {
166 let mut error = std::ptr::null_mut();
167 let ret = ffi::g_socket_connection_get_remote_address(
168 self.as_ref().to_glib_none().0,
169 &mut error,
170 );
171 if error.is_null() {
172 Ok(from_glib_full(ret))
173 } else {
174 Err(from_glib_full(error))
175 }
176 }
177 }
178
179 #[doc(alias = "g_socket_connection_get_socket")]
180 #[doc(alias = "get_socket")]
181 fn socket(&self) -> Socket {
182 unsafe {
183 from_glib_none(ffi::g_socket_connection_get_socket(
184 self.as_ref().to_glib_none().0,
185 ))
186 }
187 }
188
189 #[doc(alias = "g_socket_connection_is_connected")]
190 fn is_connected(&self) -> bool {
191 unsafe {
192 from_glib(ffi::g_socket_connection_is_connected(
193 self.as_ref().to_glib_none().0,
194 ))
195 }
196 }
197}
198
199impl<O: IsA<SocketConnection>> SocketConnectionExt for O {}