1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 13:21:38 +03:00

filedescriptor: fix a silly typo, enhance docs

This commit is contained in:
Wez Furlong 2019-06-01 08:19:18 -07:00
parent d518c9b2c9
commit 2c8e36648b
5 changed files with 136 additions and 7 deletions

View File

@ -1,12 +1,13 @@
[package] [package]
name = "filedescriptor" name = "filedescriptor"
version = "0.1.1" version = "0.2.0"
authors = ["Wez Furlong"] authors = ["Wez Furlong"]
edition = "2018" edition = "2018"
repository = "https://github.com/wez/wzsh" repository = "https://github.com/wez/wzsh"
description = "More ergonomic wrappers around RawFd and RawHandle" description = "More ergonomic wrappers around RawFd and RawHandle"
license = "MIT" license = "MIT"
documentation = "https://docs.rs/filedescriptor" documentation = "https://docs.rs/filedescriptor"
readme = "README.md"
[dependencies] [dependencies]
failure = "0.1" failure = "0.1"

49
filedescriptor/README.md Normal file
View File

@ -0,0 +1,49 @@
The purpose of this crate is to make it a bit more ergonomic for portable
applications that need to work with the platform level `RawFd` and
`RawHandle` types.
Rather than conditionally using `RawFd` and `RawHandle`, the `FileDescriptor`
type can be used to manage ownership, duplicate, read and write.
## FileDescriptor
This is a bit of a contrived example, but demonstrates how to avoid
the conditional code that would otherwise be required to deal with
calling `as_raw_fd` and `as_raw_handle`:
```rust
use filedescriptor::{FileDescriptor, FromRawFileDescriptor};
use failure::Fallible;
use std::io::Write;
fn get_stdout() -> Fallible<FileDescriptor> {
let stdout = std::io::stdout();
let handle = stdout.lock();
FileDescriptor::dup(&handle)
}
fn print_something() -> Fallible<()> {
get_stdout()?.write(b"hello")?;
Ok(())
}
```
## Pipe
The `Pipe` type makes it more convenient to create a pipe and manage
the lifetime of both the read and write ends of that pipe.
```rust
use filedescriptor::Pipe;
use std::io::{Read,Write};
use failure::Error;
let mut pipe = Pipe::new()?;
pipe.write.write(b"hello")?;
drop(pipe.write);
let mut s = String::new();
pipe.read.read_to_string(&mut s)?;
assert_eq!(s, "hello");
# Ok::<(), Error>(())
```

View File

