mirror of
https://github.com/openharmony/third_party_rust_io-lifetimes.git
synced 2026-07-01 21:04:05 -04:00
Update for io_safety being stabilized. (#41)
* Update for io_safety being stabilized. io_safety is now [stable in Rust 1.63]! This PR updates io-lifetimes to use the standard library types and traits when available, and use its own types and traits on older Rust versions. The traits `FromFd` and `IntoFd` are now marked as deprecated. These are replaced by `From<OwnedFd>` and `From<...> for OwnedFd` in the standard library, and users should migrate accordingly. [stable in Rust 1.63]: https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html#rust-ownership-for-raw-file-descriptorshandles-io-safety * Disable deprecation warnings for our own uses of `FromFd` and `IntoFd`. And, migrate the portability types and traits to use `From<OwnedFd>` and `Into<OwnedFd>`. * Deprecate the `from_fd` function, rather than the `FromFd` trait. This allows the `from_into_fd` extension to continue working, for now.
This commit is contained in:
@@ -95,37 +95,16 @@ is what motivates having `BorrowedFd` instead of just using `&OwnedFd`.
|
||||
Note the use of `Option<OwnedFd>` as the return value of `open`, representing
|
||||
the fact that it can either succeed or fail.
|
||||
|
||||
## I/O Safety in Rust Nightly
|
||||
## I/O Safety in Rust
|
||||
|
||||
The I/O Safety
|
||||
[implementation PR](https://github.com/rust-lang/rust/pull/87329) has now
|
||||
landed and is available on Rust Nightly. It can be used directly, or through
|
||||
io-lifetimes: when `io_lifetimes_use_std` mode is enabled, io-lifetimes uses
|
||||
the std's `OwnedFd`, `BorrowedFd`, and `AsFd` instead of defining its own.
|
||||
|
||||
To enable `io_lifetimes_use_std` mode:
|
||||
- Set the environment variable `RUSTFLAGS=--cfg=io_lifetimes_use_std`, and
|
||||
- add `#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]` to your
|
||||
lib.rs or main.rs.
|
||||
|
||||
Note that, unfortunately, `io_lifetimes_use_std` mode doesn't support the
|
||||
optional impls for third-party crates.
|
||||
|
||||
The code in `std` uses `From<OwnedFd>` and `Into<OwnedFd>` instead of `FromFd`
|
||||
and `IntoFd`. io-lifetimes is unable to provide impls for these for third-party
|
||||
types, so it continues to provide `FromFd` and `IntoFd` for now, with default
|
||||
impls that forward to `From<OwnedFd>` and `Into<OwnedFd>` in
|
||||
`io_lifetimes_use_std` mode.
|
||||
I/O Safety feature is stablized in Rust 1.63. With this version or later,
|
||||
io-lifetimes will use and re-export the standard-library types and traits. With
|
||||
older versions, io-lifetimes defines its own copy of these types and traits.
|
||||
|
||||
io-lifetimes also includes several features which are not (yet?) in std,
|
||||
including the portability traits `AsFilelike`/`AsSocketlike`/etc., the
|
||||
`from_into_*` functions in the `From*` traits, and [views].
|
||||
|
||||
If you test a crate with the std I/O safety types and traits, or io-lifetimes
|
||||
in `io_lifetimes_use_std` mode, please post a note about it in the
|
||||
[I/O safety tracking issue] as an example of usage.
|
||||
|
||||
[I/O safety tracking issue]: https://github.com/rust-lang/rust/issues/87074
|
||||
[views]: https://docs.rs/io-lifetimes/*/io_lifetimes/views/index.html
|
||||
|
||||
## Prior Art
|
||||
|
||||
@@ -2,6 +2,11 @@ use std::env::var;
|
||||
use std::io::Write;
|
||||
|
||||
fn main() {
|
||||
// I/O safety is stabilized in Rust 1.63.
|
||||
if has_io_safety() {
|
||||
use_feature("io_lifetimes_use_std")
|
||||
}
|
||||
|
||||
// Niche optimizations for `Borrowed*` and `Owned*` depend on `rustc_attrs`
|
||||
// which, outside of `std`, are only available on nightly.
|
||||
use_feature_or_nothing("rustc_attrs");
|
||||
@@ -65,3 +70,36 @@ fn has_panic_in_const_fn() -> bool {
|
||||
|
||||
child.wait().unwrap().success()
|
||||
}
|
||||
|
||||
/// Test whether the rustc at `var("RUSTC")` supports the I/O safety feature.
|
||||
fn has_io_safety() -> bool {
|
||||
let out_dir = var("OUT_DIR").unwrap();
|
||||
let rustc = var("RUSTC").unwrap();
|
||||
|
||||
let mut child = std::process::Command::new(rustc)
|
||||
.arg("--crate-type=rlib") // Don't require `main`.
|
||||
.arg("--emit=metadata") // Do as little as possible but still parse.
|
||||
.arg("--out-dir")
|
||||
.arg(out_dir) // Put the output somewhere inconsequential.
|
||||
.arg("-") // Read from stdin.
|
||||
.stdin(std::process::Stdio::piped()) // Stdin is a pipe.
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
writeln!(
|
||||
child.stdin.take().unwrap(),
|
||||
"\
|
||||
#[cfg(unix)]\n\
|
||||
use std::os::unix::io::OwnedFd as Owned;\n\
|
||||
#[cfg(target_os = \"wasi\")]\n\
|
||||
use std::os::wasi::io::OwnedFd as Owned;\n\
|
||||
#[cfg(windows)]\n\
|
||||
use std::os::windows::io::OwnedHandle as Owned;\n\
|
||||
\n\
|
||||
pub type Success = Owned;\n\
|
||||
"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
child.wait().unwrap().success()
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
//! implementing `IntoFilelike` and `FromSocketlike` to types implementing
|
||||
//! `FromFilelike` and `IntoSocketlike`, respectively.
|
||||
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
use io_lifetimes::FromFilelike;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read};
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
//! The following uses the POSIX-ish `Fd` types; similar considerations
|
||||
//! apply to the Windows and portable types.
|
||||
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
#[cfg(all(feature = "close", not(windows)))]
|
||||
use io_lifetimes::{AsFd, BorrowedFd, IntoFd, OwnedFd};
|
||||
use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
|
||||
|
||||
/// The simplest way to accept a borrowed I/O resource is to simply use a
|
||||
/// `BorrwedFd` as an argument. This doesn't require the function to have any
|
||||
@@ -53,14 +51,14 @@ fn consume_fd_a(fd: OwnedFd) {
|
||||
/// has the advantage of allowing users to pass in any type implementing
|
||||
/// `IntoFd` directly.
|
||||
#[cfg(all(feature = "close", not(windows)))]
|
||||
fn consume_fd_b<Fd: IntoFd>(fd: Fd) {
|
||||
let _ = fd.into_fd();
|
||||
fn consume_fd_b<Fd: Into<OwnedFd>>(fd: Fd) {
|
||||
let _: OwnedFd = fd.into();
|
||||
}
|
||||
|
||||
/// Another way to do this is to use an `impl IntoFd` parameter.
|
||||
#[cfg(all(feature = "close", not(windows)))]
|
||||
fn consume_fd_c(fd: impl IntoFd) {
|
||||
let _ = fd.into_fd();
|
||||
fn consume_fd_c(fd: impl Into<OwnedFd>) {
|
||||
let _: OwnedFd = fd.into();
|
||||
}
|
||||
|
||||
/// Now let's see how the APIs look for users.
|
||||
@@ -87,13 +85,13 @@ fn main() {
|
||||
let b = std::fs::File::open("Cargo.toml").unwrap();
|
||||
let c = std::fs::File::open("Cargo.toml").unwrap();
|
||||
|
||||
// The simple option requires an `.into_fd()` at the callsite.
|
||||
consume_fd_a(a.into_fd());
|
||||
// The simple option requires an `.into()` at the callsite.
|
||||
consume_fd_a(a.into());
|
||||
|
||||
// Another option can take any `IntoFd` type directly.
|
||||
// Another option can take any `Into<OwnedFd>` type directly.
|
||||
consume_fd_b(b);
|
||||
|
||||
// The other option can take any `IntoFd` type directly.
|
||||
// The other option can take any `Into<OwnedFd>` type directly.
|
||||
consume_fd_c(c);
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -2,7 +2,6 @@
|
||||
//! the io-lifetimes API.
|
||||
|
||||
#![cfg_attr(not(rustc_attrs), allow(unused_imports))]
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
#[cfg(feature = "close")]
|
||||
use io_lifetimes::example_ffi::*;
|
||||
@@ -13,7 +12,7 @@ use std::{
|
||||
};
|
||||
|
||||
#[cfg(all(unix, feature = "close"))]
|
||||
use io_lifetimes::{AsFd, FromFd, OwnedFd};
|
||||
use io_lifetimes::{AsFd, OwnedFd};
|
||||
|
||||
#[cfg(windows)]
|
||||
use io_lifetimes::{AsHandle, FromHandle, OwnedHandle};
|
||||
@@ -40,7 +39,7 @@ fn main() -> io::Result<()> {
|
||||
};
|
||||
|
||||
// Convert into a `File`. No `unsafe` here!
|
||||
let mut file = File::from_fd(fd);
|
||||
let mut file = File::from(fd);
|
||||
writeln!(&mut file, "greetings, y'all")?;
|
||||
|
||||
// We can borrow a `BorrowedFd` from a `File`.
|
||||
@@ -95,7 +94,7 @@ fn main() -> io::Result<()> {
|
||||
};
|
||||
|
||||
// Convert into a `File`. No `unsafe` here!
|
||||
let mut file = File::from_handle(handle);
|
||||
let mut file = File::from(handle);
|
||||
writeln!(&mut file, "greetings, y'all")?;
|
||||
|
||||
// We can borrow a `BorrowedHandle` from a `File`.
|
||||
|
||||
+20
-10
@@ -1,12 +1,22 @@
|
||||
//! A simple example implementing the main traits for a type.
|
||||
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(any(feature = "close", not(io_lifetimes_use_std)))]
|
||||
use io_lifetimes::FromFd;
|
||||
#[cfg(windows)]
|
||||
#[cfg(any(feature = "close", not(io_lifetimes_use_std)))]
|
||||
use io_lifetimes::FromHandle;
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
use io_lifetimes::IntoFd;
|
||||
#[cfg(windows)]
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
use io_lifetimes::IntoHandle;
|
||||
use io_lifetimes::OwnedFilelike;
|
||||
#[cfg(not(windows))]
|
||||
use io_lifetimes::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd};
|
||||
use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
|
||||
#[cfg(windows)]
|
||||
use io_lifetimes::{AsHandle, BorrowedHandle, FromHandle, IntoHandle, OwnedHandle};
|
||||
use io_lifetimes::{AsHandle, BorrowedHandle, OwnedHandle};
|
||||
|
||||
/// A wrapper around a file descriptor.
|
||||
///
|
||||
@@ -33,6 +43,7 @@ impl AsFd for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(not(windows))]
|
||||
impl IntoFd for Thing {
|
||||
#[inline]
|
||||
@@ -41,7 +52,6 @@ impl IntoFd for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(not(windows))]
|
||||
impl From<Thing> for OwnedFd {
|
||||
#[inline]
|
||||
@@ -50,6 +60,7 @@ impl From<Thing> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(not(windows))]
|
||||
impl FromFd for Thing {
|
||||
#[inline]
|
||||
@@ -58,7 +69,6 @@ impl FromFd for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(not(windows))]
|
||||
impl From<OwnedFd> for Thing {
|
||||
#[inline]
|
||||
@@ -75,6 +85,7 @@ impl AsHandle for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(windows)]
|
||||
impl IntoHandle for Thing {
|
||||
#[inline]
|
||||
@@ -83,7 +94,6 @@ impl IntoHandle for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(windows)]
|
||||
impl From<Thing> for OwnedHandle {
|
||||
#[inline]
|
||||
@@ -92,6 +102,7 @@ impl From<Thing> for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(windows)]
|
||||
impl FromHandle for Thing {
|
||||
#[inline]
|
||||
@@ -100,7 +111,6 @@ impl FromHandle for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
#[cfg(windows)]
|
||||
impl From<OwnedHandle> for Thing {
|
||||
#[inline]
|
||||
@@ -119,7 +129,7 @@ fn main() {
|
||||
let file = std::fs::File::open("Cargo.toml").unwrap();
|
||||
let thing = Thing::from_into_fd(file);
|
||||
let _ = thing.as_fd();
|
||||
let _ = thing.into_fd();
|
||||
let _: OwnedFd = thing.into();
|
||||
}
|
||||
|
||||
// Minimally exercise `Thing`'s Windows API.
|
||||
@@ -128,7 +138,7 @@ fn main() {
|
||||
let file = std::fs::File::open("Cargo.toml").unwrap();
|
||||
let thing = Thing::from_into_handle(file);
|
||||
let _ = thing.as_handle();
|
||||
let _ = thing.into_handle();
|
||||
let _: OwnedHandle = thing.into();
|
||||
}
|
||||
|
||||
// Implementing the above traits makes the blanket impls for the portable
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
//! io-lifetimes provides safe, convenient, and portable ways to temporarily
|
||||
//! view an I/O resource as a `File`, `Socket`, or other types.
|
||||
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
use io_lifetimes::AsFilelike;
|
||||
use std::fs::File;
|
||||
use std::io::{self, stdout};
|
||||
|
||||
+8
-1
@@ -30,7 +30,6 @@
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(rustc_attrs, feature(rustc_attrs))]
|
||||
#![cfg_attr(all(io_lifetimes_use_std, target_os = "wasi"), feature(wasi_ext))]
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
mod portability;
|
||||
mod traits;
|
||||
@@ -48,8 +47,10 @@ pub use traits::AsFd;
|
||||
#[cfg(windows)]
|
||||
pub use traits::{AsHandle, AsSocket};
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
#[allow(deprecated)]
|
||||
pub use traits::{FromFd, IntoFd};
|
||||
#[cfg(windows)]
|
||||
#[allow(deprecated)]
|
||||
pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket};
|
||||
|
||||
#[cfg(not(io_lifetimes_use_std))]
|
||||
@@ -88,6 +89,7 @@ pub use std::os::windows::io::{
|
||||
// `From`/`Into`,
|
||||
#[cfg(io_lifetimes_use_std)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
#[allow(deprecated)]
|
||||
impl<T: From<OwnedFd>> FromFd for T {
|
||||
#[inline]
|
||||
fn from_fd(owned_fd: OwnedFd) -> Self {
|
||||
@@ -96,6 +98,7 @@ impl<T: From<OwnedFd>> FromFd for T {
|
||||
}
|
||||
#[cfg(io_lifetimes_use_std)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
#[allow(deprecated)]
|
||||
impl<T> IntoFd for T
|
||||
where
|
||||
OwnedFd: From<T>,
|
||||
@@ -108,6 +111,7 @@ where
|
||||
|
||||
#[cfg(io_lifetimes_use_std)]
|
||||
#[cfg(windows)]
|
||||
#[allow(deprecated)]
|
||||
impl<T: From<OwnedHandle>> FromHandle for T {
|
||||
#[inline]
|
||||
fn from_handle(owned_handle: OwnedHandle) -> Self {
|
||||
@@ -116,6 +120,7 @@ impl<T: From<OwnedHandle>> FromHandle for T {
|
||||
}
|
||||
#[cfg(io_lifetimes_use_std)]
|
||||
#[cfg(windows)]
|
||||
#[allow(deprecated)]
|
||||
impl<T> IntoHandle for T
|
||||
where
|
||||
OwnedHandle: From<T>,
|
||||
@@ -128,6 +133,7 @@ where
|
||||
|
||||
#[cfg(io_lifetimes_use_std)]
|
||||
#[cfg(windows)]
|
||||
#[allow(deprecated)]
|
||||
impl<T: From<OwnedSocket>> FromSocket for T {
|
||||
#[inline]
|
||||
fn from_socket(owned_socket: OwnedSocket) -> Self {
|
||||
@@ -136,6 +142,7 @@ impl<T: From<OwnedSocket>> FromSocket for T {
|
||||
}
|
||||
#[cfg(io_lifetimes_use_std)]
|
||||
#[cfg(windows)]
|
||||
#[allow(deprecated)]
|
||||
impl<T> IntoSocket for T
|
||||
where
|
||||
OwnedSocket: From<T>,
|
||||
|
||||
+48
-45
@@ -6,12 +6,9 @@
|
||||
|
||||
use crate::views::{FilelikeView, FilelikeViewType, SocketlikeView, SocketlikeViewType};
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
use crate::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd};
|
||||
use crate::{AsFd, BorrowedFd, OwnedFd};
|
||||
#[cfg(windows)]
|
||||
use crate::{
|
||||
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, FromHandle, FromSocket, IntoHandle,
|
||||
IntoSocket, OwnedHandle, OwnedSocket,
|
||||
};
|
||||
use crate::{AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, OwnedHandle, OwnedSocket};
|
||||
|
||||
/// A reference to a filelike object.
|
||||
///
|
||||
@@ -104,6 +101,8 @@ pub trait AsFilelike: AsFd {
|
||||
/// ```
|
||||
///
|
||||
/// [`File`]: std::fs::File
|
||||
/// [`Read`]: std::io::Read
|
||||
/// [`Write`]: std::io::Write
|
||||
fn as_filelike_view<Target: FilelikeViewType>(&self) -> FilelikeView<'_, Target>;
|
||||
}
|
||||
|
||||
@@ -155,6 +154,8 @@ pub trait AsFilelike: AsHandle {
|
||||
/// ```
|
||||
///
|
||||
/// [`File`]: std::fs::File
|
||||
/// [`Read`]: std::io::Read
|
||||
/// [`Write`]: std::io::Write
|
||||
fn as_filelike_view<Target: FilelikeViewType>(&self) -> FilelikeView<'_, Target>;
|
||||
}
|
||||
|
||||
@@ -195,6 +196,8 @@ pub trait AsSocketlike: AsFd {
|
||||
/// ```
|
||||
///
|
||||
/// [`TcpStream`]: std::net::TcpStream
|
||||
/// [`Read`]: std::io::Read
|
||||
/// [`Write`]: std::io::Write
|
||||
fn as_socketlike_view<Target: SocketlikeViewType>(&self) -> SocketlikeView<'_, Target>;
|
||||
}
|
||||
|
||||
@@ -254,10 +257,10 @@ impl<T: AsSocket> AsSocketlike for T {
|
||||
/// A portable trait to express the ability to consume an object and acquire
|
||||
/// ownership of its filelike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like [`IntoFd`] and Windows'
|
||||
/// `IntoHandle`.
|
||||
/// This is a portability abstraction over Unix-like [`Into<OwnedFd>`] and Windows'
|
||||
/// `Into<OwnedHandle>`.
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
pub trait IntoFilelike: IntoFd {
|
||||
pub trait IntoFilelike: Into<OwnedFd> {
|
||||
/// Consumes this object, returning the underlying filelike object.
|
||||
///
|
||||
/// # Example
|
||||
@@ -275,58 +278,58 @@ pub trait IntoFilelike: IntoFd {
|
||||
}
|
||||
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
impl<T: IntoFd> IntoFilelike for T {
|
||||
impl<T: Into<OwnedFd>> IntoFilelike for T {
|
||||
#[inline]
|
||||
fn into_filelike(self) -> OwnedFilelike {
|
||||
self.into_fd()
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// A portable trait to express the ability to consume an object and acquire
|
||||
/// ownership of its filelike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like `IntoFd` and Windows'
|
||||
/// [`IntoHandle`].
|
||||
/// This is a portability abstraction over Unix-like `Into<OwnedFd>` and Windows'
|
||||
/// [`Into<OwnedHandle>`].
|
||||
#[cfg(windows)]
|
||||
pub trait IntoFilelike: IntoHandle {
|
||||
pub trait IntoFilelike: Into<OwnedHandle> {
|
||||
/// Consumes this object, returning the underlying filelike object.
|
||||
fn into_filelike(self) -> OwnedFilelike;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl<T: IntoHandle> IntoFilelike for T {
|
||||
impl<T: Into<OwnedHandle>> IntoFilelike for T {
|
||||
#[inline]
|
||||
fn into_filelike(self) -> OwnedFilelike {
|
||||
self.into_handle()
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// A portable trait to express the ability to consume an object and acquire
|
||||
/// ownership of its socketlike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like [`IntoFd`] and Windows'
|
||||
/// `IntoSocket`.
|
||||
/// This is a portability abstraction over Unix-like [`Into<OwnedFd>`] and Windows'
|
||||
/// `Into<OwnedSocket>`.
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
pub trait IntoSocketlike: IntoFd {
|
||||
pub trait IntoSocketlike: Into<OwnedFd> {
|
||||
/// Consumes this object, returning the underlying socketlike object.
|
||||
fn into_socketlike(self) -> OwnedSocketlike;
|
||||
}
|
||||
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
impl<T: IntoFd> IntoSocketlike for T {
|
||||
impl<T: Into<OwnedFd>> IntoSocketlike for T {
|
||||
#[inline]
|
||||
fn into_socketlike(self) -> OwnedSocketlike {
|
||||
self.into_fd()
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// A portable trait to express the ability to consume an object and acquire
|
||||
/// ownership of its socketlike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like `IntoFd` and Windows'
|
||||
/// [`IntoSocket`].
|
||||
/// This is a portability abstraction over Unix-like `Into<OwnedFd>` and Windows'
|
||||
/// [`Into<OwnedSocket>`].
|
||||
#[cfg(windows)]
|
||||
pub trait IntoSocketlike: IntoSocket {
|
||||
pub trait IntoSocketlike: Into<OwnedSocket> {
|
||||
/// Consumes this object, returning the underlying socketlike object.
|
||||
///
|
||||
/// # Example
|
||||
@@ -344,21 +347,21 @@ pub trait IntoSocketlike: IntoSocket {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl<T: IntoSocket> IntoSocketlike for T {
|
||||
impl<T: Into<OwnedSocket>> IntoSocketlike for T {
|
||||
#[inline]
|
||||
fn into_socketlike(self) -> OwnedSocketlike {
|
||||
self.into_socket()
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// A portable trait to express the ability to construct an object from a
|
||||
/// filelike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like [`FromFd`] and Windows'
|
||||
/// `FromHandle`. It also provides the `from_into_filelike` convenience
|
||||
/// This is a portability abstraction over Unix-like [`From<OwnedFd>`] and Windows'
|
||||
/// `From<OwnedHandle>`. It also provides the `from_into_filelike` convenience
|
||||
/// function providing simplified from+into conversions.
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
pub trait FromFilelike: FromFd {
|
||||
pub trait FromFilelike: From<OwnedFd> {
|
||||
/// Constructs a new instance of `Self` from the given filelike object.
|
||||
///
|
||||
/// # Example
|
||||
@@ -393,10 +396,10 @@ pub trait FromFilelike: FromFd {
|
||||
}
|
||||
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
impl<T: FromFd> FromFilelike for T {
|
||||
impl<T: From<OwnedFd>> FromFilelike for T {
|
||||
#[inline]
|
||||
fn from_filelike(owned: OwnedFilelike) -> Self {
|
||||
Self::from_fd(owned)
|
||||
Self::from(owned)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -408,11 +411,11 @@ impl<T: FromFd> FromFilelike for T {
|
||||
/// A portable trait to express the ability to construct an object from a
|
||||
/// filelike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like `FromFd` and Windows'
|
||||
/// [`FromHandle`]. It also provides the `from_into_filelike` convenience
|
||||
/// This is a portability abstraction over Unix-like `From<OwnedFd>` and Windows'
|
||||
/// [`From<OwnedHandle>`]. It also provides the `from_into_filelike` convenience
|
||||
/// function providing simplified from+into conversions.
|
||||
#[cfg(windows)]
|
||||
pub trait FromFilelike: FromHandle {
|
||||
pub trait FromFilelike: From<OwnedHandle> {
|
||||
/// Constructs a new instance of `Self` from the given filelike object.
|
||||
///
|
||||
/// # Example
|
||||
@@ -447,10 +450,10 @@ pub trait FromFilelike: FromHandle {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl<T: FromHandle> FromFilelike for T {
|
||||
impl<T: From<OwnedHandle>> FromFilelike for T {
|
||||
#[inline]
|
||||
fn from_filelike(owned: OwnedFilelike) -> Self {
|
||||
Self::from_handle(owned)
|
||||
Self::from(owned)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -462,11 +465,11 @@ impl<T: FromHandle> FromFilelike for T {
|
||||
/// A portable trait to express the ability to construct an object from a
|
||||
/// socketlike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like [`FromFd`] and Windows'
|
||||
/// `FromSocket`. It also provides the `from_into_socketlike` convenience
|
||||
/// This is a portability abstraction over Unix-like [`From<OwnedFd>`] and Windows'
|
||||
/// `From<OwnedSocketFrom<OwnedSocket> It also provides the `from_into_socketlike` convenience
|
||||
/// function providing simplified from+into conversions.
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
pub trait FromSocketlike: FromFd {
|
||||
pub trait FromSocketlike: From<OwnedFd> {
|
||||
/// Constructs a new instance of `Self` from the given socketlike object.
|
||||
fn from_socketlike(owned: OwnedSocketlike) -> Self;
|
||||
|
||||
@@ -476,10 +479,10 @@ pub trait FromSocketlike: FromFd {
|
||||
}
|
||||
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
impl<T: FromFd> FromSocketlike for T {
|
||||
impl<T: From<OwnedFd>> FromSocketlike for T {
|
||||
#[inline]
|
||||
fn from_socketlike(owned: OwnedSocketlike) -> Self {
|
||||
Self::from_fd(owned)
|
||||
Self::from(owned)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -491,11 +494,11 @@ impl<T: FromFd> FromSocketlike for T {
|
||||
/// A portable trait to express the ability to construct an object from a
|
||||
/// socketlike object.
|
||||
///
|
||||
/// This is a portability abstraction over Unix-like `FromFd` and Windows'
|
||||
/// [`FromSocket`]. It also provides the `from_into_socketlike` convenience
|
||||
/// This is a portability abstraction over Unix-like `From<OwnedFd>` and Windows'
|
||||
/// [`From<OwnedSocket>`]. It also provides the `from_into_socketlike` convenience
|
||||
/// function providing simplified from+into conversions.
|
||||
#[cfg(windows)]
|
||||
pub trait FromSocketlike: FromSocket {
|
||||
pub trait FromSocketlike: From<OwnedSocket> {
|
||||
/// Constructs a new instance of `Self` from the given socketlike object.
|
||||
fn from_socketlike(owned: OwnedSocketlike) -> Self;
|
||||
|
||||
@@ -505,10 +508,10 @@ pub trait FromSocketlike: FromSocket {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl<T: FromSocket> FromSocketlike for T {
|
||||
impl<T: From<OwnedSocket>> FromSocketlike for T {
|
||||
#[inline]
|
||||
fn from_socketlike(owned: OwnedSocketlike) -> Self {
|
||||
Self::from_socket(owned)
|
||||
Self::from(owned)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
+33
-17
@@ -22,7 +22,6 @@ pub trait AsFd {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{AsFd, BorrowedFd};
|
||||
@@ -43,7 +42,6 @@ pub trait AsHandle {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{AsHandle, BorrowedHandle};
|
||||
@@ -66,13 +64,16 @@ pub trait AsSocket {
|
||||
/// A trait to express the ability to consume an object and acquire ownership
|
||||
/// of its file descriptor.
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "`IntoFd` is replaced by `From<...> for OwnedFd` or `Into<OwnedFd>`"
|
||||
)]
|
||||
pub trait IntoFd {
|
||||
/// Consumes this object, returning the underlying file descriptor.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{IntoFd, OwnedFd};
|
||||
@@ -87,13 +88,16 @@ pub trait IntoFd {
|
||||
/// A trait to express the ability to consume an object and acquire ownership
|
||||
/// of its handle.
|
||||
#[cfg(windows)]
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "`IntoHandle` is replaced by `From<...> for OwnedHandle` or `Into<OwnedHandle>`"
|
||||
)]
|
||||
pub trait IntoHandle {
|
||||
/// Consumes this object, returning the underlying handle.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{IntoHandle, OwnedHandle};
|
||||
@@ -108,6 +112,10 @@ pub trait IntoHandle {
|
||||
/// A trait to express the ability to consume an object and acquire ownership
|
||||
/// of its socket.
|
||||
#[cfg(windows)]
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "`IntoSocket` is replaced by `From<...> for OwnedSocket` or `Into<OwnedSocket>`"
|
||||
)]
|
||||
pub trait IntoSocket {
|
||||
/// Consumes this object, returning the underlying socket.
|
||||
fn into_socket(self) -> OwnedSocket;
|
||||
@@ -122,7 +130,6 @@ pub trait FromFd {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{FromFd, IntoFd, OwnedFd};
|
||||
@@ -132,6 +139,10 @@ pub trait FromFd {
|
||||
/// let f = File::from_fd(owned_fd);
|
||||
/// # Ok::<(), io::Error>(())
|
||||
/// ```
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "`FromFd::from_fd` is replaced by `From<OwnedFd>::from`"
|
||||
)]
|
||||
fn from_fd(owned: OwnedFd) -> Self;
|
||||
|
||||
/// Constructs a new instance of `Self` from the given file descriptor
|
||||
@@ -140,7 +151,6 @@ pub trait FromFd {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{FromFd, IntoFd};
|
||||
@@ -150,11 +160,11 @@ pub trait FromFd {
|
||||
/// # Ok::<(), io::Error>(())
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from_into_fd<Owned: IntoFd>(into_owned: Owned) -> Self
|
||||
fn from_into_fd<Owned: Into<OwnedFd>>(into_owned: Owned) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
Self: Sized + From<OwnedFd>,
|
||||
{
|
||||
Self::from_fd(into_owned.into_fd())
|
||||
Self::from(into_owned.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +176,6 @@ pub trait FromHandle {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{FromHandle, IntoHandle, OwnedHandle};
|
||||
@@ -176,6 +185,10 @@ pub trait FromHandle {
|
||||
/// let f = File::from_handle(owned_handle);
|
||||
/// # Ok::<(), io::Error>(())
|
||||
/// ```
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "`FromHandle::from_handle` is replaced by `From<OwnedHandle>::from`"
|
||||
)]
|
||||
fn from_handle(owned: OwnedHandle) -> Self;
|
||||
|
||||
/// Constructs a new instance of `Self` from the given handle converted
|
||||
@@ -184,7 +197,6 @@ pub trait FromHandle {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use io_lifetimes::{FromHandle, IntoHandle};
|
||||
@@ -194,11 +206,11 @@ pub trait FromHandle {
|
||||
/// # Ok::<(), io::Error>(())
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from_into_handle<Owned: IntoHandle>(into_owned: Owned) -> Self
|
||||
fn from_into_handle<Owned: Into<OwnedHandle>>(into_owned: Owned) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
Self: Sized + From<OwnedHandle>,
|
||||
{
|
||||
Self::from_handle(into_owned.into_handle())
|
||||
Self::from(into_owned.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,16 +218,20 @@ pub trait FromHandle {
|
||||
#[cfg(windows)]
|
||||
pub trait FromSocket {
|
||||
/// Constructs a new instance of `Self` from the given socket.
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "`FromSocket::from_socket` is replaced by `From<OwnedSocket>::from`"
|
||||
)]
|
||||
fn from_socket(owned: OwnedSocket) -> Self;
|
||||
|
||||
/// Constructs a new instance of `Self` from the given socket converted
|
||||
/// from `into_owned`.
|
||||
#[inline]
|
||||
fn from_into_socket<Owned: IntoSocket>(into_owned: Owned) -> Self
|
||||
fn from_into_socket<Owned: Into<OwnedSocket>>(into_owned: Owned) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
Self: Sized + From<OwnedSocket>,
|
||||
{
|
||||
Self::from_socket(into_owned.into_socket())
|
||||
Self::from(into_owned.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
|
||||
#![cfg(feature = "close")]
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
use io_lifetimes::raw::{AsRawFilelike, AsRawSocketlike};
|
||||
use io_lifetimes::views::{FilelikeView, SocketlikeView};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#![cfg_attr(not(rustc_attrs), allow(unused_imports))]
|
||||
#![cfg(feature = "close")]
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
#[cfg(any(unix, windows))]
|
||||
use io_lifetimes::example_ffi::*;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#![cfg_attr(not(rustc_attrs), allow(unused_imports))]
|
||||
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
|
||||
#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
|
||||
|
||||
use std::mem::size_of;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user