Skip to content

Commit f33b156

Browse files
authored
Define dedicated error types for HandleOrNull and HandleOrInvalid
Introduce the `InvalidHandleError` and `NullHandleError` error types, corresponding to rust-lang/rust#95387.
1 parent ec8b17b commit f33b156

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

examples/hello.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{
1616
use io_lifetimes::{AsFd, FromFd, OwnedFd};
1717

1818
#[cfg(windows)]
19-
use io_lifetimes::{AsHandle, FromHandle, OwnedHandle};
19+
use io_lifetimes::{AsHandle, FromHandle, InvalidHandleError, OwnedHandle};
2020
#[cfg(windows)]
2121
use std::{convert::TryInto, os::windows::io::RawHandle, ptr::null_mut};
2222

@@ -74,7 +74,7 @@ fn main() -> io::Result<()> {
7474
null_mut() as RawHandle as HANDLE,
7575
)
7676
.try_into()
77-
.map_err(|()| io::Error::last_os_error())?;
77+
.map_err(|_err| io::Error::last_os_error())?;
7878

7979
// Borrow the handle to write to it.
8080
let mut number_of_bytes_written = 0;

src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket};
5656
pub use types::{BorrowedFd, OwnedFd};
5757
#[cfg(not(io_lifetimes_use_std))]
5858
#[cfg(windows)]
59-
pub use types::{BorrowedHandle, BorrowedSocket, HandleOrInvalid, OwnedHandle, OwnedSocket};
59+
pub use types::{
60+
BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError, NullHandleError,
61+
OwnedHandle, OwnedSocket,
62+
};
6063

6164
#[cfg(io_lifetimes_use_std)]
6265
#[cfg(unix)]
@@ -67,7 +70,8 @@ pub use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
6770
#[cfg(io_lifetimes_use_std)]
6871
#[cfg(windows)]
6972
pub use std::os::windows::io::{
70-
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, OwnedHandle, OwnedSocket,
73+
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError,
74+
NullHandleError, OwnedHandle, OwnedSocket,
7175
};
7276

7377
// io-lifetimes defined `FromFd`/`IntoFd` traits instead of just using

src/types.rs

+34-6
Original file line numberDiff line numberDiff line change
@@ -484,17 +484,17 @@ impl BorrowedSocket<'_> {
484484

485485
#[cfg(windows)]
486486
impl TryFrom<HandleOrInvalid> for OwnedHandle {
487-
type Error = ();
487+
type Error = InvalidHandleError;
488488

489489
#[inline]
490-
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, ()> {
490+
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
491491
let raw = handle_or_invalid.0;
492492
if raw as HANDLE == INVALID_HANDLE_VALUE {
493493
// Don't call `CloseHandle`; it'd be harmless, except that it could
494494
// overwrite the `GetLastError` error.
495495
forget(handle_or_invalid);
496496

497-
Err(())
497+
Err(InvalidHandleError(()))
498498
} else {
499499
Ok(OwnedHandle { handle: raw })
500500
}
@@ -503,23 +503,51 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
503503

504504
#[cfg(windows)]
505505
impl TryFrom<HandleOrNull> for OwnedHandle {
506-
type Error = ();
506+
type Error = NullHandleError;
507507

508508
#[inline]
509-
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, ()> {
509+
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
510510
let raw = handle_or_null.0;
511511
if raw.is_null() {
512512
// Don't call `CloseHandle`; it'd be harmless, except that it could
513513
// overwrite the `GetLastError` error.
514514
forget(handle_or_null);
515515

516-
Err(())
516+
Err(NullHandleError(()))
517517
} else {
518518
Ok(OwnedHandle { handle: raw })
519519
}
520520
}
521521
}
522522

523+
/// This is the error type used by [`HandleOrNull`] when attempting to convert
524+
/// into a handle, to indicate that the value is null.
525+
#[derive(Debug, Clone, PartialEq, Eq)]
526+
pub struct NullHandleError(());
527+
528+
impl fmt::Display for NullHandleError {
529+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
530+
"A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
531+
}
532+
}
533+
534+
impl std::error::Error for NullHandleError {}
535+
536+
/// This is the error type used by [`HandleOrInvalid`] when attempting to
537+
/// convert into a handle, to indicate that the value is
538+
/// `INVALID_HANDLE_VALUE`.
539+
#[derive(Debug, Clone, PartialEq, Eq)]
540+
pub struct InvalidHandleError(());
541+
542+
impl fmt::Display for InvalidHandleError {
543+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
544+
"A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
545+
.fmt(fmt)
546+
}
547+
}
548+
549+
impl std::error::Error for InvalidHandleError {}
550+
523551
#[cfg(any(unix, target_os = "wasi"))]
524552
impl AsRawFd for BorrowedFd<'_> {
525553
#[inline]

tests/ffi.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#[cfg(any(unix, windows))]
66
use io_lifetimes::example_ffi::*;
77
#[cfg(windows)]
8-
use io_lifetimes::OwnedHandle;
8+
use io_lifetimes::{InvalidHandleError, OwnedHandle};
99
#[cfg(windows)]
1010
use std::{convert::TryInto, os::windows::io::RawHandle, ptr::null_mut};
1111
#[cfg(windows)]
@@ -28,7 +28,7 @@ fn test_file_not_found() {
2828
#[cfg(windows)]
2929
#[test]
3030
fn test_file_not_found() {
31-
let handle: Result<OwnedHandle, ()> = unsafe {
31+
let handle: Result<OwnedHandle, InvalidHandleError> = unsafe {
3232
CreateFileW(
3333
[
3434
'C' as u16, ':' as _, '/' as _, 'n' as _, 'o' as _, '/' as _, 's' as _, 'u' as _,
@@ -60,7 +60,7 @@ fn test_file_found() {
6060
#[cfg(windows)]
6161
#[test]
6262
fn test_file_found() {
63-
let handle: Result<OwnedHandle, ()> = unsafe {
63+
let handle: Result<OwnedHandle, InvalidHandleError> = unsafe {
6464
CreateFileW(
6565
[
6666
'C' as u16, 'a' as _, 'r' as _, 'g' as _, 'o' as _, '.' as _, 't' as _, 'o' as _,

0 commit comments

Comments
 (0)