use sec::Secret;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use failure::{Error, ResultExt};
use toml;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub general: General,
pub github: Option<GithubConfig>,
pub gitlab: Option<GitLabConfig>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct General {
pub dest_dir: PathBuf,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct GithubConfig {
pub api_key: Secret<String>,
#[serde(default = "always_true")]
pub starred: bool,
#[serde(default = "always_true")]
pub owned: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[allow(deprecated)]
pub struct GitLabConfig {
pub api_key: Secret<String>,
#[serde(default = "default_gitlab_url")]
pub host: String,
#[serde(default = "always_false")]
pub organisations: bool,
#[serde(default = "always_true")]
pub owned: bool,
}
fn always_true() -> bool {
true
}
fn always_false() -> bool {
false
}
fn default_gitlab_url() -> String {
String::from("https://gitlab.com/")
}
impl Config {
pub fn from_file<P: AsRef<Path>>(file: P) -> Result<Config, Error> {
let file = file.as_ref();
debug!("Reading config from {}", file.display());
let mut buffer = String::new();
File::open(file)
.with_context(|_| format!("Unable to open {}", file.display()))?
.read_to_string(&mut buffer)
.context("Reading config file failed")?;
Config::from_str(&buffer)
}
pub fn from_str(src: &str) -> Result<Config, Error> {
toml::from_str(src)
.context("Parsing config file failed")
.map_err(Error::from)
}
pub fn example() -> Config {
Config {
general: General {
dest_dir: PathBuf::from("/srv"),
},
github: Some(GithubConfig {
api_key: String::from("your API key").into(),
owned: true,
starred: false,
}),
gitlab: Some(GitLabConfig {
api_key: String::from("your API key").into(),
host: String::from("gitlab.com"),
organisations: true,
owned: true,
}),
}
}
pub fn as_toml(&self) -> String {
match toml::to_string_pretty(self) {
Ok(s) => s,
Err(e) => {
panic!("Serializing a Config should never fail. {}", e);
}
}
}
}