@ -1,10 +1,51 @@
//! The purpose of this crate is to make it a bit more ergonomic for portable //! The purpose of this crate is to make it a bit more ergonomic for portable
//! applications that need to work with the platform level `RawFd` and //! applications that need to work with the platform level `RawFd` and
//! `RawHandle` types. //! `RawHandle` types.
//!
//! Rather than conditionally using `RawFd` and `RawHandle`, the `FileDescriptor` //! Rather than conditionally using `RawFd` and `RawHandle`, the `FileDescriptor`
//! type can be used to manage ownership, duplicate, read and write. //! type can be used to manage ownership, duplicate, read and write.
//!
//! ## FileDescriptor
//!
//! This is a bit of a contrived example, but demonstrates how to avoid
//! the conditional code that would otherwise be required to deal with
//! calling `as_raw_fd` and `as_raw_handle`:
//!
//! ```
//! use filedescriptor::{FileDescriptor, FromRawFileDescriptor};
//! use failure::Fallible;
//! use std::io::Write;
//!
//! fn get_stdout() -> Fallible<FileDescriptor> {
//! let stdout = std::io::stdout();
//! let handle = stdout.lock();
//! FileDescriptor::dup(&handle)
//! }
//!
//! fn print_something() -> Fallible<()> {
//! get_stdout()?.write(b"hello")?;
//! Ok(())
//! }
//! ```
//!
//! ## Pipe
//! The `Pipe` type makes it more convenient to create a pipe and manage //! The `Pipe` type makes it more convenient to create a pipe and manage
//! the lifetime of both the read and write ends of that pipe. //! the lifetime of both the read and write ends of that pipe.
//!
//! ```
//! use filedescriptor::Pipe;
//! use std::io::{Read,Write};
//! use failure::Error;
//!
//! let mut pipe = Pipe::new()?;
//! pipe.write.write(b"hello")?;
//! drop(pipe.write);
//!
//! let mut s = String::new();
//! pipe.read.read_to_string(&mut s)?;
//! assert_eq!(s, "hello");
//! # Ok::<(), Error>(())
//! ```
use failure::Fallible; use failure::Fallible;
#[cfg(unix)] #[cfg(unix)]
mod unix; mod unix;
@ -32,11 +73,11 @@ pub trait IntoRawFileDescriptor {
/// `FromRawFileDescriptor` is a platform independent trait for creating /// `FromRawFileDescriptor` is a platform independent trait for creating
/// an instance from the underlying platform file descriptor type. /// an instance from the underlying platform file descriptor type.
/// Because the platform file descriptor type has no inherent ownership /// Because the platform file descriptor type has no inherent ownership
/// management, the `from_raw_file_descrptor` function is marked as unsafe /// management, the `from_raw_file_descriptor` function is marked as unsafe
/// to indicate that care must be taken by the caller to ensure that it /// to indicate that care must be taken by the caller to ensure that it
/// is used appropriately. /// is used appropriately.
pub trait FromRawFileDescriptor { pub trait FromRawFileDescriptor {
unsafe fn from_raw_file_descrptor(fd: RawFileDescriptor) -> Self; unsafe fn from_raw_file_descriptor(fd: RawFileDescriptor) -> Self;
} }
/// `OwnedHandle` allows managing the lifetime of the platform `RawFileDescriptor` /// `OwnedHandle` allows managing the lifetime of the platform `RawFileDescriptor`
@ -69,7 +110,7 @@ impl OwnedHandle {
} }
/// Attempt to duplicate the underlying handle from an object that is /// Attempt to duplicate the underlying handle from an object that is
/// representable as the systemm `RawFileDescriptor` type and return an /// representable as the system `RawFileDescriptor` type and return an
/// `OwnedHandle` wrapped around the duplicate. Since the duplication /// `OwnedHandle` wrapped around the duplicate. Since the duplication
/// requires kernel resources that may not be available, this is a /// requires kernel resources that may not be available, this is a
/// potentially fallible operation. /// potentially fallible operation.
@ -82,6 +123,27 @@ impl OwnedHandle {
/// `FileDescriptor` is a thin wrapper on top of the `OwnedHandle` type that /// `FileDescriptor` is a thin wrapper on top of the `OwnedHandle` type that
/// exposes the ability to Read and Write to the platform `RawFileDescriptor`. /// exposes the ability to Read and Write to the platform `RawFileDescriptor`.
///
/// This is a bit of a contrived example, but demonstrates how to avoid
/// the conditional code that would otherwise be required to deal with
/// calling `as_raw_fd` and `as_raw_handle`:
///
/// ```
/// use filedescriptor::{FileDescriptor, FromRawFileDescriptor};
/// use failure::Fallible;
/// use std::io::Write;
///
/// fn get_stdout() -> Fallible<FileDescriptor> {
/// let stdout = std::io::stdout();
/// let handle = stdout.lock();
/// FileDescriptor::dup(&handle)
/// }
///
/// fn print_something() -> Fallible<()> {
/// get_stdout()?.write(b"hello")?;
/// Ok(())
/// }
/// ```
#[derive(Debug)] #[derive(Debug)]
pub struct FileDescriptor { pub struct FileDescriptor {
handle: OwnedHandle, handle: OwnedHandle,
@ -97,7 +159,7 @@ impl FileDescriptor {
} }
/// Attempt to duplicate the underlying handle from an object that is /// Attempt to duplicate the underlying handle from an object that is
/// representable as the systemm `RawFileDescriptor` type and return a /// representable as the system `RawFileDescriptor` type and return a
/// `FileDescriptor` wrapped around the duplicate. Since the duplication /// `FileDescriptor` wrapped around the duplicate. Since the duplication
/// requires kernel resources that may not be available, this is a /// requires kernel resources that may not be available, this is a
/// potentially fallible operation. /// potentially fallible operation.
@ -128,7 +190,24 @@ impl FileDescriptor {
/// Represents the readable and writable ends of a pair of descriptors /// Represents the readable and writable ends of a pair of descriptors
/// connected via a kernel pipe. /// connected via a kernel pipe.
///
/// ```
/// use filedescriptor::Pipe;
/// use std::io::{Read,Write};
/// use failure::Error;
///
/// let mut pipe = Pipe::new()?;
/// pipe.write.write(b"hello")?;
/// drop(pipe.write);
///
/// let mut s = String::new();
/// pipe.read.read_to_string(&mut s)?;
/// assert_eq!(s, "hello");
/// # Ok::<(), Error>(())
/// ```
pub struct Pipe { pub struct Pipe {
/// The readable end of the pipe
pub read: FileDescriptor, pub read: FileDescriptor,
/// The writable end of the pipe
pub write: FileDescriptor, pub write: FileDescriptor,
} }

View File

@ -23,7 +23,7 @@ impl<T: IntoRawFd> IntoRawFileDescriptor for T {
} }
impl<T: FromRawFd> FromRawFileDescriptor for T { impl<T: FromRawFd> FromRawFileDescriptor for T {
unsafe fn from_raw_file_descrptor(fd: RawFileDescriptor) -> Self { unsafe fn from_raw_file_descriptor(fd: RawFileDescriptor) -> Self {
Self::from_raw_fd(fd) Self::from_raw_fd(fd)
} }
} }

View File

@ -31,7 +31,7 @@ impl<T: IntoRawHandle> IntoRawFileDescriptor for T {
} }
impl<T: FromRawHandle> FromRawFileDescriptor for T { impl<T: FromRawHandle> FromRawFileDescriptor for T {
unsafe fn from_raw_file_descrptor(handle: RawHandle) -> Self { unsafe fn from_raw_file_descriptor(handle: RawHandle) -> Self {
Self::from_raw_handle(handle) Self::from_raw_handle(handle)
} }
} }