Last active
March 12, 2025 17:58
-
-
Save RandyMcMillan/04f5ee116ef1d5bb026afa8aaa53149b to your computer and use it in GitHub Desktop.
tokio_async_command
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Cargo.toml | |
// [package] | |
// name = "tokio_async_command" | |
// version = "0.1.0" | |
// edition = "2021" | |
// | |
// [dependencies] | |
// tokio = { version = "1.44.0", features = ["full"] } | |
use tokio::io::{AsyncBufReadExt, BufReader}; | |
use tokio::process::Command; | |
use tokio::spawn; | |
#[tokio::main] | |
async fn main() -> Result<(), Box<dyn std::error::Error>> { | |
let mut child = Command::new("ls") | |
.arg("-l") | |
.stdout(std::process::Stdio::piped()) | |
.stderr(std::process::Stdio::piped()) | |
.spawn()?; | |
let stdout = child.stdout.take().expect("stdout was not configured"); | |
let stderr = child.stderr.take().expect("stderr was not configured"); | |
let stdout_reader = BufReader::new(stdout); | |
let stderr_reader = BufReader::new(stderr); | |
let stdout_handle = spawn(async move { | |
let mut lines = stdout_reader.lines(); | |
while let Some(line) = lines.next_line().await.unwrap_or(Some("0".to_string())) { | |
println!("{}", line); | |
} | |
}); | |
let stderr_handle = spawn(async move { | |
let mut lines = stderr_reader.lines(); | |
while let Some(line) = lines.next_line().await.unwrap_or(Some("0".to_string())) { | |
eprintln!("stderr: {}", line); | |
} | |
}); | |
let _status = child.wait().await?; | |
stdout_handle.await?; | |
stderr_handle.await?; | |
//println!("Exited with status: {}", _status); | |
let option_handle = spawn(async move { | |
process_options(Some(10), Some("hello".to_string())); | |
}); | |
option_handle.await?; | |
let option_handle = spawn(async move { | |
process_options(Some(20), None); | |
}); | |
option_handle.await?; | |
let option_handle = spawn(async move { | |
process_options(None, Some("world".to_string())); | |
}); | |
option_handle.await?; | |
Ok(()) | |
} | |
#[allow(unused_assignments)] | |
fn process_options(mut opt1: Option<i32>, mut opt2: Option<String>) { | |
let mut o1 = opt1.clone(); | |
let mut o2 = opt2.clone(); | |
while o1.is_some() || o2.is_some() { | |
match (o1.take(), o2.take()) { | |
(Some(val1), Some(val2)) => { | |
//prints twice - once for each option | |
println!("Both Some: {}, {}", val1, val2); | |
// process both values | |
} | |
(Some(val1), None) => { | |
println!("Opt1 Some: {}", val1); | |
// process opt1 | |
} | |
(None, Some(val2)) => { | |
println!("Opt2 Some: {}", val2); | |
// process opt2 | |
} | |
(None, None) => { | |
//should not happen since we already checked is_some() above. | |
} | |
} | |
// o1 = opt1; | |
// o2 = opt2; | |
opt1 = None; | |
opt2 = None; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment