Coverage Report

Created: 2025-10-10 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-2.0.4/src/portability.rs
Line
Count
Source
1
//! Portability abstractions over `Owned*` and `Borrowed*`.
2
//!
3
//! On Unix, "everything is a file descriptor". On Windows, file/pipe/process
4
//! handles are distinct from socket descriptors. This file provides a minimal
5
//! layer of portability over this difference.
6
7
use crate::views::{FilelikeView, FilelikeViewType, SocketlikeView, SocketlikeViewType};
8
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
9
use crate::{AsFd, BorrowedFd, OwnedFd};
10
#[cfg(windows)]
11
use crate::{AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, OwnedHandle, OwnedSocket};
12
13
/// A reference to a filelike object.
14
///
15
/// This is a portability abstraction over Unix-like [`BorrowedFd`] and
16
/// Windows' `BorrowedHandle`.
17
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
18
pub type BorrowedFilelike<'filelike> = BorrowedFd<'filelike>;
19
20
/// A reference to a filelike object.
21
///
22
/// This is a portability abstraction over Unix-like `BorrowedFd` and
23
/// Windows' [`BorrowedHandle`].
24
#[cfg(windows)]
25
pub type BorrowedFilelike<'filelike> = BorrowedHandle<'filelike>;
26
27
/// A reference to a socketlike object.
28
///
29
/// This is a portability abstraction over Unix-like [`BorrowedFd`] and
30
/// Windows' `BorrowedSocket`.
31
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
32
pub type BorrowedSocketlike<'socketlike> = BorrowedFd<'socketlike>;
33
34
/// A reference to a socketlike object.
35
///
36
/// This is a portability abstraction over Unix-like `BorrowedFd` and
37
/// Windows' [`BorrowedSocket`].
38
#[cfg(windows)]
39
pub type BorrowedSocketlike<'socketlike> = BorrowedSocket<'socketlike>;
40
41
/// An owned filelike object.
42
///
43
/// This is a portability abstraction over Unix-like [`OwnedFd`] and
44
/// Windows' `OwnedHandle`.
45
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
46
pub type OwnedFilelike = OwnedFd;
47
48
/// An owned filelike object.
49
///
50
/// This is a portability abstraction over Unix-like `OwnedFd` and
51
/// Windows' [`OwnedHandle`].
52
#[cfg(windows)]
53
pub type OwnedFilelike = OwnedHandle;
54
55
/// An owned socketlike object.
56
///
57
/// This is a portability abstraction over Unix-like [`OwnedFd`] and
58
/// Windows' `OwnedSocket`.
59
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
60
pub type OwnedSocketlike = OwnedFd;
61
62
/// An owned socketlike object.
63
///
64
/// This is a portability abstraction over Unix-like `OwnedFd` and
65
/// Windows' [`OwnedSocket`].
66
#[cfg(windows)]
67
pub type OwnedSocketlike = OwnedSocket;
68
69
/// A portable trait to borrow a reference from an underlying filelike object.
70
///
71
/// This is a portability abstraction over Unix-like [`AsFd`] and Windows'
72
/// `AsHandle`. It also provides the `as_filelike_view` convenience function
73
/// providing typed views.
74
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
75
pub trait AsFilelike: AsFd {
76
    /// Borrows the reference.
77
    ///
78
    /// # Example
79
    ///
80
    /// ```rust,no_run
81
    /// use std::fs::File;
82
    /// # use std::io;
83
    /// use io_lifetimes::{AsFilelike, BorrowedFilelike};
84
    ///
85
    /// let mut f = File::open("foo.txt")?;
86
    /// let borrowed_filelike: BorrowedFilelike<'_> = f.as_filelike();
87
    /// # Ok::<(), io::Error>(())
88
    /// ```
89
    fn as_filelike(&self) -> BorrowedFilelike<'_>;
90
91
    /// Return a borrowing view of a resource which dereferences to a
92
    /// `&Target`.
93
    ///
94
    /// Note that [`Read`] or [`Write`] require `&mut Target`, but in some
95
    /// cases, such as [`File`], `Read` and `Write` are implemented for
96
    /// `&Target` in addition to `Target`, and you can get a `&mut &Target`
97
    /// by doing `&*` on the resuting view, like this:
98
    ///
99
    /// ```rust,ignore
100
    /// let v = f.as_filelike_view::<std::fs::File>();
101
    /// (&*v).read(&mut buf).unwrap();
102
    /// ```
103
    ///
104
    /// [`File`]: std::fs::File
105
    /// [`Read`]: std::io::Read
106
    /// [`Write`]: std::io::Write
107
    fn as_filelike_view<Target: FilelikeViewType>(&self) -> FilelikeView<'_, Target>;
108
}
109
110
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
111
impl<T: AsFd> AsFilelike for T {
112
    #[inline]
113
0
    fn as_filelike(&self) -> BorrowedFilelike<'_> {
114
0
        self.as_fd()
115
0
    }
