summaryrefslogtreecommitdiffstats
path: root/src/configuration.rs
blob: 2fbaf70e0f1f91cdd1297ea7b3d11174cfef3630 (plain)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::fmt::{Debug, Formatter, Error};
use std::path::Path;

use config::reader::from_file;
use config::types::Config as Cfg;
use cli::CliConfig;

/**
 * Configuration object which represents the configuration file.
 *
 * It gets passed a CliConfig object on ::new(), retreives some data from this one which is then
 * provided as default value to the callee if there is no value for it in the configuration.
 *
 * TODO: Setup is kinda ugly, as we re-use data from the CLI, which is the job of the Runtime
 * object later.
 */
pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub editor      : Option<String>,
    pub editor_opts : String,
    pub report_exit : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config).or(default_path()).unwrap_or(String::from("/tmp/"));


        let cfg = fetch_config(&rtp);

        let store_sub   = String::from(cfg.lookup_str("store").unwrap_or("/store"));
        let editor      = cfg.lookup_str("editor").map(String::from);
        let editor_opts = String::from(cfg.lookup_str("editor-opts").unwrap_or(""));
        let report_exit = cfg.lookup_boolean("report-exit").unwrap_or(false);

        debug!("Building configuration");
        debug!("  - store sub  : {}", store_sub);
        debug!("  - runtimepath: {}", rtp);
        debug!("  - editor     : {:?}", editor);
        debug!("  - editor-opts: {}", editor_opts);
        debug!("  - report exit: {}", report_exit);

        Configuration {
            store_sub: store_sub,
            rtp: rtp,
            editor: editor,
            editor_opts: editor_opts,
            report_exit: report_exit,
        }
    }

    /**
     * Get the store path the configuration configured
     */
    pub fn store_path(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    /**
     * Get the runtime path the configuration configured
     */
    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

    pub fn editor(&self) -> Option<String> {
        self.editor.clone()
    }

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

    pub fn report_exit(&self) -> bool {
        self.report_exit
    }

}

/**
 * Helper to get the runtimepath from the CLI
 */
fn rtp_path(config: &CliConfig) -> Option<String> {
    config.cli_matches.value_of("rtp")
                      .and_then(|s| Some(String::from(s)))
}

fn fetch_config(rtp: &String) -> Cfg {
    use std::process::exit;

    let configpath = format!("{}{}", rtp, "/config");
    from_file(Path::new(&configpath)).map_err(|e| {
        println!("Error loading config at '{}' -> {:?}", configpath, e);
        println!("Exiting now.");
        exit(1)
    }).unwrap()
}

/**
 * Default runtime path, if available.
 */
fn default_path() -> Option<String> {
    use std::env::home_dir;

    home_dir().and_then(|mut buf| {
        buf.push("/.imag");
        buf.to_str().map(|s| String::from(s))
    })

}

impl Debug for Configuration {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Configuration (rtp: {}, store path: {})",
            self.get_rtp(),
            self.store_path()
            )
    }

}