use std::path::PathBuf;
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct EnvFile(Vec<PathBuf>);
impl EnvFile {
pub fn from_args(env_file: Vec<String>, no_env_file: bool) -> Self {
if no_env_file {
return Self::default();
}
if env_file.is_empty() {
return Self::default();
}
let mut paths = Vec::new();
for env_file in env_file {
let mut current = String::new();
let mut escape = false;
for c in env_file.chars() {
if escape {
current.push(c);
escape = false;
} else if c == '\\' {
escape = true;
} else if c.is_whitespace() {
if !current.is_empty() {
paths.push(PathBuf::from(current));
current = String::new();
}
} else {
current.push(c);
}
}
if !current.is_empty() {
paths.push(PathBuf::from(current));
}
}
Self(paths)
}
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &PathBuf> {
self.0.iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_args_default() {
let env_file = EnvFile::from_args(vec![], false);
assert_eq!(env_file, EnvFile::default());
}
#[test]
fn test_from_args_no_env_file() {
let env_file = EnvFile::from_args(vec!["path1 path2".to_string()], true);
assert_eq!(env_file, EnvFile::default());
}
#[test]
fn test_from_args_empty_string() {
let env_file = EnvFile::from_args(vec![String::new()], false);
assert_eq!(env_file, EnvFile::default());
}
#[test]
fn test_from_args_whitespace_only() {
let env_file = EnvFile::from_args(vec![" ".to_string()], false);
assert_eq!(env_file, EnvFile::default());
}
#[test]
fn test_from_args_single_path() {
let env_file = EnvFile::from_args(vec!["path1".to_string()], false);
assert_eq!(env_file.0, vec![PathBuf::from("path1")]);
}
#[test]
fn test_from_args_multiple_paths() {
let env_file = EnvFile::from_args(vec!["path1 path2 path3".to_string()], false);
assert_eq!(
env_file.0,
vec![
PathBuf::from("path1"),
PathBuf::from("path2"),
PathBuf::from("path3")
]
);
}
#[test]
fn test_from_args_escaped_spaces() {
let env_file = EnvFile::from_args(vec![r"path\ with\ spaces".to_string()], false);
assert_eq!(env_file.0, vec![PathBuf::from("path with spaces")]);
}
#[test]
fn test_from_args_mixed_escaped_and_normal() {
let env_file =
EnvFile::from_args(vec![r"path1 path\ with\ spaces path2".to_string()], false);
assert_eq!(
env_file.0,
vec![
PathBuf::from("path1"),
PathBuf::from("path with spaces"),
PathBuf::from("path2")
]
);
}
#[test]
fn test_from_args_escaped_backslash() {
let env_file = EnvFile::from_args(vec![r"path\\with\\backslashes".to_string()], false);
assert_eq!(env_file.0, vec![PathBuf::from(r"path\with\backslashes")]);
}
#[test]
fn test_iter() {
let env_file = EnvFile(vec![PathBuf::from("path1"), PathBuf::from("path2")]);
let paths: Vec<_> = env_file.iter().collect();
assert_eq!(
paths,
vec![&PathBuf::from("path1"), &PathBuf::from("path2")]
);
}
}