Define dedicated error types for HandleOrNull and HandleOrInvalid

Introduce the `InvalidHandleError` and `NullHandleError` error types,
corresponding to rust-lang/rust#95387.
This commit is contained in:
Dan Gohman
2022-04-29 07:00:00 -07:00
committed by GitHub
parent a281008efe
commit 0acbd122de
4 changed files with 45 additions and 13 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ use std::{
use io_lifetimes::{AsFd, FromFd, OwnedFd};
#[cfg(windows)]
use io_lifetimes::{AsHandle, FromHandle, OwnedHandle};
use io_lifetimes::{AsHandle, FromHandle, InvalidHandleError, OwnedHandle};
#[cfg(windows)]
use std::{convert::TryInto, os::windows::io::RawHandle, ptr::null_mut};
@@ -74,7 +74,7 @@ fn main() -> io::Result<()> {
null_mut() as RawHandle as HANDLE,
)
.try_into()
.map_err(|()| io::Error::last_os_error())?;
.map_err(|_err| io::Error::last_os_error())?;
// Borrow the handle to write to it.
let mut number_of_bytes_written = 0;
+6 -2
View File
@@ -56,7 +56,10 @@ pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket};
pub use types::{BorrowedFd, OwnedFd};
#[cfg(not(io_lifetimes_use_std))]
#[cfg(windows)]
pub use types::{BorrowedHandle, BorrowedSocket, HandleOrInvalid, OwnedHandle, OwnedSocket};
pub use types::{
BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError, NullHandleError,
OwnedHandle, OwnedSocket,
};
#[cfg(io_lifetimes_use_std)]
#[cfg(unix)]
@@ -67,7 +70,8 @@ pub use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(io_lifetimes_use_std)]
#[cfg(windows)]
pub use std::os::windows::io::{
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, OwnedHandle, OwnedSocket,
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError,
NullHandleError, OwnedHandle, OwnedSocket,
};
// io-lifetimes defined `FromFd`/`IntoFd` traits instead of just using
+34 -6
View File
@@ -484,17 +484,17 @@ impl BorrowedSocket<'_> {
#[cfg(windows)]
impl TryFrom<HandleOrInvalid> for OwnedHandle {
type Error = ();
type Error = InvalidHandleError;
#[inline]
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, ()> {
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
let raw = handle_or_invalid.0;
if raw as HANDLE == INVALID_HANDLE_VALUE {
// Don't call `CloseHandle`; it'd be harmless, except that it could
// overwrite the `GetLastError` error.
forget(handle_or_invalid);
Err(())
Err(InvalidHandleError(()))
} else {
Ok(OwnedHandle { handle: raw })
}
@@ -503,23 +503,51 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
#[cfg(windows)]
impl TryFrom<HandleOrNull> for OwnedHandle {
type Error = ();
type Error = NullHandleError;
#[inline]
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, ()> {
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
let raw = handle_or_null.0;
if raw.is_null() {
// Don't call `CloseHandle`; it'd be harmless, except that it could
// overwrite the `GetLastError` error.
forget(handle_or_null);
Err(())
Err(NullHandleError(()))
} else {
Ok(OwnedHandle { handle: raw })
}
}
}
/// This is the error type used by [`HandleOrNull`] when attempting to convert
/// into a handle, to indicate that the value is null.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NullHandleError(());
impl fmt::Display for NullHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
}
}
impl std::error::Error for NullHandleError {}
/// This is the error type used by [`HandleOrInvalid`] when attempting to
/// convert into a handle, to indicate that the value is
/// `INVALID_HANDLE_VALUE`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidHandleError(());
impl fmt::Display for InvalidHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
.fmt(fmt)
}
}
impl std::error::Error for InvalidHandleError {}
#[cfg(any(unix, target_os = "wasi"))]
impl AsRawFd for BorrowedFd<'_> {
#[inline]
+3 -3
View File
@@ -5,7 +5,7 @@
#[cfg(any(unix, windows))]
use io_lifetimes::example_ffi::*;
#[cfg(windows)]
use io_lifetimes::OwnedHandle;
use io_lifetimes::{InvalidHandleError, OwnedHandle};
#[cfg(windows)]
use std::{convert::TryInto, os::windows::io::RawHandle, ptr::null_mut};
#[cfg(windows)]
@@ -28,7 +28,7 @@ fn test_file_not_found() {
#[cfg(windows)]
#[test]
fn test_file_not_found() {
let handle: Result<OwnedHandle, ()> = unsafe {
let handle: Result<OwnedHandle, InvalidHandleError> = unsafe {
CreateFileW(
[
'C' as u16, ':' as _, '/' as _, 'n' as _, 'o' as _, '/' as _, 's' as _, 'u' as _,
@@ -60,7 +60,7 @@ fn test_file_found() {
#[cfg(windows)]
#[test]
fn test_file_found() {
let handle: Result<OwnedHandle, ()> = unsafe {
let handle: Result<OwnedHandle, InvalidHandleError> = unsafe {
CreateFileW(
[
'C' as u16, 'a' as _, 'r' as _, 'g' as _, 'o' as _, '.' as _, 't' as _, 'o' as _,