pub struct Run { /* private fields */ }Expand description
The run of a command that the caller observes while it runs
The handle starts with the command and ends with the result of the run. It gives the output of the command to the caller as lines, in the order in which the lines arrive, and it collects the same capture that a run in one call collects. A caller that reads no line at all therefore still gets every byte that the command wrote.
The handle owns the command. A caller that drops the handle ends the
command with it, so a timeout, a select, and a scheduler that abandons a
run leave no process behind. The kill that ends such a command is
immediate, and a caller that wants the command to end in good order calls
stop instead. A caller that waits for the end of the command in a
select keeps the handle with wait_for_end.
§Examples
use kawauso_process::Invocation;
let mut run = Invocation::new("cargo").arg("build").start()?;
while let Some(line) = run.next_line().await? {
println!("[{}] {line}", line.stream());
}
let execution = run.wait().await?.require_success()?;
println!("{}", execution.duration().as_secs());Implementations§
Source§impl Run
impl Run
Sourcepub fn id(&self) -> Option<ProcessId>
pub fn id(&self) -> Option<ProcessId>
Returns the identifier that the operating system gave the command
An application that reports which program it started, or that gives the command to a tool of the platform, reads the identifier here. The handle records the value when the command starts, so the value is there for the whole life of the handle. A wait for the end of the command does not remove the value.
The operating system takes the identifier of a command that ended, and it can give the same identifier to another command. A caller that waited for the end therefore reads the identifier of the command that ran, and not the identifier of a command that runs.
The value is None when the operating system gave the command no
identifier.
Sourcepub fn invocation(&self) -> &Invocation
pub fn invocation(&self) -> &Invocation
Returns the command that runs
Sourcepub async fn next_line(&mut self) -> Result<Option<Line>, RunCommandError>
pub async fn next_line(&mut self) -> Result<Option<Line>, RunCommandError>
Returns the next line of the output of the command
The method waits until the command writes a line to one of its
streams, and it returns the lines in the order in which they arrive.
It returns None when the command closed both of its streams, which a
command does when it ends. A command that writes a last line without
the characters that end a line still reports that line.
Every line that the method returns stays in the capture of the result as well, so a caller that shows the output while the command runs and then reports the whole output reads both from the same run.
§Errors
Returns IncompleteRun when a stream of the command
cannot be read.
§Cancel safety
The method is cancel safe. A caller often waits for a line and for
another event, such as a timeout or another branch of a select. The
caller drops the future of the call when the other event occurs first,
and the call loses no output. The bytes that the call took stay with
the handle, and the call that follows reports the line that they
belong to.
§Examples
use kawauso_process::Invocation;
let mut run = Invocation::new("cargo").arg("test").start()?;
while let Some(line) = run.next_line().await? {
println!("{line}");
}Sourcepub async fn stop(self, grace: Duration) -> Result<Execution, RunCommandError>
pub async fn stop(self, grace: Duration) -> Result<Execution, RunCommandError>
Ends the command and reports the result of the run
The method asks the command to end, and it gives the command the time that the caller names. It kills a command that is still there when the time is over. A program that answers the request removes its lock file, writes what it has, and ends, which a kill gives it no time to do.
The request is SIGTERM on a Unix platform. A platform that has no
request of this kind kills the command at once, and the time then
passes unused. The request reaches the program that the crate
started, and not a group of processes, so a program that starts
programs of its own decides what happens to them.
The time measures the command, and not the streams of the command. A program that starts programs of its own gives them its streams. Such a program can end while a program that it started holds the streams open.
The method reads both streams while it waits, so a command that fills a pipe ends as well. It takes what the streams hold when the command ends. On a Unix platform, a program that holds a stream open therefore does not hold the call. On a platform that has no read of this kind, the call waits for the end of both streams.
The method reports what wait reports: the exit status, the
capture of both streams, and the time that the run took.
A caller that drops the handle instead of this call kills the command at once, with no request before it.
§Errors
Returns IncompleteRun when a stream of the command
cannot be read, or when the end of the command cannot be waited for.
§Panics
Panics when the Tokio runtime that drives the future has no timer. The method waits for the time that the caller names, and the timer of the runtime measures it.
§Examples
use std::time::Duration;
use kawauso_process::Invocation;
let run = Invocation::new("cargo").arg("build").start()?;
let execution = run.stop(Duration::from_secs(5)).await?;
println!("{}", execution.status());Sourcepub async fn wait(self) -> Result<Execution, RunCommandError>
pub async fn wait(self) -> Result<Execution, RunCommandError>
Waits for the end of the command and reports the result of the run
The method reads what the command still writes, waits for the end of the command, and reports what a run in one call reports: the exit status, the capture of both streams, and the time that the run took. The capture holds everything that the command wrote, whether or not the caller read a line.
A command that ends without success is no failure of this method. The
status travels in the result, and
require_success turns a status that is not a
success into an error.
§Errors
Returns IncompleteRun when a stream of the command
cannot be read, or when the end of the command cannot be waited for.
§Cancel safety
The method is not cancel safe. It takes the handle, so a caller that
drops the future of a call ends the command. The caller loses the
result of the run, and the capture of both streams with it. A caller
that waits for the end of the command, and for an event of its own,
calls wait_for_end. That method leaves the handle.
§Examples
use kawauso_process::Invocation;
let run = Invocation::new("cargo").arg("build").start()?;
let execution = run.wait().await?;
println!("{}", execution.status());Sourcepub async fn wait_for_end(&mut self) -> Result<(), RunCommandError>
pub async fn wait_for_end(&mut self) -> Result<(), RunCommandError>
Waits for the end of the command and leaves the handle with the caller
A caller often waits for the end of a command and for an event of its
own, such as a token that cancels the work. wait takes the
handle, and this caller needs it. The caller holds nothing when the
event comes first, and stop needs the handle. This method
reports the end of the command, and it leaves the handle. The caller
then asks for the result, or it stops a command that still runs.
The method reports no result of its own. The handle keeps everything
that a result needs, so wait reports the result after this
call. The wait that follows returns at once, because the command
ended.
The method reads both streams while it waits, so a command that fills a pipe ends as well. It waits for the command and not for the output of the command. A command that closed both of its streams can still run, and this method reports that end.
§Errors
Returns IncompleteRun when a stream of the command
cannot be read, or when the end of the command cannot be waited for.
§Cancel safety
The method is cancel safe. The caller drops the future of the call when the other event occurs first, and the command continues. The handle keeps the output that the call read, and the caller stops the command, takes the result, or waits again.
§Examples
use std::time::Duration;
use kawauso_process::Invocation;
let mut run = Invocation::new("cargo").arg("build").start()?;
let execution = tokio::select! {
ended = run.wait_for_end() => {
ended?;
run.wait().await?
}
() = cancelled() => run.stop(Duration::from_secs(5)).await?,
};
println!("{}", execution.status());