1use crate::raw::{
9 AsRawFilelike, AsRawSocketlike, FromRawFilelike, FromRawSocketlike, IntoRawFilelike,
10 IntoRawSocketlike, RawFilelike, RawSocketlike,
11};
12#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
13use crate::OwnedFd;
14use crate::{
15 AsFilelike, AsSocketlike, FromFilelike, FromSocketlike, IntoFilelike, IntoSocketlike,
16 OwnedFilelike, OwnedSocketlike,
17};
18#[cfg(windows)]
19use crate::{OwnedHandle, OwnedSocket};
20use std::fmt;
21use std::marker::PhantomData;
22use std::mem::ManuallyDrop;
23use std::ops::Deref;
24
25pub unsafe trait FilelikeViewType: FromFilelike + IntoFilelike {}
34
35pub unsafe trait SocketlikeViewType: FromSocketlike + IntoSocketlike {}
44
45pub struct FilelikeView<'filelike, Target: FilelikeViewType> {
48 target: ManuallyDrop<Target>,
51
52 #[cfg(debug_assertions)]
56 orig: RawFilelike,
57
58 _phantom: PhantomData<&'filelike OwnedFilelike>,
61}
62
63pub struct SocketlikeView<'socketlike, Target: SocketlikeViewType> {
66 target: ManuallyDrop<Target>,
69
70 #[cfg(debug_assertions)]
74 orig: RawSocketlike,
75
76 _phantom: PhantomData<&'socketlike OwnedSocketlike>,
79}
80
81impl<Target: FilelikeViewType> FilelikeView<'_, Target> {
82 #[inline]
84 pub(crate) fn new<T: AsFilelike>(filelike: &T) -> Self {
85 unsafe { Self::view_raw(filelike.as_filelike().as_raw_filelike()) }
89 }
90
91 #[inline]
99 pub unsafe fn view_raw(raw: RawFilelike) -> Self {
100 let owned = OwnedFilelike::from_raw_filelike(raw);
101 Self {
102 target: ManuallyDrop::new(Target::from_filelike(owned)),
103 #[cfg(debug_assertions)]
104 orig: raw,
105 _phantom: PhantomData,
106 }
107 }
108}
109
110impl<Target: SocketlikeViewType> SocketlikeView<'_, Target> {
111 #[inline]
114 pub(crate) fn new<T: AsSocketlike>(socketlike: &T) -> Self {
115 unsafe { Self::view_raw(socketlike.as_socketlike().as_raw_socketlike()) }
119 }
120
121 #[inline]
129 pub unsafe fn view_raw(raw: RawSocketlike) -> Self {
130 let owned = OwnedSocketlike::from_raw_socketlike(raw);
131 Self {
132 target: ManuallyDrop::new(Target::from_socketlike(owned)),
133 #[cfg(debug_assertions)]
134 orig: raw,
135 _phantom: PhantomData,
136 }
137 }
138}
139
140impl<Target: FilelikeViewType> Deref for FilelikeView<'_, Target> {
141 type Target = Target;
142
143 #[inline]
144 fn deref(&self) -> &Self::Target {
145 &self.target
146 }
147}
148
149impl<Target: SocketlikeViewType> Deref for SocketlikeView<'_, Target> {
150 type Target = Target;
151
152 #[inline]
153 fn deref(&self) -> &Self::Target {
154 &self.target
155 }
156}
157
158impl<Target: FilelikeViewType> Drop for FilelikeView<'_, Target> {
159 #[inline]
160 fn drop(&mut self) {
161 let _raw = unsafe { ManuallyDrop::take(&mut self.target) }
167 .into_filelike()
168 .into_raw_filelike();
169
170 #[cfg(debug_assertions)]
171 debug_assert_eq!(self.orig, _raw);
172 }
173}
174
175impl<Target: SocketlikeViewType> Drop for SocketlikeView<'_, Target> {
176 #[inline]
177 fn drop(&mut self) {
178 let _raw = unsafe { ManuallyDrop::take(&mut self.target) }
184 .into_socketlike()
185 .into_raw_socketlike();
186
187 #[cfg(debug_assertions)]
188 debug_assert_eq!(self.orig, _raw);
189 }
190}
191
192impl<Target: FilelikeViewType> fmt::Debug for FilelikeView<'_, Target> {
193 #[allow(clippy::missing_inline_in_public_items)]
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 f.debug_struct("FilelikeView")
196 .field("target", &*self)
197 .finish()
198 }
199}
200
201impl<Target: SocketlikeViewType> fmt::Debug for SocketlikeView<'_, Target> {
202 #[allow(clippy::missing_inline_in_public_items)]
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 f.debug_struct("SocketlikeView")
205 .field("target", &*self)
206 .finish()
207 }
208}
209
210#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
211unsafe impl FilelikeViewType for OwnedFd {}
212#[cfg(windows)]
213unsafe impl FilelikeViewType for OwnedHandle {}
214#[cfg(windows)]
215unsafe impl SocketlikeViewType for OwnedSocket {}
216unsafe impl FilelikeViewType for std::fs::File {}
217unsafe impl SocketlikeViewType for std::net::TcpStream {}
218unsafe impl SocketlikeViewType for std::net::TcpListener {}
219unsafe impl SocketlikeViewType for std::net::UdpSocket {}
220#[cfg(unix)]
221unsafe impl SocketlikeViewType for std::os::unix::net::UnixStream {}
222#[cfg(unix)]
223unsafe impl SocketlikeViewType for std::os::unix::net::UnixListener {}
224
225#[cfg(unix)]
226unsafe impl SocketlikeViewType for std::os::unix::net::UnixDatagram {}
227#[cfg(not(any(target_os = "wasi", target_os = "hermit")))]
228#[cfg(feature = "os_pipe")]
229unsafe impl FilelikeViewType for os_pipe::PipeWriter {}
230#[cfg(not(any(target_os = "wasi", target_os = "hermit")))]
231#[cfg(feature = "os_pipe")]
232unsafe impl FilelikeViewType for os_pipe::PipeReader {}
233
234#[cfg(not(any(target_os = "wasi", target_os = "hermit")))]
235#[cfg(feature = "socket2")]
236unsafe impl SocketlikeViewType for socket2::Socket {}
237
238#[cfg(not(any(target_os = "wasi", target_os = "hermit")))]
239#[cfg(feature = "async-std")]
240unsafe impl SocketlikeViewType for async_std::net::TcpStream {}
241#[cfg(not(any(target_os = "wasi", target_os = "hermit")))]
242#[cfg(feature = "async-std")]
243unsafe impl SocketlikeViewType for async_std::net::TcpListener {}
244#[cfg(not(any(target_os = "wasi", target_os = "hermit")))]
245#[cfg(feature = "async-std")]
246unsafe impl SocketlikeViewType for async_std::net::UdpSocket {}
247#[cfg(unix)]
248#[cfg(feature = "async-std")]
249unsafe impl SocketlikeViewType for async_std::os::unix::net::UnixStream {}
250#[cfg(unix)]
251#[cfg(feature = "async-std")]
252unsafe impl SocketlikeViewType for async_std::os::unix::net::UnixListener {}
253#[cfg(unix)]
254#[cfg(feature = "async-std")]
255unsafe impl SocketlikeViewType for async_std::os::unix::net::UnixDatagram {}
256
257#[cfg(feature = "mio")]
258unsafe impl SocketlikeViewType for mio::net::TcpStream {}
259#[cfg(feature = "mio")]
260unsafe impl SocketlikeViewType for mio::net::TcpListener {}
261#[cfg(feature = "mio")]
262unsafe impl SocketlikeViewType for mio::net::UdpSocket {}
263#[cfg(unix)]
264#[cfg(feature = "mio")]
265unsafe impl SocketlikeViewType for mio::net::UnixDatagram {}
266#[cfg(unix)]
267#[cfg(feature = "mio")]
268unsafe impl SocketlikeViewType for mio::net::UnixListener {}
269#[cfg(unix)]
270#[cfg(feature = "mio")]
271unsafe impl SocketlikeViewType for mio::net::UnixStream {}
272#[cfg(unix)]
273#[cfg(feature = "mio")]
274unsafe impl FilelikeViewType for mio::unix::pipe::Receiver {}
275#[cfg(unix)]
276#[cfg(feature = "mio")]
277unsafe impl FilelikeViewType for mio::unix::pipe::Sender {}