blob: a1c8cffb83200f5b474c69ce60066eea70ff6f1a [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const DEBUG_ARG: &str = "--debug";
// Wrapper to allow faking of std::env.
pub trait EnvLike {
/// Returns an iterator over the program's arguments. Unlike `std::env::args``, this method
/// filters non-unicode arguments rather than panicking. It also omits the first item returned
/// by `std::env::args`` (the program name).
fn args(&self) -> impl Iterator<Item = String>;
/// Returns the value of the environment variable identified by `key`. This is a wrapper for
/// `std::env::var` and has the same behavior.
fn var(&self, key: &str) -> Result<String, std::env::VarError>;
// Determines if this `EnvLike` contains a '--debug' command line argument.
fn contains_debug_arg(&self) -> bool {
self.args().any(|a| a == DEBUG_ARG)
}
}
/// Implements `EnvLike` using `std::env`.
pub struct ActualEnv;
impl EnvLike for ActualEnv {
fn args(&self) -> impl Iterator<Item = String> {
std::env::args_os().skip(1).filter_map(|os_string| os_string.into_string().ok())
}
fn var(&self, key: &str) -> Result<String, std::env::VarError> {
std::env::var(key)
}
}
#[cfg(test)]
pub mod testutils {
use super::*;
use std::collections::HashMap;
/// Fake `EnvLike` for tests.
pub struct FakeEnv {
args: Vec<String>,
vars: HashMap<String, String>,
}
impl FakeEnv {
/// Creates a `FakeEnv` from a space-separated string of arguments and a space-separated
/// string of variable assignments.
pub fn new(args: &str, vars: &str) -> Self {
Self {
args: args.split_ascii_whitespace().map(|str| String::from(str)).collect(),
vars: make_hashmap(vars),
}
}
}
impl EnvLike for FakeEnv {
fn args(&self) -> impl Iterator<Item = String> {
self.args.clone().into_iter()
}
fn var(&self, key: &str) -> Result<String, std::env::VarError> {
self.vars.get(key).ok_or(std::env::VarError::NotPresent).cloned()
}
}
// Makes a hashmap of strings from a space-separated string of variable assignments.
fn make_hashmap(from: &str) -> HashMap<String, String> {
from.split_ascii_whitespace()
.map(|assignment| {
let (key, rest) = assignment.split_once("=").unwrap();
(String::from(key), String::from(rest))
})
.collect::<HashMap<String, String>>()
}
}