Unexecuted instantiation: <std::fs::File as io_lifetimes::portability::AsFilelike>::as_filelike
Unexecuted instantiation: <std::os::fd::owned::BorrowedFd as io_lifetimes::portability::AsFilelike>::as_filelike
116
117
    #[inline]
118
0
    fn as_filelike_view<Target: FilelikeViewType>(&self) -> FilelikeView<'_, Target> {
119
0
        FilelikeView::new(self)
120
0
    }
Unexecuted instantiation: <std::fs::File as io_lifetimes::portability::AsFilelike>::as_filelike_view::<std::fs::File>
Unexecuted instantiation: <std::os::fd::owned::BorrowedFd as io_lifetimes::portability::AsFilelike>::as_filelike_view::<std::fs::File>
121
}
122
123
/// A portable trait to borrow a reference from an underlying filelike object.
124
///
125
/// This is a portability abstraction over Unix-like `AsFd` and Windows'
126
/// [`AsHandle`]. It also provides the `as_filelike_view` convenience function
127
/// providing typed views.
128
#[cfg(windows)]
129
pub trait AsFilelike: AsHandle {
130
    /// Borrows the reference.
131
    ///
132
    /// # Example
133
    ///
134
    /// ```rust,no_run
135
    /// use std::fs::File;
136
    /// # use std::io;
137
    /// use io_lifetimes::{AsFilelike, BorrowedFilelike};
138
    ///
139
    /// let mut f = File::open("foo.txt")?;
140
    /// let borrowed_filelike: BorrowedFilelike<'_> = f.as_filelike();
141
    /// # Ok::<(), io::Error>(())
142
    /// ```
143
    fn as_filelike(&self) -> BorrowedFilelike<'_>;
144
145
    /// Return a borrowing view of a resource which dereferences to a
146
    /// `&Target`.
147
    ///
148
    /// Note that [`Read`] or [`Write`] require `&mut Target`, but in some
149
    /// cases, such as [`File`], `Read` and `Write` are implemented for
150
    /// `&Target` in addition to `Target`, and you can get a `&mut &Target`
151
    /// by doing `&*` on the resuting view, like this:
152
    ///
153
    /// ```rust,ignore
154
    /// let v = f.as_filelike_view::<std::fs::File>();
155
    /// (&*v).read(&mut buf).unwrap();
156
    /// ```
157
    ///
158
    /// [`File`]: std::fs::File
159
    /// [`Read`]: std::io::Read
160
    /// [`Write`]: std::io::Write
161
    fn as_filelike_view<Target: FilelikeViewType>(&self) -> FilelikeView<'_, Target>;
162
}
163
164
#[cfg(windows)]
165
impl<T: AsHandle> AsFilelike for T {
166
    #[inline]
167
    fn as_filelike(&self) -> BorrowedFilelike<'_> {
168
        self.as_handle()
169
    }
170
171
    #[inline]
172
    fn as_filelike_view<Target: FilelikeViewType>(&self) -> FilelikeView<'_, Target> {
173
        FilelikeView::new(self)
174
    }
175
}
176
177
/// A portable trait to borrow a reference from an underlying socketlike
178
/// object.
179
///
180
/// This is a portability abstraction over Unix-like [`AsFd`] and Windows'
181
/// `AsSocket`. It also provides the `as_socketlike_view` convenience
182
/// function providing typed views.
183
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
184
pub trait AsSocketlike: AsFd {
185
    /// Borrows the reference.
186
    fn as_socketlike(&self) -> BorrowedSocketlike<'_>;
187
188
    /// Return a borrowing view of a resource which dereferences to a
189
    /// `&Target`.
190
    ///
191
    /// Note that [`Read`] or [`Write`] require `&mut Target`, but in some
192
    /// cases, such as [`TcpStream`], `Read` and `Write` are implemented
193
    /// for `&Target` in addition to `Target`, and you can get a `&mut
194
    /// &Target` by doing `&*` on the resuting view, like this:
195
    ///
196
    /// ```rust,ignore
197
    /// let v = s.as_socketlike_view::<std::net::TcpStream>();
198
    /// (&*v).read(&mut buf).unwrap();
199
    /// ```
200
    ///
201
    /// [`TcpStream`]: std::net::TcpStream
202
    /// [`Read`]: std::io::Read
203
    /// [`Write`]: std::io::Write
204
    fn as_socketlike_view<Target: SocketlikeViewType>(&self) -> SocketlikeView<'_, Target>;
205
}
206
207
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
208
impl<T: AsFd> AsSocketlike for T {
209
    #[inline]
210
    fn as_socketlike(&self) -> BorrowedSocketlike<'_> {
211
        self.as_fd()
212
    }
