1use gio_sys;
6use glib;
7use glib::object::IsA;
8use glib::translate::*;
9use glib_sys;
10use gobject_sys;
11use std::boxed::Box as Box_;
12use std::ptr;
13use Cancellable;
14use Error;
15use Socket;
16use SocketConnection;
17use SocketListener;
18
19#[cfg(feature = "futures")]
20use futures::future;
21
22pub trait SocketListenerExtManual: Sized {
23 fn accept_socket_async<
24 Q: FnOnce(Result<(Socket, Option<glib::Object>), Error>) + Send + 'static,
25 >(
26 &self,
27 cancellable: Option<&Cancellable>,
28 callback: Q,
29 );
30
31 #[cfg(feature = "futures")]
32 fn accept_socket_async_future(
33 &self,
34 ) -> Box<
35 dyn future::Future<Output = Result<(Socket, Option<glib::Object>), Error>>
36 + std::marker::Unpin,
37 >;
38
39 fn accept_async<
40 P: IsA<Cancellable>,
41 Q: FnOnce(Result<(SocketConnection, Option<glib::Object>), Error>) + Send + 'static,
42 >(
43 &self,
44 cancellable: Option<&P>,
45 callback: Q,
46 );
47
48 #[cfg(feature = "futures")]
49 fn accept_async_future(
50 &self,
51 ) -> Box_<
52 dyn future::Future<Output = Result<(SocketConnection, Option<glib::Object>), Error>>
53 + std::marker::Unpin,
54 >;
55}
56
57impl<O: IsA<SocketListener>> SocketListenerExtManual for O {
58 fn accept_socket_async<
59 Q: FnOnce(Result<(Socket, Option<glib::Object>), Error>) + Send + 'static,
60 >(
61 &self,
62 cancellable: Option<&Cancellable>,
63 callback: Q,
64 ) {
65 let cancellable = cancellable.to_glib_none();
66 let user_data: Box<Q> = Box::new(callback);
67 unsafe extern "C" fn accept_socket_async_trampoline<
68 Q: FnOnce(Result<(Socket, Option<glib::Object>), Error>) + Send + 'static,
69 >(
70 _source_object: *mut gobject_sys::GObject,
71 res: *mut gio_sys::GAsyncResult,
72 user_data: glib_sys::gpointer,
73 ) {
74 let mut error = ptr::null_mut();
75 let mut source_object = ptr::null_mut();
76 let res = gio_sys::g_socket_listener_accept_socket_finish(
77 _source_object as *mut _,
78 res,
79 &mut source_object,
80 &mut error,
81 );
82 let result = if error.is_null() {
83 Ok((from_glib_full(res), from_glib_none(source_object)))
84 } else {
85 Err(from_glib_full(error))
86 };
87 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
88 callback(result);
89 }
90 let callback = accept_socket_async_trampoline::<Q>;
91 unsafe {
92 gio_sys::g_socket_listener_accept_socket_async(
93 self.as_ref().to_glib_none().0,
94 cancellable.0,
95 Some(callback),
96 Box::into_raw(user_data) as *mut _,
97 );
98 }
99 }
100
101 #[cfg(feature = "futures")]
102 fn accept_socket_async_future(
103 &self,
104 ) -> Box<
105 dyn future::Future<Output = Result<(Socket, Option<glib::Object>), Error>>
106 + std::marker::Unpin,
107 > {
108 use GioFuture;
109
110 GioFuture::new(self, move |obj, send| {
111 use fragile::Fragile;
112
113 let cancellable = Cancellable::new();
114 let send = Fragile::new(send);
115 obj.accept_socket_async(Some(&cancellable), move |res| {
116 let _ = send.into_inner().send(res);
117 });
118
119 cancellable
120 })
121 }
122
123 fn accept_async<
124 P: IsA<Cancellable>,
125 Q: FnOnce(Result<(SocketConnection, Option<glib::Object>), Error>) + Send + 'static,
126 >(
127 &self,
128 cancellable: Option<&P>,
129 callback: Q,
130 ) {
131 let user_data: Box<Q> = Box::new(callback);
132 unsafe extern "C" fn accept_async_trampoline<
133 Q: FnOnce(Result<(SocketConnection, Option<glib::Object>), Error>) + Send + 'static,
134 >(
135 _source_object: *mut gobject_sys::GObject,
136 res: *mut gio_sys::GAsyncResult,
137 user_data: glib_sys::gpointer,
138 ) {
139 let mut error = ptr::null_mut();
140 let mut source_object = ptr::null_mut();
141 let ret = gio_sys::g_socket_listener_accept_finish(
142 _source_object as *mut _,
143 res,
144 &mut source_object,
145 &mut error,
146 );
147 let result = if error.is_null() {
148 Ok((from_glib_full(ret), from_glib_none(source_object)))
149 } else {
150 Err(from_glib_full(error))
151 };
152 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
153 callback(result);
154 }
155 let callback = accept_async_trampoline::<Q>;
156 unsafe {
157 gio_sys::g_socket_listener_accept_async(
158 self.as_ref().to_glib_none().0,
159 cancellable.map(|p| p.as_ref()).to_glib_none().0,
160 Some(callback),
161 Box::into_raw(user_data) as *mut _,
162 );
163 }
164 }
165
166 #[cfg(feature = "futures")]
167 fn accept_async_future(
168 &self,
169 ) -> Box_<
170 dyn future::Future<Output = Result<(SocketConnection, Option<glib::Object>), Error>>
171 + std::marker::Unpin,
172 > {
173 use fragile::Fragile;
174 use GioFuture;
175
176 GioFuture::new(self, move |obj, send| {
177 let cancellable = Cancellable::new();
178 let send = Fragile::new(send);
179 obj.accept_async(Some(&cancellable), move |res| {
180 let _ = send.into_inner().send(res);
181 });
182
183 cancellable
184 })
185 }
186}