From 3c94117b577667b6c34a23529a0aa18ac354404b Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 6 Mar 2021 02:34:09 -0500 Subject: docs --- src/command.rs | 26 ++++++++++++++++++++++++++ src/error.rs | 9 +++++++++ src/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/pty.rs | 5 +++++ 4 files changed, 87 insertions(+) diff --git a/src/command.rs b/src/command.rs index 6ba783c..ff8a7cf 100644 --- a/src/command.rs +++ b/src/command.rs @@ -10,10 +10,17 @@ mod std; #[cfg(feature = "backend-tokio")] mod tokio; +/// Adds methods to the existing `Command` struct. +/// +/// This trait is automatically implemented for a backend's `Command` struct +/// when that backend's feature is enabled. pub trait Command { type Child; type Pty; + /// Creates a new pty, associates the command's stdin/stdout/stderr with + /// that pty, and then calls `spawn`. This will override any previous + /// calls to `stdin`/`stdout`/`stderr`. fn spawn_pty( &mut self, size: Option<&crate::pty::Size>, @@ -75,6 +82,7 @@ where } } +/// Wrapper struct adding pty methods to the normal `Child` struct. pub struct Child { child: C, pty: P, @@ -84,14 +92,32 @@ impl Child where P: crate::pty::Pty, { + /// Returns a reference to the pty. + /// + /// The underlying pty instance is guaranteed to implement + /// [`AsRawFd`](::std::os::unix::io::AsRawFd), as well as the appropriate + /// `Read` and `Write` traits for the associated backend. pub fn pty(&self) -> &P::Pt { self.pty.pt() } + /// Returns a mutable reference to the pty. + /// + /// The underlying pty instance is guaranteed to implement + /// [`AsRawFd`](::std::os::unix::io::AsRawFd), as well as the appropriate + /// `Read` and `Write` traits for the associated backend. + /// + /// This method is primarily useful for the tokio backend, since tokio's + /// `AsyncRead` and `AsyncWrite` traits have methods which take mutable + /// references. pub fn pty_mut(&mut self) -> &mut P::Pt { self.pty.pt_mut() } + /// Causes the pty to change its size. + /// + /// This will additionally cause a `SIGWINCH` signal to be sent to the + /// running process. pub fn resize_pty(&self, size: &crate::pty::Size) -> Result<()> { self.pty.resize(size) } diff --git a/src/error.rs b/src/error.rs index effee47..f97ede5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,25 +1,34 @@ +/// Error type for this crate #[derive(thiserror::Error, Debug)] pub enum Error { + /// error making pty async #[error("error making pty async")] AsyncPty(#[source] std::io::Error), + /// error making pty async #[error("error making pty async")] AsyncPtyNix(#[source] nix::Error), + /// error creating pty #[error("error creating pty")] CreatePty(#[source] nix::Error), + /// error opening pts at \ #[error("error opening pts at {0}")] OpenPts(#[source] std::io::Error, std::path::PathBuf), + /// error setting terminal size #[error("error setting terminal size")] SetTermSize(#[source] nix::Error), + /// error spawning subprocess #[error("error spawning subprocess")] Spawn(#[source] std::io::Error), + /// error spawning subprocess #[error("error spawning subprocess")] SpawnNix(#[source] nix::Error), } +/// Convenience wrapper for `Result`s using [`Error`](Error) pub type Result = std::result::Result; diff --git a/src/lib.rs b/src/lib.rs index 7d282ef..80fdbc7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,50 @@ +//! This crate adds a helper method to +//! [`std::process::Command`](::std::process::Command) (and optionally its +//! equivalent in various async frameworks) to allocate a pty to spawn the +//! process into. This allows for manipulation of interactive programs. +//! +//! The basic functionality is provided by the [`Command`](Command) trait in +//! this crate: +//! +//! ```no_run +//! use pty_process::Command as _; +//! +//! let mut cmd = std::process::Command::new("nethack"); +//! let child = cmd.spawn_pty(Some(&pty_process::Size::new(24, 80))).unwrap(); +//! ``` +//! +//! The `child` instance returned by the call to +//! [`spawn_pty`](Command::spawn_pty) is a thin wrapper around the `Child` +//! struct associated with the `Command` module used. You can use it +//! identically to how you would use the normal +//! [`std::process::Child`](::std::process::Child) instance, but it also +//! provides additional methods for interacting with the pty: +//! +//! ```no_run +//! # use pty_process::Command as _; +//! # +//! # let mut cmd = std::process::Command::new("nethack"); +//! # let mut child = cmd +//! # .spawn_pty(Some(&pty_process::Size::new(24, 80))).unwrap(); +//! use std::io::Write as _; +//! +//! child.pty().write_all(b"foo\n").unwrap(); +//! child.resize_pty(&pty_process::Size::new(30, 100)).unwrap(); +//! let status = child.wait().unwrap(); +//! ``` +//! +//! The available implementations are gated by features: +//! * `backend-std`: Add an implementation for +//! [`std::process::Command`](::std::process::Command). Enabled by default. +//! * `backend-smol`: Add an implementation for +//! [`smol::process::Command`](::smol::process::Command). +//! * `backend-async-std`: Add an implementation for +//! [`async_std::process::Command`](::async_std::process::Command). +//! * `backend-tokio`: Add an implementation for +//! [`tokio::process::Command`](::tokio::process::Command). +//! +//! Any number of backends may be enabled, depending on your needs. + mod command; pub use command::{Child, Command}; mod error; diff --git a/src/pty.rs b/src/pty.rs index 03a6217..bf34d61 100644 --- a/src/pty.rs +++ b/src/pty.rs @@ -21,6 +21,7 @@ pub trait Pty { fn resize(&self, size: &super::Size) -> Result<()>; } +/// Represents the size of the pty. pub struct Size { row: u16, col: u16, @@ -29,6 +30,8 @@ pub struct Size { } impl Size { + /// Returns a [`Size`](Size) instance with the given number of rows and + /// columns. pub fn new(row: u16, col: u16) -> Self { Self { row, @@ -38,6 +41,8 @@ impl Size { } } + /// Returns a [`Size`](Size) instance with the given number of rows and + /// columns, as well as the given pixel dimensions. pub fn new_with_pixel( row: u16, col: u16, -- cgit v1.2.3-54-g00ecf