213
214
    #[inline]
215
    fn as_socketlike_view<Target: SocketlikeViewType>(&self) -> SocketlikeView<'_, Target> {
216
        SocketlikeView::new(self)
217
    }
218
}
219
220
/// A portable trait to borrow a reference from an underlying socketlike
221
/// object.
222
///
223
/// This is a portability abstraction over Unix-like `AsFd` and Windows'
224
/// [`AsSocket`]. It also provides the `as_socketlike_view` convenience
225
/// function providing typed views.
226
#[cfg(windows)]
227
pub trait AsSocketlike: AsSocket {
228
    /// Borrows the reference.
229
    fn as_socketlike(&self) -> BorrowedSocketlike;
230
231
    /// Return a borrowing view of a resource which dereferences to a
232
    /// `&Target`.
233
    ///
234
    /// Note that [`Read`] or [`Write`] require `&mut Target`, but in some
235
    /// cases, such as [`TcpStream`], `Read` and `Write` are implemented
236
    /// for `&Target` in addition to `Target`, and you can get a `&mut
237
    /// &Target` by doing `&*` on the resuting view, like this:
238
    ///
239
    /// ```rust,ignore
240
    /// let v = s.as_socketlike_view::<std::net::TcpStream>();
241
    /// (&*v).read(&mut buf).unwrap();
242
    /// ```
243
    ///
244
    /// [`TcpStream`]: std::net::TcpStream
245
    fn as_socketlike_view<Target: SocketlikeViewType>(&self) -> SocketlikeView<'_, Target>;
246
}
247
248
#[cfg(windows)]
249
impl<T: AsSocket> AsSocketlike for T {
250
    #[inline]
251
    fn as_socketlike(&self) -> BorrowedSocketlike<'_> {
252
        self.as_socket()
253
    }
254
255
    #[inline]
256
    fn as_socketlike_view<Target: SocketlikeViewType>(&self) -> SocketlikeView<'_, Target> {
257
        SocketlikeView::new(self)
258
    }
