hone/
config.rs

1use crate::{Error, ErrorKind, Result};
2use serde::{Deserialize, Serialize};
3use serde_json;
4use std::env;
5use std::fs::File;
6use std::path::{Path, PathBuf};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub struct Config {
11    #[serde(default, skip_serializing_if = "Option::is_none")]
12    pub data_dir: Option<PathBuf>,
13    // default_sampler, default_pruner
14}
15
16impl Default for Config {
17    fn default() -> Self {
18        Self { data_dir: None }
19    }
20}
21
22impl Config {
23    pub const FILE_NAME: &'static str = "config.json";
24    pub const FILE_PATH: &'static str = ".hone/config.json";
25
26    pub fn data_dir(&self) -> Result<PathBuf> {
27        // TODO
28        let config_path = track!(Self::lookup_path())?;
29        let config_dir = track_assert_some!(config_path.parent(), ErrorKind::Bug);
30        if let Some(data_dir) = &self.data_dir {
31            Ok(config_dir.join(data_dir))
32        } else {
33            Ok(config_dir.join("data/"))
34        }
35    }
36
37    pub fn lookup_path() -> Result<PathBuf> {
38        let current_dir = track!(env::current_dir().map_err(Error::from))?;
39        let mut dir = current_dir.as_path();
40        loop {
41            let path = dir.join(Self::FILE_PATH);
42            if path.exists() {
43                return Ok(path);
44            }
45
46            dir = track_assert_some!(dir.parent(), ErrorKind::InvalidInput);
47        }
48    }
49
50    pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
51        let file = track!(File::open(path).map_err(Error::from))?;
52        let config = track!(serde_json::from_reader(file).map_err(Error::from))?;
53        Ok(config)
54    }
55
56    pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()> {
57        let file = track!(File::create(path).map_err(Error::from))?;
58        track!(serde_json::to_writer_pretty(file, self).map_err(Error::from))?;
59        Ok(())
60    }
61}