io_extras/
grip.rs

1//! "Grip" is an abstraction over "Fd" and "HandleOrSocket". "Handle"
2//! would be the obvious term, but that has a more specific meaning on
3//! Windows.
4
5#[cfg(windows)]
6use crate::os::windows::{
7    AsHandleOrSocket, AsRawHandleOrSocket, AsRawReadWriteHandleOrSocket, AsReadWriteHandleOrSocket,
8    BorrowedHandleOrSocket, FromRawHandleOrSocket, IntoRawHandleOrSocket, OwnedHandleOrSocket,
9    RawHandleOrSocket,
10};
11#[cfg(not(windows))]
12use {
13    crate::os::rustix::{AsRawFd, AsRawReadWriteFd, AsReadWriteFd, FromRawFd, IntoRawFd, RawFd},
14    io_lifetimes::{AsFd, BorrowedFd, OwnedFd},
15};
16
17/// Portability abstraction over `BorrowedFd` and `BorrowedHandleOrSocket`.
18#[cfg(not(windows))]
19pub type BorrowedGrip<'a> = BorrowedFd<'a>;
20/// Portability abstraction over `OwnedFd` and `OwnedHandleOrSocket`.
21#[cfg(not(windows))]
22pub type OwnedGrip = OwnedFd;
23
24/// Portability abstraction over `BorrowedFd` and `BorrowedHandleOrSocket`.
25#[cfg(windows)]
26pub type BorrowedGrip<'a> = BorrowedHandleOrSocket<'a>;
27/// Portability abstraction over `OwnedFd` and `OwnedHandleOrSocket`.
28#[cfg(windows)]
29pub type OwnedGrip = OwnedHandleOrSocket;
30
31/// Portability abstraction over `AsFd` and `AsHandleOrSocket`.
32#[cfg(not(windows))]
33pub trait AsGrip: AsFd {
34    /// Extracts the grip.
35    fn as_grip(&self) -> BorrowedGrip<'_>;
36}
37
38/// Portability abstraction over `AsFd` and `AsHandleOrSocket`.
39#[cfg(windows)]
40pub trait AsGrip: AsHandleOrSocket {
41    /// Extracts the grip.
42    fn as_grip(&self) -> BorrowedGrip<'_>;
43}
44
45/// Portability abstraction over `AsReadWriteFd` and
46/// `AsReadWriteHandleOrSocket`.
47#[cfg(not(windows))]
48pub trait AsReadWriteGrip: AsReadWriteFd {
49    /// Extracts the grip for reading.
50    ///
51    /// Like [`AsGrip::as_grip`], but returns the
52    /// reading grip.
53    fn as_read_grip(&self) -> BorrowedGrip<'_>;
54
55    /// Extracts the grip for writing.
56    ///
57    /// Like [`AsGrip::as_grip`], but returns the
58    /// writing grip.
59    fn as_write_grip(&self) -> BorrowedGrip<'_>;
60}
61
62/// Portability abstraction over `AsReadWriteFd` and
63/// `AsReadWriteHandleOrSocket`.
64#[cfg(windows)]
65pub trait AsReadWriteGrip: AsReadWriteHandleOrSocket {
66    /// Extracts the grip for reading.
67    ///
68    /// Like [`AsGrip::as_grip`], but returns the
69    /// reading grip.
70    fn as_read_grip(&self) -> BorrowedGrip<'_>;
71
72    /// Extracts the grip for writing.
73    ///
74    /// Like [`AsGrip::as_grip`], but returns the
75    /// writing grip.
76    fn as_write_grip(&self) -> BorrowedGrip<'_>;
77}
78
79/// Portability abstraction over `Into<OwnedFd>` and
80/// `Into<OwnedHandleOrSocket>`.
81#[cfg(not(windows))]
82pub trait IntoGrip: Into<OwnedFd> {
83    /// Consume `self` and convert into an `OwnedGrip`.
84    fn into_grip(self) -> OwnedGrip;
85}
86
87/// Portability abstraction over `Into<OwnedFd>` and
88/// `Into<OwnedHandleOrSocket>`.
89#[cfg(windows)]
90pub trait IntoGrip: Into<OwnedHandleOrSocket> {
91    /// Consume `self` and convert into an `OwnedGrip`.
92    fn into_grip(self) -> OwnedGrip;
93}
94
95/// Portability abstraction over `From<OwnedFd>` and
96/// `From<OwnedHandleOrSocket>`.
97#[cfg(not(windows))]
98pub trait FromGrip: From<OwnedFd> {
99    /// Consume an `OwnedGrip` and convert into a `Self`.
100    fn from_grip(owned_grip: OwnedGrip) -> Self;
101}
102
103/// Portability abstraction over `From<OwnedFd>` and
104/// `From<OwnedHandleOrSocket>`.
105#[cfg(windows)]
106pub trait FromGrip: From<OwnedHandleOrSocket> {
107    /// Consume an `OwnedGrip` and convert into a `Self`.
108    fn from_grip(owned_grip: OwnedGrip) -> Self;
109}
110
111#[cfg(not(windows))]
112impl<T: AsFd> AsGrip for T {
113    #[inline]
114    fn as_grip(&self) -> BorrowedGrip<'_> {
115        self.as_fd()
116    }
117}
118
119#[cfg(windows)]
120impl<T: AsHandleOrSocket> AsGrip for T {
121    #[inline]
122    fn as_grip(&self) -> BorrowedGrip<'_> {
123        self.as_handle_or_socket()
124    }
125}
126
127#[cfg(not(windows))]
128impl<T: AsReadWriteFd> AsReadWriteGrip for T {
129    #[inline]
130    fn as_read_grip(&self) -> BorrowedGrip<'_> {
131        self.as_read_fd()
132    }
133
134    #[inline]
135    fn as_write_grip(&self) -> BorrowedGrip<'_> {
136        self.as_write_fd()
137    }
138}
139
140#[cfg(windows)]
141impl<T: AsReadWriteHandleOrSocket> AsReadWriteGrip for T {
142    #[inline]
143    fn as_read_grip(&self) -> BorrowedGrip<'_> {
144        self.as_read_handle_or_socket()
145    }
146
147    #[inline]
148    fn as_write_grip(&self) -> BorrowedGrip<'_> {
149        self.as_write_handle_or_socket()
150    }
151}
152
153#[cfg(not(windows))]
154impl<T: Into<OwnedFd>> IntoGrip for T {
155    #[inline]
156    fn into_grip(self) -> OwnedGrip {
157        self.into()
158    }
159}
160
161#[cfg(windows)]
162impl<T: Into<OwnedHandleOrSocket>> IntoGrip for T {
163    #[inline]
164    fn into_grip(self) -> OwnedGrip {
165        self.into()
166    }
167}
168
169#[cfg(not(windows))]
170impl<T: From<OwnedFd>> FromGrip for T {
171    #[inline]
172    fn from_grip(owned_grip: OwnedGrip) -> Self {
173        Self::from(owned_grip)
174    }
175}
176
177#[cfg(windows)]
178impl<T: From<OwnedHandleOrSocket>> FromGrip for T {
179    #[inline]
180    fn from_grip(owned_grip: OwnedGrip) -> Self {
181        Self::from(owned_grip)
182    }
183}
184
185/// Portability abstraction over `RawFd` and `RawHandleOrSocket`.
186#[cfg(not(windows))]
187pub type RawGrip = RawFd;
188
189/// Portability abstraction over `RawFd` and `RawHandleOrSocket`.
190#[cfg(windows)]
191pub type RawGrip = RawHandleOrSocket;
192
193/// Portability abstraction over `AsFd` and `AsHandleOrSocket`.
194#[cfg(not(windows))]
195pub trait AsRawGrip: AsRawFd {
196    /// Extracts the raw grip.
197    fn as_raw_grip(&self) -> RawGrip;
198}
199
200/// Portability abstraction over `AsFd` and `AsHandleOrSocket`.
201#[cfg(windows)]
202pub trait AsRawGrip: AsRawHandleOrSocket {
203    /// Extracts the raw grip.
204    fn as_raw_grip(&self) -> RawGrip;
205}
206
207/// Portability abstraction over `AsReadWriteFd` and
208/// `AsReadWriteHandleOrSocket`.
209#[cfg(not(windows))]
210pub trait AsRawReadWriteGrip: AsRawReadWriteFd {
211    /// Extracts the grip for reading.
212    ///
213    /// Like [`AsRawGrip::as_raw_grip`], but returns the
214    /// raw reading grip.
215    fn as_raw_read_grip(&self) -> RawGrip;
216
217    /// Extracts the grip for writing.
218    ///
219    /// Like [`AsRawGrip::as_raw_grip`], but returns the
220    /// raw writing grip.
221    fn as_raw_write_grip(&self) -> RawGrip;
222}
223
224/// Portability abstraction over `AsReadWriteFd` and
225/// `AsReadWriteHandleOrSocket`.
226#[cfg(windows)]
227pub trait AsRawReadWriteGrip: AsRawReadWriteHandleOrSocket {
228    /// Extracts the grip for reading.
229    ///
230    /// Like [`AsRawGrip::as_raw_grip`], but returns the
231    /// raw reading grip.
232    fn as_raw_read_grip(&self) -> RawGrip;
233
234    /// Extracts the grip for writing.
235    ///
236    /// Like [`AsRawGrip::as_raw_grip`], but returns the
237    /// raw writing grip.
238    fn as_raw_write_grip(&self) -> RawGrip;
239}
240
241/// Portability abstraction over `IntoRawFd` and
242/// `IntoRawHandleOrSocket`.
243#[cfg(not(windows))]
244pub trait IntoRawGrip: IntoRawFd {
245    /// Consume `self` and convert into an `RawGrip`.
246    fn into_raw_grip(self) -> RawGrip;
247}
248
249/// Portability abstraction over `IntoRawFd` and
250/// `IntoRawHandleOrSocket`.
251#[cfg(windows)]
252pub trait IntoRawGrip: IntoRawHandleOrSocket {
253    /// Consume `self` and convert into an `RawGrip`.
254    fn into_raw_grip(self) -> RawGrip;
255}
256
257/// Portability abstraction over `From<OwnedFd>` and
258/// `From<OwnedHandleOrSocket>`.
259#[cfg(not(windows))]
260pub trait FromRawGrip: FromRawFd {
261    /// Consume an `RawGrip` and convert into a `Self`.
262    ///
263    /// # Safety
264    ///
265    /// `raw_grip` must be a suitable grip for assuming ownership.
266    unsafe fn from_raw_grip(raw_grip: RawGrip) -> Self;
267}
268
269/// Portability abstraction over `From<OwnedFd>` and
270/// `From<OwnedHandleOrSocket>`.
271#[cfg(windows)]
272pub trait FromRawGrip: FromRawHandleOrSocket {
273    /// Consume an `RawGrip` and convert into a `Self`.
274    ///
275    /// # Safety
276    ///
277    /// `raw_grip` must be a suitable grip for assuming ownership.
278    unsafe fn from_raw_grip(raw_grip: RawGrip) -> Self;
279}
280
281#[cfg(not(windows))]
282impl<T: AsRawFd> AsRawGrip for T {
283    #[inline]
284    fn as_raw_grip(&self) -> RawGrip {
285        self.as_raw_fd()
286    }
287}
288
289#[cfg(windows)]
290impl<T: AsRawHandleOrSocket> AsRawGrip for T {
291    #[inline]
292    fn as_raw_grip(&self) -> RawGrip {
293        self.as_raw_handle_or_socket()
294    }
295}
296
297#[cfg(not(windows))]
298impl<T: AsRawReadWriteFd> AsRawReadWriteGrip for T {
299    #[inline]
300    fn as_raw_read_grip(&self) -> RawGrip {
301        self.as_raw_read_fd()
302    }
303
304    #[inline]
305    fn as_raw_write_grip(&self) -> RawGrip {
306        self.as_raw_write_fd()
307    }
308}
309
310#[cfg(windows)]
311impl<T: AsRawReadWriteHandleOrSocket> AsRawReadWriteGrip for T {
312    #[inline]
313    fn as_raw_read_grip(&self) -> RawGrip {
314        self.as_raw_read_handle_or_socket()
315    }
316
317    #[inline]
318    fn as_raw_write_grip(&self) -> RawGrip {
319        self.as_raw_write_handle_or_socket()
320    }
321}
322
323#[cfg(not(windows))]
324impl<T: IntoRawFd> IntoRawGrip for T {
325    #[inline]
326    fn into_raw_grip(self) -> RawGrip {
327        self.into_raw_fd()
328    }
329}
330
331#[cfg(windows)]
332impl<T: IntoRawHandleOrSocket> IntoRawGrip for T {
333    #[inline]
334    fn into_raw_grip(self) -> RawGrip {
335        self.into_raw_handle_or_socket()
336    }
337}
338
339#[cfg(not(windows))]
340impl<T: FromRawFd> FromRawGrip for T {
341    #[inline]
342    unsafe fn from_raw_grip(raw_grip: RawGrip) -> Self {
343        Self::from_raw_fd(raw_grip)
344    }
345}
346
347#[cfg(windows)]
348impl<T: FromRawHandleOrSocket> FromRawGrip for T {
349    #[inline]
350    unsafe fn from_raw_grip(raw_grip: RawGrip) -> Self {
351        Self::from_raw_handle_or_socket(raw_grip)
352    }
353}
354
355/// Portability abstraction over `BorrowedFd::from_raw_fd` and
356/// `BorrowedHandleOrSocket::from_raw_handle_or_socket`.
357///
358/// # Safety
359///
360/// See the safety conditions for [`borrow_raw`].
361///
362/// [`borrow_raw`]: https://doc.rust-lang.org/stable/std/os/unix/io/struct.BorrowedFd.html#method.borrow_raw
363#[cfg(not(windows))]
364#[must_use]
365#[inline]
366pub unsafe fn borrow_raw<'a>(grip: RawGrip) -> BorrowedGrip<'a> {
367    BorrowedFd::borrow_raw(grip)
368}
369
370/// Portability abstraction over `BorrowedFd::from_raw_fd` and
371/// `BorrowedHandleOrSocket::from_raw_handle_or_socket`.
372///
373/// # Safety
374///
375/// See the safety conditions for [`BorrowedHandle::borrow_raw`], and
376/// [`BorrowedSocket::borrow_raw`].
377///
378/// [`BorrowedHandle::borrow_raw`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.BorrowedHandle.html#method.borrow_raw
379/// [`BorrowedSocket::borrow_raw`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.BorrowedSocket.html#method.borrow_raw
380#[cfg(windows)]
381#[must_use]
382#[inline]
383pub unsafe fn borrow_raw<'a>(grip: RawGrip) -> BorrowedGrip<'a> {
384    BorrowedHandleOrSocket::borrow_raw(grip)
385}