1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! `HandleOrSocket` variants of io-lifetimes'
//! `BorrowedHandle`/`BorrowedSocket` and `OwnedHandle`/`OwnedSocket`.

use super::{AsRawHandleOrSocket, RawEnum, RawHandleOrSocket};
use io_lifetimes::{BorrowedHandle, BorrowedSocket, OwnedHandle, OwnedSocket};
use std::fmt;
use std::marker::PhantomData;
use std::os::windows::io::{AsRawHandle, AsRawSocket, RawSocket};
use winapi::um::winsock2::INVALID_SOCKET;

/// `HandleOrSocket` variant of io-lifetimes'
/// `BorrowedHandle`/`BorrowedSocket`.
#[derive(Copy, Clone)]
pub struct BorrowedHandleOrSocket<'a> {
    raw: RawHandleOrSocket,
    _phantom: PhantomData<&'a OwnedHandleOrSocket>,
}

/// `HandleOrSocket` variant of io-lifetimes'
/// `BorrowedHandle`/`BorrowedSocket`.
#[allow(missing_copy_implementations)]
pub struct OwnedHandleOrSocket {
    raw: RawHandleOrSocket,
}

impl<'a> BorrowedHandleOrSocket<'a> {
    /// Return a `BorrowedHandleOrSocket` holding the given raw handle or
    /// socket.
    ///
    /// # Safety
    ///
    /// The resource pointed to by `raw` must remain open for the duration of
    /// the returned `BorrowedHandleOrSocket`, and it must not be a null handle
    /// or an invalid socket.
    #[inline]
    pub unsafe fn borrow_raw_handle_or_socket(raw: RawHandleOrSocket) -> Self {
        match raw.0 {
            RawEnum::Handle(raw_handle) => assert!(!raw_handle.is_null()),
            RawEnum::Socket(raw_socket) => assert_ne!(raw_socket, INVALID_SOCKET as RawSocket),
            RawEnum::Stdio(_) => (),
        }
        Self {
            raw,
            _phantom: PhantomData,
        }
    }

    /// Construct a `BorrowedHandleOrSocket` from a `BorrowedHandle`.
    #[inline]
    pub fn from_handle(handle: BorrowedHandle<'a>) -> Self {
        Self {
            raw: RawHandleOrSocket(RawEnum::Handle(handle.as_raw_handle())),
            _phantom: PhantomData,
        }
    }

    /// Construct a `BorrowedHandleOrSocket` from a `BorrowedSocket`.
    #[inline]
    pub fn from_socket(socket: BorrowedSocket<'a>) -> Self {
        Self {
            raw: RawHandleOrSocket(RawEnum::Socket(socket.as_raw_socket())),
            _phantom: PhantomData,
        }
    }
}

impl OwnedHandleOrSocket {
    /// Return an `OwnedHandleOrSocket` holding the given raw handle or socket.
    ///
    /// # Safety
    ///
    /// The resource pointed to by `raw` must remain open for the duration of
    /// the returned `OwnedHandleOrSocket`, and it must not be a null handle
    /// or an invalid socket.
    #[inline]
    pub unsafe fn acquire_raw_handle_or_socket(raw: RawHandleOrSocket) -> Self {
        match raw.0 {
            RawEnum::Handle(raw_handle) => assert!(!raw_handle.is_null()),
            RawEnum::Socket(raw_socket) => assert_ne!(raw_socket, INVALID_SOCKET as RawSocket),
            RawEnum::Stdio(_) => (),
        }
        Self { raw }
    }

    /// Construct a new `OwnedHandleOrSocket` from an `OwnedHandle`.
    #[inline]
    pub fn from_handle(handle: OwnedHandle) -> Self {
        Self {
            raw: RawHandleOrSocket(RawEnum::Handle(handle.as_raw_handle())),
        }
    }

    /// Construct a new `OwnedHandleOrSocket` from an `OwnedSocket`.
    #[inline]
    pub fn from_socket(socket: OwnedSocket) -> Self {
        Self {
            raw: RawHandleOrSocket(RawEnum::Socket(socket.as_raw_socket())),
        }
    }
}

impl AsRawHandleOrSocket for OwnedHandleOrSocket {
    #[inline]
    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
        self.raw
    }
}

impl AsRawHandleOrSocket for BorrowedHandleOrSocket<'_> {
    #[inline]
    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
        self.raw
    }
}

impl fmt::Debug for BorrowedHandleOrSocket<'_> {
    #[allow(clippy::missing_inline_in_public_items)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Just print the raw handle or socket; don't try to print the path or
        // any information about it, because this information is otherwise
        // unavailable to safe portable Rust code.
        f.debug_struct("BorrowedHandleOrSocket")
            .field("raw", &self.raw)
            .finish()
    }
}

impl fmt::Debug for OwnedHandleOrSocket {
    #[allow(clippy::missing_inline_in_public_items)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Just print the raw handle or socket; don't try to print the path or
        // any information about it, because this information is otherwise
        // unavailable to safe portable Rust code.
        f.debug_struct("OwnedHandleOrSocket")
            .field("raw", &self.raw)
            .finish()
    }
}