task/
environment_variable.rs1use alloc::{ffi::CString, format, sync::Arc};
2use core::fmt::Debug;
3
4#[derive(Clone, Eq, PartialEq, Hash)]
5pub struct EnvironmentVariable(Arc<CString>, usize);
6
7impl Debug for EnvironmentVariable {
8 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9 formatter
10 .debug_struct("Environment_variable_type")
11 .field("Name", &self.get_name())
12 .field("Value", &self.get_value())
13 .finish()
14 }
15}
16
17impl EnvironmentVariable {
18 pub fn new(name: &str, value: &str) -> Self {
20 let environment_variable = CString::new(format!("{name}={value}")).unwrap();
21 Self(Arc::new(environment_variable), name.len())
22 }
23
24 pub fn get_name(&self) -> &str {
36 self.0.to_str().unwrap()[..self.1].trim_end_matches('\0')
37 }
38
39 pub fn get_value(&self) -> &str {
51 self.0.to_str().unwrap()[self.1 + 1..].trim_end_matches('\0')
52 }
53
54 pub fn get_raw(&self) -> &CString {
56 &self.0
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_environment_variable_creation() {
66 let env_var = EnvironmentVariable::new("PATH", "/usr/bin:/bin");
67
68 assert_eq!(env_var.get_name(), "PATH");
69 assert_eq!(env_var.get_value(), "/usr/bin:/bin");
70 }
71
72 #[test]
73 fn test_environment_variable_empty_name() {
74 let env_var = EnvironmentVariable::new("", "some_value");
75
76 assert_eq!(env_var.get_name(), "");
77 assert_eq!(env_var.get_value(), "some_value");
78 }
79
80 #[test]
81 fn test_environment_variable_empty_value() {
82 let env_var = EnvironmentVariable::new("EMPTY_VAR", "");
83
84 assert_eq!(env_var.get_name(), "EMPTY_VAR");
85 assert_eq!(env_var.get_value(), "");
86 }
87
88 #[test]
89 fn test_environment_variable_both_empty() {
90 let env_var = EnvironmentVariable::new("", "");
91
92 assert_eq!(env_var.get_name(), "");
93 assert_eq!(env_var.get_value(), "");
94 }
95
96 #[test]
97 fn test_environment_variable_special_characters() {
98 let name = "TEST_VAR";
99 let value = "value with spaces and !@#$%^&*()";
100 let env_var = EnvironmentVariable::new(name, value);
101
102 assert_eq!(env_var.get_name(), name);
103 assert_eq!(env_var.get_value(), value);
104 }
105
106 #[test]
107 fn test_environment_variable_equals_in_value() {
108 let name = "CONFIG";
109 let value = "key=value=another=part";
110 let env_var = EnvironmentVariable::new(name, value);
111
112 assert_eq!(env_var.get_name(), name);
113 assert_eq!(env_var.get_value(), value);
114 }
115
116 #[test]
117 fn test_environment_variable_unicode() {
118 let name = "UNICODE_VAR";
119 let value = "🦀 Rust is awesome! 䏿–‡æµ‹è¯•";
120 let env_var = EnvironmentVariable::new(name, value);
121
122 assert_eq!(env_var.get_name(), name);
123 assert_eq!(env_var.get_value(), value);
124 }
125
126 #[test]
127 fn test_environment_variable_clone() {
128 let env_var1 = EnvironmentVariable::new("HOME", "/home/user");
129 let env_var2 = env_var1.clone();
130
131 assert_eq!(env_var1.get_name(), env_var2.get_name());
132 assert_eq!(env_var1.get_value(), env_var2.get_value());
133 assert_eq!(env_var1, env_var2);
134 }
135
136 #[test]
137 fn test_environment_variable_equality() {
138 let env_var1 = EnvironmentVariable::new("USER", "alice");
139 let env_var2 = EnvironmentVariable::new("USER", "alice");
140 let env_var3 = EnvironmentVariable::new("USER", "bob");
141 let env_var4 = EnvironmentVariable::new("HOME", "alice");
142
143 assert_eq!(env_var1, env_var2);
144 assert_ne!(env_var1, env_var3);
145 assert_ne!(env_var1, env_var4);
146 }
147
148 #[test]
149 fn test_environment_variable_hash() {
150 use std::collections::HashMap;
151
152 let env_var1 = EnvironmentVariable::new("PATH", "/usr/bin");
153 let env_var2 = EnvironmentVariable::new("HOME", "/home/user");
154 let env_var3 = EnvironmentVariable::new("PATH", "/usr/bin"); let mut map = HashMap::new();
157 map.insert(env_var1.clone(), "first");
158 map.insert(env_var2.clone(), "second");
159
160 map.insert(env_var3.clone(), "third");
162
163 assert_eq!(map.len(), 2);
164 assert_eq!(map.get(&env_var1), Some(&"third")); assert_eq!(map.get(&env_var2), Some(&"second"));
166 assert_eq!(map.get(&env_var3), Some(&"third"));
167 }
168
169 #[test]
170 fn test_environment_variable_debug_format() {
171 let env_var = EnvironmentVariable::new("DEBUG_VAR", "debug_value");
172 let debug_string = format!("{env_var:?}");
173
174 assert!(debug_string.contains("Environment_variable_type"));
175 assert!(debug_string.contains("DEBUG_VAR"));
176 assert!(debug_string.contains("debug_value"));
177 }
178
179 #[test]
180 fn test_environment_variable_get_raw() {
181 let name = "RAW_TEST";
182 let value = "raw_value";
183 let env_var = EnvironmentVariable::new(name, value);
184 let raw_cstring = env_var.get_raw();
185
186 assert_eq!(raw_cstring.to_str().unwrap(), "RAW_TEST=raw_value");
187 }
188
189 #[test]
190 fn test_environment_variable_long_name_and_value() {
191 let long_name = "A".repeat(1000);
192 let long_value = "B".repeat(2000);
193 let env_var = EnvironmentVariable::new(&long_name, &long_value);
194
195 assert_eq!(env_var.get_name(), long_name);
196 assert_eq!(env_var.get_value(), long_value);
197 }
198
199 #[test]
200 fn test_environment_variable_single_character() {
201 let env_var = EnvironmentVariable::new("A", "B");
202
203 assert_eq!(env_var.get_name(), "A");
204 assert_eq!(env_var.get_value(), "B");
205 }
206
207 #[test]
208 fn test_environment_variable_newlines_and_tabs() {
209 let name = "MULTILINE";
210 let value = "line1\nline2\tvalue";
211 let env_var = EnvironmentVariable::new(name, value);
212
213 assert_eq!(env_var.get_name(), name);
214 assert_eq!(env_var.get_value(), value);
215 }
216
217 #[test]
218 fn test_environment_variable_arc_sharing() {
219 let env_var1 = EnvironmentVariable::new("SHARED", "value");
220 let env_var2 = env_var1.clone();
221
222 assert_eq!(Arc::as_ptr(&env_var1.0), Arc::as_ptr(&env_var2.0));
224
225 assert_eq!(env_var1.get_name(), env_var2.get_name());
227 assert_eq!(env_var1.get_value(), env_var2.get_value());
228 }
229}