tls_api/
socket_box.rs

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/// Newtype for [`Box<dyn AsyncSocket>`](AsyncSocket).
12#[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        // Can be made safe with specialization.
23        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    /// Construct.
36    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}