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 env::var("SNAP").ok()
25}
26
27pub fn snap_arch() -> Option<String> {
32 env::var("SNAP_ARCH").ok()
33}
34
35pub fn snap_common() -> Option<PathBuf> {
41 if let Ok(snap_common) = env::var("SNAP_COMMON") {
42 Some(Path::new(snap_common.as_str()).to_path_buf())
43 } else {
44 None
45 }
46}
47
48pub fn snap_data() -> Option<PathBuf> {
54 if let Ok(snap_data) = env::var("SNAP_DATA") {
55 Some(Path::new(snap_data.as_str()).to_path_buf())
56 } else {
57 None
58 }
59}
60
61pub fn snap_instance_name() -> Option<String> {
66 env::var("SNAP_INSTANCE_NAME").ok()
67}
68
69pub fn snap_instance_key() -> Option<String> {
74 env::var("SNAP_INSTANCE_KEY").ok()
75}
76
77pub fn snap_library_path() -> Option<Vec<PathBuf>> {
83 if let Ok(snap_real_home) = env::var("SNAP_LIBRARY_PATH") {
84 let snap_lib_paths: Vec<PathBuf> = snap_real_home
85 .split(':')
86 .filter(|x| !x.is_empty())
87 .map(|x| Path::new(x).to_path_buf())
88 .collect();
89 Some(snap_lib_paths)
90 } else {
91 None
92 }
93}
94
95pub fn snap_name() -> Option<String> {
99 env::var("SNAP_NAME").ok()
100}
101
102pub fn snap_real_home() -> Option<PathBuf> {
108 if let Ok(snap_real_home) = env::var("SNAP_REAL_HOME") {
109 Some(Path::new(snap_real_home.as_str()).to_path_buf())
110 } else {
111 None
112 }
113}
114
115pub fn snap_revision() -> Option<String> {
122 env::var("SNAP_REVISION").ok()
123}
124
125pub fn snap_save_data() -> Option<PathBuf> {
133 if let Ok(snap_save_data) = env::var("SNAP_SAVE_DATA") {
134 Some(Path::new(snap_save_data.as_str()).to_path_buf())
135 } else {
136 None
137 }
138}
139
140pub fn snap_user_common() -> Option<PathBuf> {
146 if let Ok(snap_user_common) = env::var("SNAP_USER_COMMON") {
147 Some(Path::new(snap_user_common.as_str()).to_path_buf())
148 } else {
149 None
150 }
151}
152
153pub fn snap_user_data() -> Option<PathBuf> {
159 if let Ok(snap_user_data) = env::var("SNAP_USER_DATA") {
160 Some(Path::new(snap_user_data.as_str()).to_path_buf())
161 } else {
162 None
163 }
164}
165
166pub fn snap_version() -> Option<String> {
170 env::var("SNAP_VERSION").ok()
171}
172
173pub fn snap_env() -> Option<HashMap<String, String>> {
175 let snap_map: HashMap<String, String> =
176 env::vars().filter(|(k, _)| k.starts_with("SNAP")).collect();
177 if snap_map.is_empty() {
178 None
179 } else {
180 Some(snap_map)
181 }
182}
183
184#[cfg(test)]
185mod tests {
186 use serial_test::serial;
187 use std::{env, path::Path};
188
189 fn setup() {
190 env::set_var("SNAP", "/snap/hello-world/27");
191 env::set_var("SNAP_ARCH", "armhf");
192 env::set_var("SNAP_COMMON", "/var/snap/hello-world/common");
193 env::set_var("SNAP_DATA", "/var/snap/hello-world/27");
194 env::set_var("SNAP_INSTANCE_NAME", "hello-world");
195 env::set_var("SNAP_INSTANCE_KEY", "foo");
196 env::set_var("SNAP_LIBRARY_PATH", "/var/lib/snapd/lib/gl:");
197 env::set_var("SNAP_NAME", "hello-world");
198 env::set_var("SNAP_REAL_HOME", "/home/user");
199 env::set_var("SNAP_REVISION", "27");
200 env::set_var("SNAP_SAVE_DATA", "/snap/hello-world/27/save");
201 env::set_var("SNAP_USER_COMMON", "/home/zyga/snap/hello-world/common");
202 env::set_var("SNAP_USER_DATA", "/home/zyga/snap/hello-world/27");
203 env::set_var("SNAP_VERSION", "v1.0.0");
204 }
205
206 fn unsetup() {
207 env::vars()
208 .filter(|(k, _)| k.starts_with("SNAP"))
209 .for_each(|(k, _)| env::remove_var(k));
210 }
211
212 #[test]
213 #[serial]
214 fn snap() {
215 setup();
216 let val = crate::snap();
217 assert!(val.is_some());
218 assert_eq!(val.unwrap(), "/snap/hello-world/27");
219 unsetup();
220 }
221
222 #[test]
223 #[serial]
224 fn in_snap() {
225 setup();
226 let val = crate::in_snap();
227 assert!(val);
228 unsetup();
229 }
230
231 #[test]
232 #[serial]
233 fn not_in_snap() {
234 let val = crate::in_snap();
235 assert!(!val);
236 }
237
238 #[test]
239 #[serial]
240 fn check_snap_home() {
241 setup();
242 let val = crate::check_snap_home();
243 assert!(val.0);
244 assert!(val.1.is_some());
245 assert_eq!(val.1.unwrap(), Path::new("/home/user").to_path_buf());
246 unsetup();
247 }
248
249 #[test]
250 #[serial]
251 fn not_check_snap_home() {
252 let val = crate::check_snap_home();
253 assert!(!val.0);
254 assert!(val.1.is_none());
255 }
256
257 #[test]
258 #[serial]
259 fn snap_arch() {
260 setup();
261 let val = crate::snap_arch();
262 assert!(val.is_some());
263 assert_eq!(val.unwrap(), "armhf");
264 unsetup();
265 }
266
267 #[test]
268 #[serial]
269 fn snap_data() {
270 setup();
271 let val = crate::snap_data();
272 assert!(val.is_some());
273 assert_eq!(
274 val.unwrap(),
275 Path::new("/var/snap/hello-world/27").to_path_buf()
276 );
277 unsetup();
278 }
279
280 #[test]
281 #[serial]
282 fn snap_instance_name() {
283 setup();
284 let val = crate::snap_instance_name();
285 assert!(val.is_some());
286 assert_eq!(val.unwrap(), "hello-world");
287 unsetup();
288 }
289
290 #[test]
291 #[serial]
292 fn snap_instance_key() {
293 setup();
294 let val = crate::snap_instance_key();
295 assert!(val.is_some());
296 assert_eq!(val.unwrap(), "foo");
297 unsetup();
298 }
299
300 #[test]
301 #[serial]
302 fn snap_library_path() {
303 setup();
304 let val = crate::snap_library_path();
305 assert!(val.is_some());
306 let val = val.unwrap();
307 assert_eq!(val.len(), 1);
308 assert_eq!(
309 val.first().unwrap().to_owned(),
310 Path::new("/var/lib/snapd/lib/gl").to_path_buf()
311 );
312 unsetup();
313 }
314
315 #[test]
316 #[serial]
317 fn snap_name() {
318 setup();
319 let val = crate::snap_name();
320 assert!(val.is_some());
321 assert_eq!(val.unwrap(), "hello-world");
322 unsetup();
323 }
324
325 #[test]
326 #[serial]
327 fn snap_real_home() {
328 setup();
329 let val = crate::snap_real_home();
330 assert!(val.is_some());
331 assert_eq!(val.unwrap(), Path::new("/home/user").to_path_buf());
332 unsetup();
333 }
334
335 #[test]
336 #[serial]
337 fn snap_revision() {
338 setup();
339 let val = crate::snap_revision();
340 assert!(val.is_some());
341 assert_eq!(val.unwrap(), "27");
342 unsetup();
343 }
344
345 #[test]
346 #[serial]
347 fn snap_save_data() {
348 setup();
349 let val = crate::snap_save_data();
350 assert!(val.is_some());
351 assert_eq!(
352 val.unwrap(),
353 Path::new("/snap/hello-world/27/save").to_path_buf()
354 );
355 unsetup();
356 }
357
358 #[test]
359 #[serial]
360 fn snap_user_common() {
361 setup();
362 let val = crate::snap_user_common();
363 assert!(val.is_some());
364 assert_eq!(
365 val.unwrap(),
366 Path::new("/home/zyga/snap/hello-world/common").to_path_buf()
367 );
368 unsetup();
369 }
370
371 #[test]
372 #[serial]
373 fn snap_user_data() {
374 setup();
375 let val = crate::snap_user_data();
376 assert!(val.is_some());
377 assert_eq!(
378 val.unwrap(),
379 Path::new("/home/zyga/snap/hello-world/27").to_path_buf()
380 );
381 unsetup();
382 }
383
384 #[test]
385 #[serial]
386 fn snap_version() {
387 setup();
388 let val = crate::snap_version();
389 assert!(val.is_some());
390 assert_eq!(val.unwrap(), "v1.0.0");
391 unsetup();
392 }
393
394 #[test]
395 #[serial]
396 fn snap_env() {
397 setup();
398 let val = crate::snap_env();
399 assert!(val.is_some());
400 if let Some(val) = val {
401 assert_eq!(val.len(), 14);
402 assert_eq!(val.get("SNAP").unwrap(), "/snap/hello-world/27");
403 assert_eq!(val.get("SNAP_ARCH").unwrap(), "armhf");
404 assert_eq!(
405 val.get("SNAP_COMMON").unwrap(),
406 "/var/snap/hello-world/common"
407 );
408 assert_eq!(val.get("SNAP_DATA").unwrap(), "/var/snap/hello-world/27");
409 assert_eq!(val.get("SNAP_INSTANCE_NAME").unwrap(), "hello-world");
410 assert_eq!(val.get("SNAP_INSTANCE_KEY").unwrap(), "foo");
411 assert_eq!(
412 val.get("SNAP_LIBRARY_PATH").unwrap(),
413 "/var/lib/snapd/lib/gl:"
414 );
415 assert_eq!(val.get("SNAP_NAME").unwrap(), "hello-world");
416 assert_eq!(val.get("SNAP_REAL_HOME").unwrap(), "/home/user");
417 assert_eq!(val.get("SNAP_REVISION").unwrap(), "27");
418 assert_eq!(
419 val.get("SNAP_SAVE_DATA").unwrap(),
420 "/snap/hello-world/27/save"
421 );
422 assert_eq!(
423 val.get("SNAP_USER_COMMON").unwrap(),
424 "/home/zyga/snap/hello-world/common"
425 );
426 assert_eq!(
427 val.get("SNAP_USER_DATA").unwrap(),
428 "/home/zyga/snap/hello-world/27"
429 );
430 assert_eq!(val.get("SNAP_VERSION").unwrap(), "v1.0.0");
431 }
432 unsetup();
433 }
434
435 #[test]
436 #[serial]
437 fn no_snap_env() {
438 unsetup();
439 let val = crate::snap_env();
440 assert!(val.is_none());
441 }
442}