uv_configuration/
env_file.rs1use std::path::PathBuf;
2
3#[derive(Default, Debug, Clone, PartialEq, Eq)]
5pub struct EnvFile(Vec<PathBuf>);
6
7impl EnvFile {
8 pub fn from_args(env_file: Vec<String>, no_env_file: bool) -> Self {
10 if no_env_file {
11 return Self::default();
12 }
13
14 if env_file.is_empty() {
15 return Self::default();
16 }
17
18 let mut paths = Vec::new();
19
20 for env_file in env_file {
22 let mut current = String::new();
23 let mut escape = false;
24 for c in env_file.chars() {
25 if escape {
26 current.push(c);
27 escape = false;
28 } else if c == '\\' {
29 escape = true;
30 } else if c.is_whitespace() {
31 if !current.is_empty() {
32 paths.push(PathBuf::from(current));
33 current = String::new();
34 }
35 } else {
36 current.push(c);
37 }
38 }
39 if !current.is_empty() {
40 paths.push(PathBuf::from(current));
41 }
42 }
43
44 Self(paths)
45 }
46
47 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &PathBuf> {
49 self.0.iter()
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_from_args_default() {
59 let env_file = EnvFile::from_args(vec![], false);
60 assert_eq!(env_file, EnvFile::default());
61 }
62
63 #[test]
64 fn test_from_args_no_env_file() {
65 let env_file = EnvFile::from_args(vec!["path1 path2".to_string()], true);
66 assert_eq!(env_file, EnvFile::default());
67 }
68
69 #[test]
70 fn test_from_args_empty_string() {
71 let env_file = EnvFile::from_args(vec![String::new()], false);
72 assert_eq!(env_file, EnvFile::default());
73 }
74
75 #[test]
76 fn test_from_args_whitespace_only() {
77 let env_file = EnvFile::from_args(vec![" ".to_string()], false);
78 assert_eq!(env_file, EnvFile::default());
79 }
80
81 #[test]
82 fn test_from_args_single_path() {
83 let env_file = EnvFile::from_args(vec!["path1".to_string()], false);
84 assert_eq!(env_file.0, vec![PathBuf::from("path1")]);
85 }
86
87 #[test]
88 fn test_from_args_multiple_paths() {
89 let env_file = EnvFile::from_args(vec!["path1 path2 path3".to_string()], false);
90 assert_eq!(
91 env_file.0,
92 vec![
93 PathBuf::from("path1"),
94 PathBuf::from("path2"),
95 PathBuf::from("path3")
96 ]
97 );
98 }
99
100 #[test]
101 fn test_from_args_escaped_spaces() {
102 let env_file = EnvFile::from_args(vec![r"path\ with\ spaces".to_string()], false);
103 assert_eq!(env_file.0, vec![PathBuf::from("path with spaces")]);
104 }
105
106 #[test]
107 fn test_from_args_mixed_escaped_and_normal() {
108 let env_file =
109 EnvFile::from_args(vec![r"path1 path\ with\ spaces path2".to_string()], false);
110 assert_eq!(
111 env_file.0,
112 vec![
113 PathBuf::from("path1"),
114 PathBuf::from("path with spaces"),
115 PathBuf::from("path2")
116 ]
117 );
118 }
119
120 #[test]
121 fn test_from_args_escaped_backslash() {
122 let env_file = EnvFile::from_args(vec![r"path\\with\\backslashes".to_string()], false);
123 assert_eq!(env_file.0, vec![PathBuf::from(r"path\with\backslashes")]);
124 }
125
126 #[test]
127 fn test_iter() {
128 let env_file = EnvFile(vec![PathBuf::from("path1"), PathBuf::from("path2")]);
129 let paths: Vec<_> = env_file.iter().collect();
130 assert_eq!(
131 paths,
132 vec![&PathBuf::from("path1"), &PathBuf::from("path2")]
133 );
134 }
135}