1use std::collections::HashMap;
2use std::env;
3use std::path::{Path, PathBuf};
4
5pub fn check_snap_home() -> (bool, Option<PathBuf>) {
7 if in_snap() {
8 (true, snap_real_home())
9 } else {
10 (false, None)
11 }
12}
13
14pub fn in_snap() -> bool {
16 snap().is_some()
17}
18
19pub fn snap() -> Option<String> {
24 if let Ok(snap) = env::var("SNAP") {
25 Some(snap)
26 } else {
27 None
28 }
29}
30
31pub fn snap_arch() -> Option<String> {
36 if let Ok(snap_arch) = env::var("SNAP_ARCH") {
37 Some(snap_arch)
38 } else {
39 None
40 }
41}
42
43pub fn snap_common() -> Option<PathBuf> {
49 if let Ok(snap_common) = env::var("SNAP_COMMON") {
50 Some(Path::new(snap_common.as_str()).to_path_buf())
51 } else {
52 None
53 }
54}
55
56pub fn snap_data() -> Option<PathBuf> {
62 if let Ok(snap_data) = env::var("SNAP_DATA") {
63 Some(Path::new(snap_data.as_str()).to_path_buf())
64 } else {
65 None
66 }
67}
68
69pub fn snap_instance_name() -> Option<String> {
74 if let Ok(snap_instance_name) = env::var("SNAP_INSTANCE_NAME") {
75 Some(snap_instance_name)
76 } else {
77 None
78 }
79}
80
81pub fn snap_instance_key() -> Option<String> {
86 if let Ok(snap_instance_key) = env::var("SNAP_INSTANCE_KEY") {
87 Some(snap_instance_key)
88 } else {
89 None
90 }
91}
92
93pub fn snap_library_path() -> Option<Vec<PathBuf>> {
99 if let Ok(snap_real_home) = env::var("SNAP_LIBRARY_PATH") {
100 let snap_lib_paths: Vec<PathBuf> = snap_real_home
101 .split(':')
102 .filter(|x| !x.is_empty())
103 .map(|x| Path::new(x).to_path_buf())
104 .collect();
105 Some(snap_lib_paths)
106 } else {
107 None
108 }
109}
110
111pub fn snap_name() -> Option<String> {
115 if let Ok(snap_name) = env::var("SNAP_NAME") {
116 Some(snap_name)
117 } else {
118 None
119 }
120}
121
122pub fn snap_real_home() -> Option<PathBuf> {
128 if let Ok(snap_real_home) = env::var("SNAP_REAL_HOME") {
129 Some(Path::new(snap_real_home.as_str()).to_path_buf())
130 } else {
131 None
132 }
133}
134
135pub fn snap_revision() -> Option<String> {
142 if let Ok(snap_revision) = env::var("SNAP_REVISION") {
143 Some(snap_revision)
144 } else {
145 None
146 }
147}
148
149pub fn snap_save_data() -> Option<PathBuf> {
157 if let Ok(snap_save_data) = env::var("SNAP_SAVE_DATA") {
158 Some(Path::new(snap_save_data.as_str()).to_path_buf())
159 } else {
160 None
161 }
162}
163
164pub fn snap_user_common() -> Option<PathBuf> {
170 if let Ok(snap_user_common) = env::var("SNAP_USER_COMMON") {
171 Some(Path::new(snap_user_common.as_str()).to_path_buf())
172 } else {
173 None
174 }
175}
176
177pub fn snap_user_data() -> Option<PathBuf> {
183 if let Ok(snap_user_data) = env::var("SNAP_USER_DATA") {
184 Some(Path::new(snap_user_data.as_str()).to_path_buf())
185 } else {
186 None
187 }
188}
189
190pub fn snap_version() -> Option<String> {
194 if let Ok(snap_version) = env::var("SNAP_VERSION") {
195 Some(snap_version)
196 } else {
197 None
198 }
199}
200
201pub fn snap_env() -> Option<HashMap<String, String>> {
203 let snap_map: HashMap<String, String> =
204 env::vars().filter(|(k, _)| k.starts_with("SNAP")).collect();
205 if snap_map.is_empty() {
206 None
207 } else {
208 Some(snap_map)
209 }
210}
211
212#[cfg(test)]
213mod tests {
214 use serial_test::serial;
215 use std::{env, path::Path};
216
217 fn setup() {
218 env::set_var("SNAP", "/snap/hello-world/27");
219 env::set_var("SNAP_ARCH", "armhf");
220 env::set_var("SNAP_COMMON", "/var/snap/hello-world/common");
221 env::set_var("SNAP_DATA", "/var/snap/hello-world/27");
222 env::set_var("SNAP_INSTANCE_NAME", "hello-world");
223 env::set_var("SNAP_INSTANCE_KEY", "foo");
224 env::set_var("SNAP_LIBRARY_PATH", "/var/lib/snapd/lib/gl:");
225 env::set_var("SNAP_NAME", "hello-world");
226 env::set_var("SNAP_REAL_HOME", "/home/user");
227 env::set_var("SNAP_REVISION", "27");
228 env::set_var("SNAP_SAVE_DATA", "/snap/hello-world/27/save");
229 env::set_var("SNAP_USER_COMMON", "/home/zyga/snap/hello-world/common");
230 env::set_var("SNAP_USER_DATA", "/home/zyga/snap/hello-world/27");
231 env::set_var("SNAP_VERSION", "v1.0.0");
232 }
233
234 fn unsetup() {
235 env::vars()
236 .filter(|(k, _)| k.starts_with("SNAP"))
237 .for_each(|(k, _)| env::remove_var(k));
238 }
239
240 #[test]
241 #[serial]
242 fn snap() {
243 setup();
244 let val = crate::snap();
245 assert!(val.is_some());
246 assert_eq!(val.unwrap(), "/snap/hello-world/27");
247 unsetup();
248 }
249
250 #[test]
251 #[serial]
252 fn in_snap() {
253 setup();
254 let val = crate::in_snap();
255 assert!(val);
256 unsetup();
257 }
258
259 #[test]
260 #[serial]
261 fn not_in_snap() {
262 let val = crate::in_snap();
263 assert!(!val);
264 }
265
266 #[test]
267 #[serial]
268 fn check_snap_home() {
269 setup();
270 let val = crate::check_snap_home();
271 assert!(val.0);
272 assert!(val.1.is_some());
273 assert_eq!(val.1.unwrap(), Path::new("/home/user").to_path_buf());
274 unsetup();
275 }
276
277 #[test]
278 #[serial]
279 fn not_check_snap_home() {
280 let val = crate::check_snap_home();
281 assert!(!val.0);
282 assert!(val.1.is_none());
283 }
284
285 #[test]
286 #[serial]
287 fn snap_arch() {
288 setup();
289 let val = crate::snap_arch();
290 assert!(val.is_some());
291 assert_eq!(val.unwrap(), "armhf");
292 unsetup();
293 }
294
295 #[test]
296 #[serial]
297 fn snap_data() {
298 setup();
299 let val = crate::snap_data();
300 assert!(val.is_some());
301 assert_eq!(
302 val.unwrap(),
303 Path::new("/var/snap/hello-world/27").to_path_buf()
304 );
305 unsetup();
306 }
307
308 #[test]
309 #[serial]
310 fn snap_instance_name() {
311 setup();
312 let val = crate::snap_instance_name();
313 assert!(val.is_some());
314 assert_eq!(val.unwrap(), "hello-world");
315 unsetup();
316 }
317
318 #[test]
319 #[serial]
320 fn snap_instance_key() {
321 setup();
322 let val = crate::snap_instance_key();
323 assert!(val.is_some());
324 assert_eq!(val.unwrap(), "foo");
325 unsetup();
326 }
327
328 #[test]
329 #[serial]
330 fn snap_library_path() {
331 setup();
332 let val = crate::snap_library_path();
333 assert!(val.is_some());
334 let val = val.unwrap();
335 assert_eq!(val.len(), 1);
336 assert_eq!(
337 val.first().unwrap().to_owned(),
338 Path::new("/var/lib/snapd/lib/gl").to_path_buf()
339 );
340 unsetup();
341 }
342
343 #[test]
344 #[serial]
345 fn snap_name() {
346 setup();
347 let val = crate::snap_name();
348 assert!(val.is_some());
349 assert_eq!(val.unwrap(), "hello-world");
350 unsetup();
351 }
352
353 #[test]
354 #[serial]
355 fn snap_real_home() {
356 setup();
357 let val = crate::snap_real_home();
358 assert!(val.is_some());
359 assert_eq!(val.unwrap(), Path::new("/home/user").to_path_buf());
360 unsetup();
361 }
362
363 #[test]
364 #[serial]
365 fn snap_revision() {
366 setup();
367 let val = crate::snap_revision();
368 assert!(val.is_some());
369 assert_eq!(val.unwrap(), "27");
370 unsetup();
371 }
372
373 #[test]
374 #[serial]
375 fn snap_save_data() {
376 setup();
377 let val = crate::snap_save_data();
378 assert!(val.is_some());
379 assert_eq!(
380 val.unwrap(),
381 Path::new("/snap/hello-world/27/save").to_path_buf()
382 );
383 unsetup();
384 }
385
386 #[test]
387 #[serial]
388 fn snap_user_common() {
389 setup();
390 let val = crate::snap_user_common();
391 assert!(val.is_some());
392 assert_eq!(
393 val.unwrap(),
394 Path::new("/home/zyga/snap/hello-world/common").to_path_buf()
395 );
396 unsetup();
397 }
398
399 #[test]
400 #[serial]
401 fn snap_user_data() {
402 setup();
403 let val = crate::snap_user_data();
404 assert!(val.is_some());
405 assert_eq!(
406 val.unwrap(),
407 Path::new("/home/zyga/snap/hello-world/27").to_path_buf()
408 );
409 unsetup();
410 }
411
412 #[test]
413 #[serial]
414 fn snap_version() {
415 setup();
416 let val = crate::snap_version();
417 assert!(val.is_some());
418 assert_eq!(val.unwrap(), "v1.0.0");
419 unsetup();
420 }
421
422 #[test]
423 #[serial]
424 fn snap_env() {
425 setup();
426 let val = crate::snap_env();
427 assert!(val.is_some());
428 if let Some(val) = val {
429 assert_eq!(val.len(), 14);
430 assert_eq!(val.get("SNAP").unwrap(), "/snap/hello-world/27");
431 assert_eq!(val.get("SNAP_ARCH").unwrap(), "armhf");
432 assert_eq!(
433 val.get("SNAP_COMMON").unwrap(),
434 "/var/snap/hello-world/common"
435 );
436 assert_eq!(val.get("SNAP_DATA").unwrap(), "/var/snap/hello-world/27");
437 assert_eq!(val.get("SNAP_INSTANCE_NAME").unwrap(), "hello-world");
438 assert_eq!(val.get("SNAP_INSTANCE_KEY").unwrap(), "foo");
439 assert_eq!(
440 val.get("SNAP_LIBRARY_PATH").unwrap(),
441 "/var/lib/snapd/lib/gl:"
442 );
443 assert_eq!(val.get("SNAP_NAME").unwrap(), "hello-world");
444 assert_eq!(val.get("SNAP_REAL_HOME").unwrap(), "/home/user");
445 assert_eq!(val.get("SNAP_REVISION").unwrap(), "27");
446 assert_eq!(
447 val.get("SNAP_SAVE_DATA").unwrap(),
448 "/snap/hello-world/27/save"
449 );
450 assert_eq!(
451 val.get("SNAP_USER_COMMON").unwrap(),
452 "/home/zyga/snap/hello-world/common"
453 );
454 assert_eq!(
455 val.get("SNAP_USER_DATA").unwrap(),
456 "/home/zyga/snap/hello-world/27"
457 );
458 assert_eq!(val.get("SNAP_VERSION").unwrap(), "v1.0.0");
459 }
460 unsetup();
461 }
462
463 #[test]
464 #[serial]
465 fn no_snap_env() {
466 unsetup();
467 let val = crate::snap_env();
468 assert!(val.is_none());
469 }
470}