InteractiveProcess

Struct InteractiveProcess 

Source
pub struct InteractiveProcess { /* private fields */ }
Expand description

Wraps a Child object in an interface for doing newline-dellimited string IO with a child process.

Calling send sends a string to the process’s stdin. A newline delimiter is automatically appended. If newline characters are present in the provided string, they will not be escaped.

Each newline-separated string sent by the child process over stdout results a call to the provided line_callback function. The line is wrapped in a std::io::Result; it will be in the Err state if the line is not valid UTF-8.

A callback may optionally be provided (via new_with_exit_callback) which is invoked when the child’s stdout stream is closed.

Implementations§

Source§

impl InteractiveProcess

Source

pub fn new<T>(command: &mut Command, line_callback: T) -> Result<Self>
where T: Fn(Result<String>) + Send + 'static,

Attempt to start a process for the provided Command, capturing the standard in and out streams for later use. The provided callback is called for every newline-terminated string written to stdout by the process.

Examples found in repository?
examples/bash.rs (lines 12-14)
10fn main() {
11    let mut cmd = Command::new("/usr/bin/bash");
12    let mut proc = InteractiveProcess::new(&mut cmd, |line| {
13        println!("Got: {}", line.unwrap());
14    })
15    .unwrap();
16
17    sleep(Duration::from_millis(10));
18
19    proc.send("echo 'Hi from bash. Running ls:'").unwrap();
20    proc.send("ls").unwrap();
21
22    sleep(Duration::from_millis(10));
23
24    proc.close();
25}
More examples
Hide additional examples
examples/echo_stream.rs (lines 6-8)
4fn main() {
5    let mut cmd = Command::new("examples/echo_stream.py");
6    let mut proc = InteractiveProcess::new(&mut cmd, |line| {
7        println!("Got: {}", line.unwrap());
8    })
9    .unwrap();
10
11    proc.send("data1").unwrap();
12    sleep(Duration::from_secs(1));
13    proc.send("data2").unwrap();
14    sleep(Duration::from_secs(1));
15    proc.send("data3").unwrap();
16
17    // If we don't sleep here, the process won't have time to reply
18    // before we kill it.
19    sleep(Duration::from_millis(1));
20
21    proc.close().kill().unwrap();
22}
Source

pub fn new_with_exit_callback<T, S>( command: &mut Command, line_callback: T, exit_callback: S, ) -> Result<Self>
where T: Fn(Result<String>) + Send + 'static, S: Fn() + Send + 'static,

Constructor with the same semantics as new, except that an additional no-argument closure is provided which is called when the client exits.

Examples found in repository?
examples/closing_stream.rs (lines 6-12)
4fn main() {
5    let mut cmd = Command::new("examples/closing_stream.py");
6    let proc = InteractiveProcess::new_with_exit_callback(
7        &mut cmd,
8        |line| {
9            println!("Got: {}", line.unwrap());
10        },
11        || println!("Child exited."),
12    )
13    .unwrap();
14
15    println!("{}", proc.wait().unwrap());
16}
Source

pub fn send(&mut self, data: &str) -> Result<()>

Send a string to the client process’s stdin stream. A newline will be appended to the string.

Examples found in repository?
examples/bash.rs (line 19)
10fn main() {
11    let mut cmd = Command::new("/usr/bin/bash");
12    let mut proc = InteractiveProcess::new(&mut cmd, |line| {
13        println!("Got: {}", line.unwrap());
14    })
15    .unwrap();
16
17    sleep(Duration::from_millis(10));
18
19    proc.send("echo 'Hi from bash. Running ls:'").unwrap();
20    proc.send("ls").unwrap();
21
22    sleep(Duration::from_millis(10));
23
24    proc.close();
25}
More examples
Hide additional examples
examples/echo_stream.rs (line 11)
4fn main() {
5    let mut cmd = Command::new("examples/echo_stream.py");
6    let mut proc = InteractiveProcess::new(&mut cmd, |line| {
7        println!("Got: {}", line.unwrap());
8    })
9    .unwrap();
10
11    proc.send("data1").unwrap();
12    sleep(Duration::from_secs(1));
13    proc.send("data2").unwrap();
14    sleep(Duration::from_secs(1));
15    proc.send("data3").unwrap();
16
17    // If we don't sleep here, the process won't have time to reply
18    // before we kill it.
19    sleep(Duration::from_millis(1));
20
21    proc.close().kill().unwrap();
22}
Source

pub fn send_unterminated(&mut self, data: &str) -> Result<()>

Send a string to the client process’s stdin stream, without appending a newline.

Source

pub fn close(self) -> Child

Consume this InteractiveProcess and return its child. This closes the process’s stdin stream, which usually kills the process. If it doesn’t, you can use the returned Child object to kill it:

proc = InteractiveProces::new(...);
proc.take().kill().unwrap();
Examples found in repository?
examples/bash.rs (line 24)
10fn main() {
11    let mut cmd = Command::new("/usr/bin/bash");
12    let mut proc = InteractiveProcess::new(&mut cmd, |line| {
13        println!("Got: {}", line.unwrap());
14    })
15    .unwrap();
16
17    sleep(Duration::from_millis(10));
18
19    proc.send("echo 'Hi from bash. Running ls:'").unwrap();
20    proc.send("ls").unwrap();
21
22    sleep(Duration::from_millis(10));
23
24    proc.close();
25}
More examples
Hide additional examples
examples/echo_stream.rs (line 21)
4fn main() {
5    let mut cmd = Command::new("examples/echo_stream.py");
6    let mut proc = InteractiveProcess::new(&mut cmd, |line| {
7        println!("Got: {}", line.unwrap());
8    })
9    .unwrap();
10
11    proc.send("data1").unwrap();
12    sleep(Duration::from_secs(1));
13    proc.send("data2").unwrap();
14    sleep(Duration::from_secs(1));
15    proc.send("data3").unwrap();
16
17    // If we don't sleep here, the process won't have time to reply
18    // before we kill it.
19    sleep(Duration::from_millis(1));
20
21    proc.close().kill().unwrap();
22}
Source

pub fn wait(self) -> Result<ExitStatus>

Block the current thread on the process exiting, and return the exit code when it does. This does not send a signal to kill the child, so it only makes sense when the child process is self-terminating.

Examples found in repository?
examples/closing_stream.rs (line 15)
4fn main() {
5    let mut cmd = Command::new("examples/closing_stream.py");
6    let proc = InteractiveProcess::new_with_exit_callback(
7        &mut cmd,
8        |line| {
9            println!("Got: {}", line.unwrap());
10        },
11        || println!("Child exited."),
12    )
13    .unwrap();
14
15    println!("{}", proc.wait().unwrap());
16}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.