rustutils_printenv/
lib.rs

1use clap::Parser;
2use rustutils_runnable::Runnable;
3use std::env;
4use std::error::Error;
5use std::ffi::{OsStr, OsString};
6use std::io::Write;
7use std::os::unix::ffi::OsStrExt;
8
9/// Print the values of the specified environment variables.
10#[derive(Parser, Clone, Debug)]
11#[clap(author, version, about, long_about = None)]
12pub struct Printenv {
13    /// When printing the current environment, separate the variables with a NUL character.
14    #[clap(short = '0', long)]
15    null: bool,
16    /// When printing the current environment, output it as JSON.
17    #[clap(short, long, conflicts_with = "null")]
18    json: bool,
19    /// Environment variables to print.
20    variables: Vec<OsString>,
21}
22
23impl Printenv {
24    pub fn run(&self) -> Result<(), Box<dyn Error>> {
25        let separator = match self.null {
26            true => OsStr::new("\0"),
27            false => OsStr::new("\n"),
28        };
29        self.print_variables(separator)
30    }
31
32    pub fn print_variables(&self, separator: &OsStr) -> Result<(), Box<dyn Error>> {
33        let mut stdout = std::io::stdout();
34        for name in &self.variables {
35            let value =
36                env::var_os(name).ok_or_else(|| format!("Missing env variable {name:?}"))?;
37            stdout.write_all(value.as_bytes())?;
38            stdout.write_all(separator.as_bytes())?;
39        }
40        Ok(())
41    }
42}
43
44impl Runnable for Printenv {
45    fn run(&self) -> Result<(), Box<dyn Error>> {
46        self.run()?;
47        Ok(())
48    }
49}