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
use crate::result::{Result, ResultExt};

#[derive(Clone, Debug)]
pub struct FileService {
  cfg_dir: String,
  log: slog::Logger
}

impl FileService {
  pub fn new(cfg_dir: &str, logger: &slog::Logger) -> FileService {
    let ret = FileService {
      cfg_dir: cfg_dir.into(),
      log: logger.new(slog::o!("service" => "file"))
    };
    match std::fs::create_dir_all(&ret.path()) {
      Ok(_) => (),
      Err(e) => slog::warn!(logger, "Can't create config directory at [{:?}]: {}", &ret.path(), e)
    };
    ret
  }

  pub fn cfg_dir(&self) -> &String {
    &self.cfg_dir
  }

  pub fn path(&self) -> &std::path::Path {
    std::path::Path::new(&self.cfg_dir)
  }

  pub fn list_json(&self, path: &str) -> Result<Vec<String>> {
    let p = self.path().join(path);
    if p.is_dir() {
      let rd = std::fs::read_dir(&p).chain_err(|| format!("Can't read directory [{}]", p.to_string_lossy()))?;

      let entries = rd
        .filter_map(|entry| {
          entry.ok().and_then(|e| {
            e.path().file_name().and_then(|n| {
              n.to_str()
                .filter(|x| x.ends_with(".json"))
                .map(|x| x.trim_end_matches(".json").into())
            })
          })
        })
        .collect::<Vec<String>>();
      Ok(entries)
    } else {
      Ok(Vec::new())
    }
  }

  pub fn read_json(&self, path: &str, key: &str) -> Result<String> {
    let p = self.path().join(path).join(format!("{}.json", key));
    std::fs::read_to_string(&p).chain_err(|| format!("Can't read file [{}]", p.to_string_lossy()))
  }
}