gio/
socket_listener.rs

1// Copyright 2013-2018, The Gtk-rs Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use 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}