1
use crate::{client, error::Error, server};
2
use serde::{Deserialize, Serialize};
3
use std::fs;
4

            
5
#[cfg(test)]
6
mod test;
7

            
8
/// Configuration options for the bot
9
#[derive(Serialize, Deserialize, Debug)]
10
#[serde(rename_all = "kebab-case")]
11
pub struct Configuration {
12
    /// Set the log level to use.
13
    /// Accepted values are "error", "warn", "info" and "debug".
14
    #[serde(skip_serializing_if = "str::is_empty", default = "default_log_level")]
15
    pub log_level: String,
16
    /// Server configuration
17
    #[serde(default)]
18
    pub server: server::ServerOptions,
19
    /// Client configuration
20
    pub github: client::ClientOptions,
21
}
22

            
23
2
fn default_log_level() -> String {
24
2
    "info".to_string()
25
2
}
26

            
27
impl Configuration {
28
    /// Load the configuration from a file
29
6
    pub fn load(path: &str) -> Result<Self, Error> {
30
        // TODO: Replace with supported version
31
5
        let contents =
32
6
            fs::read_to_string(path).map_err(|e| Error::ReadConfigFile(path.to_string(), e))?;
33

            
34
5
        let config: Self = serde_yaml::from_str(&contents)
35
5
            .map_err(|e| Error::ParseConfigFile(path.to_string(), e))?;
36

            
37
5
        config.validate().map_err(Error::InvalidConfig)?;
38
5
        Ok(config)
39
6
    }
40

            
41
    /// Validate the configuration
42
5
    pub fn validate(&self) -> Result<(), &'static str> {
43
5
        self.server.validate()?;
44
5
        self.github.validate()?;
45
5
        Ok(())
46
5
    }
47
}