chilli/
config.rs

1//! This module implements configuration related stuff.
2
3use std::fmt;
4use std::env;
5use std::io::Read;
6use std::fs::File;
7use std::path::Path;
8use serde_json::{self, Map, Value};
9
10/// The pencil `Config` type, We provide ways to fill it from JSON files:
11///
12/// ```rust,no_run
13/// let mut app = chilli::Pencil::new("/demo");
14/// app.config.from_jsonfile("yourconfig.json")
15/// ```
16///
17/// You can also load configurations from an environment variable
18/// pointing to a file:
19///
20/// ```rust,no_run
21/// let mut app = chilli::Pencil::new("/demo");
22/// app.config.from_envvar("YOURAPPLICATION_SETTINGS")
23/// ```
24///
25/// In this case, you have to set this environment variable to the file
26/// you want to use.  On Linux and OS X you can use the export statement:
27///
28/// ```bash
29/// export YOURAPPLICATION_SETTINGS="/path/to/config/file"
30/// ```
31#[derive(Clone)]
32pub struct Config {
33    config: serde_json::Map<String, Value>,
34}
35
36impl Default for Config {
37    fn default() -> Config {
38        Config::new()
39    }
40}
41
42impl Config {
43    /// Create a `Config` object.
44    pub fn new() -> Config {
45        let json_object: Map<String, Value> = Map::new();
46        Config {
47            config: json_object,
48        }
49    }
50
51    /// Set a value for the key.
52    pub fn set(&mut self, key: &str, value: Value) {
53        self.config.insert(key.to_string(), value);
54    }
55
56    /// Returns a reference to the value corresponding to the key.
57    pub fn get(&self, key: &str) -> Option<&Value> {
58        self.config.get(&key.to_string())
59    }
60
61    /// Get a boolean configuration value.  If the key doesn't exist
62    /// or the value is not a `Json::Boolean`, the default value
63    /// will be returned.
64    pub fn get_boolean(&self, key: &str, default: bool) -> bool {
65        match self.get(key) {
66            Some(value) => {
67                match *value {
68                    Value::Bool(value) => value,
69                    _ => default
70                }   
71            },  
72            None => default
73        }
74    }
75
76    /// Loads a configuration from an environment variable pointing to
77    /// a JSON configuration file.
78    pub fn from_envvar(&mut self, variable_name: &str) {
79        match env::var(variable_name) {
80            Ok(value) => self.from_jsonfile(&value),
81            Err(_) => panic!("The environment variable {} is not set.", variable_name),
82        }
83    }
84
85    /// Updates the values in the config from a JSON file.
86    pub fn from_jsonfile(&mut self, filepath: &str) {
87        let path = Path::new(filepath);
88        let mut file = File::open(&path).unwrap();
89        let mut content = String::new();
90        file.read_to_string(&mut content).unwrap();
91        let object: Value = serde_json::from_str(&content).unwrap();
92        match object {
93            Value::Object(object) => { self.from_object(object); },
94            _ => { panic!("The configuration file is not an JSON object."); }
95        }
96    }
97
98    /// Updates the values from the given `Object`.
99    pub fn from_object(&mut self, object: Map<String, Value>) {
100        for (key, value) in &object {
101            self.set(&key, value.clone());
102        }
103    }
104}
105
106impl fmt::Debug for Config {
107    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108        write!(f, "<Pencil Config {:?}>", self.config)
109    }
110}