1use crate::error;
2
3use glob;
4use std::env;
5use std::path;
6
7#[derive(Debug)]
8pub struct Paths {
9 config: path::PathBuf,
10 cache: path::PathBuf,
11 data: path::PathBuf,
12}
13
14impl Paths {
15 pub fn new() -> error::Result<Self> {
16 match env::var_os("RQ_SYSTEM_DIR") {
17 Some(basepath) => {
18 let basepath = path::Path::new(&basepath);
19 Ok(Self {
20 config: basepath.join("config"),
21 cache: basepath.join("cache"),
22 data: basepath.join("data"),
23 })
24 },
25 None => match directories::ProjectDirs::from("io", "dflemstr", "rq") {
26 Some(dirs) => Ok(Self {
27 config: dirs.config_dir().into(),
28 cache: dirs.cache_dir().into(),
29 data: dirs.data_dir().into(),
30 }),
31 None => Err(error::Error::Message(
32 "The environment variable RQ_SYSTEM_DIR is unspecified and no home directory is known".to_string()
33 )),
34 },
35 }
36 }
37
38 pub fn preferred_config<P>(&self, path: P) -> path::PathBuf
39 where
40 P: AsRef<path::Path>,
41 {
42 let mut result = self.config.clone();
43 result.push(path);
44 result
45 }
46
47 pub fn preferred_cache<P>(&self, path: P) -> path::PathBuf
48 where
49 P: AsRef<path::Path>,
50 {
51 let mut result = self.cache.clone();
52 result.push(path);
53 result
54 }
55
56 pub fn preferred_data<P>(&self, path: P) -> path::PathBuf
57 where
58 P: AsRef<path::Path>,
59 {
60 let mut result = self.data.clone();
61 result.push(path);
62 result
63 }
64
65 pub fn find_config(&self, pattern: &str) -> error::Result<Vec<path::PathBuf>> {
66 find(&self.config, pattern)
67 }
68
69 pub fn find_data(&self, pattern: &str) -> error::Result<Vec<path::PathBuf>> {
70 find(&self.data, pattern)
71 }
72}
73
74fn find(home: &path::Path, pattern: &str) -> error::Result<Vec<path::PathBuf>> {
75 let mut result = Vec::new();
76 run_pattern(home, pattern, &mut result)?;
77 Ok(result)
78}
79
80fn run_pattern(
81 dir: &path::Path,
82 pattern: &str,
83 result: &mut Vec<path::PathBuf>,
84) -> error::Result<()> {
85 let full_pattern = format!("{}/{}", dir.to_string_lossy(), pattern);
86
87 for entry in glob::glob(&full_pattern)? {
88 result.push(entry?);
89 }
90
91 Ok(())
92}