259
}
260
261
/// A portable trait to express the ability to consume an object and acquire
262
/// ownership of its filelike object.
263
///
264
/// This is a portability abstraction over Unix-like [`Into<OwnedFd>`] and
265
/// Windows' `Into<OwnedHandle>`.
266
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
267
pub trait IntoFilelike: Into<OwnedFd> {
268
    /// Consumes this object, returning the underlying filelike object.
269
    ///
270
    /// # Example
271
    ///
272
    /// ```rust,no_run
273
    /// use std::fs::File;
274
    /// # use std::io;
275
    /// use io_lifetimes::{IntoFilelike, OwnedFilelike};
276
    ///
277
    /// let f = File::open("foo.txt")?;
278
    /// let owned_filelike: OwnedFilelike = f.into_filelike();
279
    /// # Ok::<(), io::Error>(())
280
    /// ```
281
    fn into_filelike(self) -> OwnedFilelike;
282
}
283
284
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
285
impl<T: Into<OwnedFd>> IntoFilelike for T {
286
    #[inline]
287
0
    fn into_filelike(self) -> OwnedFilelike {
288
0
        self.into()
289
0
    }
290
}
291
292
/// A portable trait to express the ability to consume an object and acquire
293
/// ownership of its filelike object.
294
///
295
/// This is a portability abstraction over Unix-like `Into<OwnedFd>` and
296
/// Windows' [`Into<OwnedHandle>`].
297
#[cfg(windows)]
298
pub trait IntoFilelike: Into<OwnedHandle> {
299
    /// Consumes this object, returning the underlying filelike object.
300
    fn into_filelike(self) -> OwnedFilelike;
301
}
302
303
#[cfg(windows)]
304
impl<T: Into<OwnedHandle>> IntoFilelike for T {
305
    #[inline]
306
    fn into_filelike(self) -> OwnedFilelike {
307
        self.into()
308
    }
309
}
310
311
/// A portable trait to express the ability to consume an object and acquire
312
/// ownership of its socketlike object.
313
///
314
/// This is a portability abstraction over Unix-like [`Into<OwnedFd>`] and
315
/// Windows' `Into<OwnedSocket>`.
316
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
317
pub trait IntoSocketlike: Into<OwnedFd> {
318
    /// Consumes this object, returning the underlying socketlike object.
319
    fn into_socketlike(self) -> OwnedSocketlike;
320
}
321
322
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
323
impl<T: Into<OwnedFd>> IntoSocketlike for T {
324
    #[inline]
325
    fn into_socketlike(self) -> OwnedSocketlike {
326
        self.into()
327
    }
328
}
329
330
/// A portable trait to express the ability to consume an object and acquire
331
/// ownership of its socketlike object.
332
///
333
/// This is a portability abstraction over Unix-like `Into<OwnedFd>` and
334
/// Windows' [`Into<OwnedSocket>`].
335
#[cfg(windows)]
336
pub trait IntoSocketlike: Into<OwnedSocket> {
337
    /// Consumes this object, returning the underlying socketlike object.
338
    ///
339
    /// # Example
340
    ///
341
    /// ```rust,no_run
342
    /// use std::fs::File;
343
    /// # use std::io;
344
    /// use io_lifetimes::{IntoFilelike, OwnedFilelike};
345
    ///
346
    /// let f = File::open("foo.txt")?;
347
    /// let owned_filelike: OwnedFilelike = f.into_filelike();
348
    /// # Ok::<(), io::Error>(())
349
    /// ```
350
    fn into_socketlike(self) -> OwnedSocketlike;
351
}
352
353
#[cfg(windows)]
354
impl<T: Into<OwnedSocket>> IntoSocketlike for T {
355
    #[inline]
356
    fn into_socketlike(self) -> OwnedSocketlike {
357
        self.into()
358
    }
359
}
360
361
/// A portable trait to express the ability to construct an object from a
362
/// filelike object.
363
///
364
/// This is a portability abstraction over Unix-like [`From<OwnedFd>`] and
365
/// Windows' `From<OwnedHandle>`. It also provides the `from_into_filelike`
366
/// convenience function providing simplified from+into conversions.
367
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
368
pub trait FromFilelike: From<OwnedFd> {
369
    /// Constructs a new instance of `Self` from the given filelike object.
370
    ///
371
    /// # Example
372
    ///
373
    /// ```rust,no_run
374
    /// use std::fs::File;
375
    /// # use std::io;
376
    /// use io_lifetimes::{FromFilelike, IntoFilelike, OwnedFilelike};
377
    ///
378
    /// let f = File::open("foo.txt")?;
379
    /// let owned_filelike: OwnedFilelike = f.into_filelike();
380
    /// let f = File::from_filelike(owned_filelike);
381
    /// # Ok::<(), io::Error>(())
382
    /// ```
383
    fn from_filelike(owned: OwnedFilelike) -> Self;
384
385
    /// Constructs a new instance of `Self` from the given filelike object
386
    /// converted from `into_owned`.
387
    ///
388
    /// # Example
389
    ///
390
    /// ```rust,no_run
391
    /// use std::fs::File;
392
    /// # use std::io;
393
    /// use io_lifetimes::{FromFilelike, IntoFilelike};
394
    ///
395
    /// let f = File::open("foo.txt")?;
396
    /// let f = File::from_into_filelike(f);
397
    /// # Ok::<(), io::Error>(())
398
    /// ```
399
    fn from_into_filelike<Owned: IntoFilelike>(owned: Owned) -> Self;
400
}
401
402
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
403
impl<T: From<OwnedFd>> FromFilelike for T {
404
    #[inline]
405
0
    fn from_filelike(owned: OwnedFilelike) -> Self {
406
0
        Self::from(owned)
407
0
    }
408
409
    #[inline]
410
    fn from_into_filelike<Owned: IntoFilelike>(owned: Owned) -> Self {
411
        Self::from_filelike(owned.into_filelike())
412
    }
413
}
414
415
/// A portable trait to express the ability to construct an object from a
416
/// filelike object.
417
///
418
/// This is a portability abstraction over Unix-like `From<OwnedFd>` and
419
/// Windows' [`From<OwnedHandle>`]. It also provides the `from_into_filelike`
420
/// convenience function providing simplified from+into conversions.
421
#[cfg(windows)]
422
pub trait FromFilelike: From<OwnedHandle> {
423
    /// Constructs a new instance of `Self` from the given filelike object.
424
    ///
425
    /// # Example
426
    ///
427
    /// ```rust,no_run
428
    /// use std::fs::File;
429
    /// # use std::io;
430
    /// use io_lifetimes::{FromFilelike, IntoFilelike, OwnedFilelike};
431
    ///
432
    /// let f = File::open("foo.txt")?;
433
    /// let owned_filelike: OwnedFilelike = f.into_filelike();
434
    /// let f = File::from_filelike(owned_filelike);
435
    /// # Ok::<(), io::Error>(())
436
    /// ```
437
    fn from_filelike(owned: OwnedFilelike) -> Self;
438
439
    /// Constructs a new instance of `Self` from the given filelike object
440
    /// converted from `into_owned`.
441
    ///
442
    /// # Example
443
    ///
444
    /// ```rust,no_run
445
    /// use std::fs::File;
446
    /// # use std::io;
447
    /// use io_lifetimes::{FromFilelike, IntoFilelike};
448
    ///
449
    /// let f = File::open("foo.txt")?;
450
    /// let f = File::from_into_filelike(f);
451
    /// # Ok::<(), io::Error>(())
452
    /// ```
453
    fn from_into_filelike<Owned: IntoFilelike>(owned: Owned) -> Self;
454
}
455
456
#[cfg(windows)]
457
impl<T: From<OwnedHandle>> FromFilelike for T {
458
    #[inline]
459
    fn from_filelike(owned: OwnedFilelike) -> Self {
460
        Self::from(owned)
461
    }
462
463
    #[inline]
464
    fn from_into_filelike<Owned: IntoFilelike>(owned: Owned) -> Self {
465
        Self::from_filelike(owned.into_filelike())
466
    }
467
}
468
469
/// A portable trait to express the ability to construct an object from a
470
/// socketlike object.
471
///
472
/// This is a portability abstraction over Unix-like [`From<OwnedFd>`] and
473
/// Windows' `From<OwnedSocketFrom<OwnedSocket>` It also provides the
474
/// `from_into_socketlike` convenience function providing simplified from+into
475
/// conversions.
476
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
477
pub trait FromSocketlike: From<OwnedFd> {
478
    /// Constructs a new instance of `Self` from the given socketlike object.
479
    fn from_socketlike(owned: OwnedSocketlike) -> Self;
480
481
    /// Constructs a new instance of `Self` from the given socketlike object
482
    /// converted from `into_owned`.
483
    fn from_into_socketlike<Owned: IntoSocketlike>(owned: Owned) -> Self;
484
}
485
486
#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
487
impl<T: From<OwnedFd>> FromSocketlike for T {
488
    #[inline]
489
    fn from_socketlike(owned: OwnedSocketlike) -> Self {
490
        Self::from(owned)
491
    }
492
493
    #[inline]
494
    fn from_into_socketlike<Owned: IntoSocketlike>(owned: Owned) -> Self {
495
        Self::from_socketlike(owned.into_socketlike())
496
    }
497
}
498
499
/// A portable trait to express the ability to construct an object from a
500
/// socketlike object.
501
///
502
/// This is a portability abstraction over Unix-like `From<OwnedFd>` and
503
/// Windows' [`From<OwnedSocket>`]. It also provides the `from_into_socketlike`
504
/// convenience function providing simplified from+into conversions.
505
#[cfg(windows)]
506
pub trait FromSocketlike: From<OwnedSocket> {
507
    /// Constructs a new instance of `Self` from the given socketlike object.
508
    fn from_socketlike(owned: OwnedSocketlike) -> Self;
509
510
    /// Constructs a new instance of `Self` from the given socketlike object
511
    /// converted from `into_owned`.
512
    fn from_into_socketlike<Owned: IntoSocketlike>(owned: Owned) -> Self;
513
}
514
515
#[cfg(windows)]
516
impl<T: From<OwnedSocket>> FromSocketlike for T {
517
    #[inline]
518
    fn from_socketlike(owned: OwnedSocketlike) -> Self {
519
        Self::from(owned)
520
    }
521
522
    #[inline]
523
    fn from_into_socketlike<Owned: IntoSocketlike>(owned: Owned) -> Self {
524
        Self::from_socketlike(owned.into_socketlike())
525
    }
526
}