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
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
use lazy_static::lazy_static;
use std::{
    ffi::OsStr,
    io,
    path::{Path, PathBuf},
    sync::atomic::{AtomicBool, Ordering},
};

/// Efficiently appends two `Vec`s together
pub fn append_vecs<T>(x: Vec<T>, mut y: Vec<T>) -> Vec<T> {
    let mut res = x;
    res.append(&mut y);

    res
}

lazy_static! {
    static ref HOME_DIR: PathBuf = match dirs::home_dir() {
        Some(home_dir) => home_dir,
        None => {
            eprintln!("Error: couldn't find home directory");
            std::process::exit(1);
        },
    };
}

pub fn home_dir() -> &'static Path {
    HOME_DIR.as_path()
}

/// Tries to replace absolute paths of the home directory
/// with a tilde for readability. If that fails for any reason, just
/// return `path`.
pub fn home_to_tilde(path: &Path) -> PathBuf {
    let relative_path = match path.strip_prefix(home_dir()) {
        Ok(relative_path) => relative_path,
        // The home directory isn't a prefix of `path` - just return `path` unchanged
        Err(_) => return PathBuf::from(path),
    };

    PathBuf::from("~").join(relative_path)
}

/// Checks if a filename is prefixed by a '.' character.
/// If the path cannot be read as UTF-8, assume it isn't hidden.
pub fn is_hidden(filename: &OsStr) -> bool {
    filename
        .to_str()
        .map(|s| s.starts_with('.'))
        .unwrap_or(false)
}

pub enum FileType {
    File,
    Directory,
    Symlink,
}
use FileType::*;

pub fn file_type(path: impl AsRef<Path>) -> io::Result<FileType> {
    let file_type = path.as_ref().symlink_metadata()?.file_type();

    Ok(if file_type.is_file() {
        File
    } else if file_type.is_dir() {
        Directory
    } else if file_type.is_symlink() {
        Symlink
    } else {
        unreachable!()
    })
}

static VERBOSE: AtomicBool = AtomicBool::new(false);

pub fn set_verbosity(verbosity: bool) {
    VERBOSE.store(verbosity, Ordering::SeqCst);
}

pub fn get_verbosity() -> bool {
    VERBOSE.load(Ordering::SeqCst)
}

#[macro_export]
macro_rules! verbose_print {
     ($($args:tt)*) => {
         if crate::common::util::get_verbosity() {
             print!($($args)*);
         }
     }
}

#[macro_export]
macro_rules! verbose_println {
     ($($args:tt)*) => {
         if crate::common::util::get_verbosity() {
             println!($($args)*);
         }
     }
}