asimov_core/
env.rs

1// This is free and unencumbered software released into the public domain.
2
3pub const ASIMOV_HOME: &str = "ASIMOV_HOME";
4
5#[cfg(feature = "std")]
6const CONFIG_PATH: &str = ".config/asimov";
7
8/// Returns the home directory of the current user.
9#[cfg(feature = "std")]
10pub fn home_dir(
11    ambient_authority: cap_std::AmbientAuthority,
12) -> std::io::Result<cap_std::fs_utf8::Dir> {
13    use cap_std::fs_utf8::Dir;
14
15    let user_dirs = cap_directories::UserDirs::new().unwrap();
16    user_dirs.home_dir(ambient_authority).map(Dir::from_cap_std)
17}
18
19/// Returns the `ASIMOV_HOME` configuration directory.
20#[cfg(feature = "std")]
21pub fn config_dir(
22    ambient_authority: cap_std::AmbientAuthority,
23) -> std::io::Result<cap_std::fs_utf8::Dir> {
24    use cap_std::fs_utf8::Dir;
25    use std::{
26        env::VarError,
27        io::{Error, ErrorKind},
28    };
29
30    match std::env::var(ASIMOV_HOME) {
31        Err(VarError::NotUnicode(_)) => Err(Error::new(
32            ErrorKind::InvalidData,
33            "ASIMOV_HOME is not valid Unicode",
34        )),
35        Err(VarError::NotPresent) => home_dir(ambient_authority)
36            .and_then(|home_dir| {
37                home_dir.create_dir_all(CONFIG_PATH)?;
38                Ok(home_dir)
39            })
40            .and_then(|home_dir| home_dir.open_dir(CONFIG_PATH)),
41        Ok(path) if path.trim().is_empty() => {
42            Err(Error::new(ErrorKind::InvalidData, "ASIMOV_HOME is empty"))
43        }
44        Ok(path) => Dir::create_ambient_dir_all(&path, ambient_authority)
45            .and_then(|_| Dir::open_ambient_dir(&path, ambient_authority)),
46    }
47}