diff --git a/Cargo.toml b/Cargo.toml index 00aafbe..478ff0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ edition = "2021" name = "echo" path = "src/echo.rs" +[[bin]] +name = "printenv" +path = "src/printenv.rs" + [dependencies] aho-corasick = "1.1.3" clap = { version = "4.5.20", features = ["derive"] } diff --git a/README.md b/README.md index 2709884..b7cda10 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,5 @@ Implementation of some of the Unix command line utils Currently implemented: ``` -echo +echo, printenv ``` \ No newline at end of file diff --git a/src/printenv.rs b/src/printenv.rs new file mode 100644 index 0000000..d20736b --- /dev/null +++ b/src/printenv.rs @@ -0,0 +1,43 @@ +#![feature(iter_intersperse)] + +use std::io::Write; + +use clap::Parser; + +/// Utility command to output information +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// End each output line with NUL instead of newline + #[arg(short='0', long)] + null: bool, +} + +fn main() { + let args = Args::parse(); + + let mut list: Vec = vec![]; + for (k, v) in std::env::vars() { + list.push(format!("{k}={v}")); + } + + let mut data: String; + + if args.null { + data = list.join("\0"); + data.push('\0'); + } else { + data = list.join("\n"); + data.push('\n'); + } + + let mut out = std::io::stdout(); + + match out.write_all(data.as_bytes()) { + Err(e) => { + eprintln!("Failed to write to stdout: {e}"); + std::process::exit(1); + }, + Ok(()) => () + }; +} \ No newline at end of file diff --git a/tests/printenv.rs b/tests/printenv.rs new file mode 100644 index 0000000..23b4dee --- /dev/null +++ b/tests/printenv.rs @@ -0,0 +1,28 @@ +use assert_cmd::prelude::*; +use predicates::prelude::*; +use std::process::Command; + +#[test] +fn env_capture() -> Result<(), Box> { + std::env::set_var("TEST_ABC", "brrrr"); + let mut cmd = Command::cargo_bin("printenv")?; + + cmd.assert() + .success() + .stdout(predicate::str::contains("TEST_ABC=brrrr\n")); + + Ok(()) +} + +#[test] +fn null_replace() -> Result<(), Box> { + std::env::set_var("TEST_ABC", "brrrr"); + let mut cmd = Command::cargo_bin("printenv")?; + + cmd.arg("-0"); + cmd.assert() + .success() + .stdout(predicate::str::contains("TEST_ABC=brrrr\0")); + + Ok(()) +} \ No newline at end of file