1use std::any::TypeId;
2use std::mem;
3use std::mem::MaybeUninit;
4use std::pin::Pin;
5use std::ptr;
6
7use crate::assert_send;
8use crate::spi_async_socket_impl_delegate;
9use crate::AsyncSocket;
10
11#[derive(Debug)]
13pub struct AsyncSocketBox(Box<dyn AsyncSocket>);
14
15fn _assert_kinds() {
16 assert_send::<AsyncSocketBox>();
17}
18
19fn transmute_or_map<A: 'static, B: 'static>(a: A, f: impl FnOnce(A) -> B) -> B {
20 if TypeId::of::<A>() == TypeId::of::<B>() {
21 assert_eq!(mem::size_of::<A>(), mem::size_of::<B>());
22 unsafe {
24 let mut b = MaybeUninit::<B>::uninit();
25 ptr::copy(&a as *const A, b.as_mut_ptr() as *mut A, 1);
26 mem::forget(a);
27 b.assume_init()
28 }
29 } else {
30 f(a)
31 }
32}
33
34impl AsyncSocketBox {
35 pub fn new<S: AsyncSocket>(socket: S) -> AsyncSocketBox {
37 transmute_or_map(socket, |socket| AsyncSocketBox(Box::new(socket)))
38 }
39
40 fn deref_pin_mut_for_impl_socket(self: Pin<&mut Self>) -> Pin<&mut dyn AsyncSocket> {
41 Pin::new(&mut self.get_mut().0)
42 }
43
44 #[allow(dead_code)]
45 fn deref_for_impl_socket(&self) -> &dyn AsyncSocket {
46 &self.0
47 }
48}
49
50spi_async_socket_impl_delegate!(AsyncSocketBox);
51
52fn _assert_async_socket_box_is_async_socket(s: AsyncSocketBox) {
53 fn accepts_socket<S: AsyncSocket>(_: S) {}
54 accepts_socket(s);
55}