diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /vendor/io-lifetimes/examples/flexible-apis.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/io-lifetimes/examples/flexible-apis.rs')
-rw-r--r-- | vendor/io-lifetimes/examples/flexible-apis.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/vendor/io-lifetimes/examples/flexible-apis.rs b/vendor/io-lifetimes/examples/flexible-apis.rs new file mode 100644 index 000000000..8eb19a287 --- /dev/null +++ b/vendor/io-lifetimes/examples/flexible-apis.rs @@ -0,0 +1,108 @@ +//! io-lifetimes provides two different options for library authors +//! writing APIs which accept untyped I/O resources. +//! +//! 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}; + +/// 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 +/// type parameters. It also works in FFI signatures, as `BorrowedFd` and (on +/// Rust nightly) `Option<BorrowedFd>` are guaranteed to have the same layout +/// as `RawFd`. +/// +/// Callers with an `AsFd`-implementing type would call `.as_fd()` and pass +/// the result. +#[cfg(all(feature = "close", not(windows)))] +fn use_fd_a(fd: BorrowedFd<'_>) { + let _ = fd; +} + +/// Another way to do this is to use an `AsFd` type parameter. This is more +/// verbose at the function definition site, and entails monomorphization, but +/// it has the advantage of allowing users to pass in any type implementing +/// `AsFd` directly, without having to call `.as_fd()` themselves. +#[cfg(all(feature = "close", not(windows)))] +fn use_fd_b<Fd: AsFd>(fd: Fd) { + let _ = fd.as_fd(); +} + +/// Another way to do this is to use an `impl AsFd` parameter. +#[cfg(all(feature = "close", not(windows)))] +fn use_fd_c(fd: impl AsFd) { + let _ = fd.as_fd(); +} + +/// The simplest way to accept a consumed I/O resource is to simply use an +/// `OwnedFd` as an argument. Similar to `use_fd_a`, this doesn't require the +/// function to have any type parameters, and also works in FFI signatures. +/// +/// Callers with an `IntoFd`-implementing type would call `.into_fd()` and pass +/// the result. +#[cfg(all(feature = "close", not(windows)))] +fn consume_fd_a(fd: OwnedFd) { + let _ = fd; +} + +/// Another way to do this is to use an `IntoFd` type parameter. Similar to +/// `use_fd_b`, this is more verbose here and entails monomorphization, but it +/// 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(); +} + +/// 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(); +} + +/// Now let's see how the APIs look for users. +#[cfg(all(feature = "close", not(windows)))] +fn main() { + let f = std::fs::File::open("Cargo.toml").unwrap(); + + // The simple option requires an `.as_fd()` at the callsite. + use_fd_a(f.as_fd()); + + // Another option can take a reference to any owning type directly. + use_fd_b(&f); + + // Of course, users can still pass in `BorrowedFd` values if they want to. + use_fd_b(f.as_fd()); + + // The other option is `impl AsFd`. + use_fd_c(&f); + + // Users can still pass in `BorrowedFd` values if they want to here too. + use_fd_c(f.as_fd()); + + let a = std::fs::File::open("Cargo.toml").unwrap(); + 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()); + + // Another option can take any `IntoFd` type directly. + consume_fd_b(b); + + // The other option can take any `IntoFd` type directly. + consume_fd_c(c); +} + +#[cfg(windows)] +fn main() { + println!("This example uses non-Windows APIs."); +} + +#[cfg(all(not(feature = "close"), not(windows)))] +fn main() { + println!("This example requires the \"close\" feature."); +} |