Skip to content

pimalaya/io-process

I/O Process Documentation Matrix Mastodon

I/O-free process client library written in Rust

This library provides an I/O-agnostic abstraction over process operations — spawning commands, waiting for exit status, and collecting output — based on three concepts:

Coroutine

A coroutine is an I/O-free, resumable and composable state machine. It emits I/O requests without performing any I/O itself, and receives I/O responses to make progress. A coroutine is terminated when it stops emitting I/O requests.

See available coroutines at ./src/coroutines.

Runtime

A runtime contains all the I/O logic. It is responsible for processing I/O requests and returning the corresponding I/O responses. A runtime targets a specific execution model (blocking std, async Tokio).

See available runtimes at ./src/runtimes.

Loop

The loop is the glue between coroutines and runtimes. It drives the coroutine forward by feeding each ProcessOutput back as the next argument, until the coroutine terminates.

Examples

Spawn a command and get its exit status (blocking)

use io_process::{
    command::Command,
    coroutines::spawn::{Spawn, SpawnResult},
    runtimes::std::handle,
};

let mut command = Command::new("ls");
command.arg("-al");
command.arg("/tmp");

let mut arg = None;
let mut spawn = Spawn::new(command);

let status = loop {
    match spawn.resume(arg.take()) {
        SpawnResult::Ok { status } => break status,
        SpawnResult::Io { input } => arg = Some(handle(input).unwrap()),
        SpawnResult::Err { err } => panic!("{err}"),
    }
};

Spawn a command and collect its output (async)

use io_process::{
    command::Command,
    coroutines::spawn_out::{SpawnOut, SpawnOutResult},
    runtimes::tokio::handle,
};

let mut command = Command::new("echo");
command.arg("hello");
command.arg("world");

let mut arg = None;
let mut spawn = SpawnOut::new(command);

let (status, stdout, stderr) = loop {
    match spawn.resume(arg.take()) {
        SpawnOutResult::Ok { status, stdout, stderr } => break (status, stdout, stderr),
        SpawnOutResult::Io { input } => arg = Some(handle(input).await.unwrap()),
        SpawnOutResult::Err { err } => panic!("{err}"),
    }
};

See complete examples at ./examples.

More examples

Have a look at projects built on top of this library:

  • Comodoro: CLI to manage timers
  • Ortie: CLI to manage OAuth access tokens

License

This project is licensed under either of:

at your option.

Social

Sponsoring

nlnet

Special thanks to the NLnet foundation and the European Commission that have been financially supporting the project for years:

If you appreciate the project, feel free to donate using one of the following providers:

GitHub Ko-fi Buy Me a Coffee Liberapay thanks.dev PayPal

About

Set of I/O-free Rust coroutines and runtimes to manage processes

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Security policy

Stars

Watchers

Forks

Contributors