1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

use aws_types::os_shim_internal;

/// An operating system, like Windows or Linux
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum Os {
    /// A Windows-based operating system
    Windows,
    /// Any Unix-based operating system
    Unix,
}

impl Os {
    /// Returns the current operating system
    pub fn real() -> Self {
        match std::env::consts::OS {
            "windows" => Os::Windows,
            _ => Os::Unix,
        }
    }
}

/// Resolve a home directory given a set of environment variables
pub fn home_dir(env_var: &os_shim_internal::Env, os: Os) -> Option<String> {
    if let Ok(home) = env_var.get("HOME") {
        tracing::debug!(src = "HOME", "loaded home directory");
        return Some(home);
    }

    if os == Os::Windows {
        if let Ok(home) = env_var.get("USERPROFILE") {
            tracing::debug!(src = "USERPROFILE", "loaded home directory");
            return Some(home);
        }

        let home_drive = env_var.get("HOMEDRIVE");
        let home_path = env_var.get("HOMEPATH");
        tracing::debug!(src = "HOMEDRIVE/HOMEPATH", "loaded home directory");
        if let (Ok(mut drive), Ok(path)) = (home_drive, home_path) {
            drive.push_str(&path);
            return Some(drive);
        }
    }
    None
}

#[cfg(test)]
mod test {
    use super::{home_dir, Os};
    use aws_types::os_shim_internal::Env;

    #[test]
    fn homedir_profile_only_windows() {
        // windows specific variables should only be considered when the platform is windows
        let env = Env::from_slice(&[("USERPROFILE", "C:\\Users\\name")]);
        assert_eq!(
            home_dir(&env, Os::Windows),
            Some("C:\\Users\\name".to_string())
        );
        assert_eq!(home_dir(&env, Os::Unix), None);
    }
}