use serde::{Deserialize, Serialize};
use serde_json;
use std::fmt;
use std::fs::File;
use std;
use std::io::{Read, Write};
use xdg;
use xdg::BaseDirectories;
use std::path::Path;
#[derive(Debug)]
pub enum ConfigError {
IOError(std::io::Error),
SerdeJsonError(serde_json::Error),
}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConfigError::IOError(ref err) => fmt::Display::fmt(err, f),
ConfigError::SerdeJsonError(ref err) => fmt::Display::fmt(err, f),
}
}
}
impl From<std::io::Error> for ConfigError {
fn from(e: std::io::Error) -> Self {
ConfigError::IOError(e)
}
}
impl From<serde_json::Error> for ConfigError {
fn from(e: serde_json::Error) -> Self {
ConfigError::SerdeJsonError(e)
}
}
pub struct ConfigFiles {
xdg_dirs: BaseDirectories,
}
impl ConfigFiles {
pub fn new() -> ConfigFiles {
let xdg_dirs = xdg::BaseDirectories::with_prefix("gog-sync").unwrap();
ConfigFiles { xdg_dirs: xdg_dirs }
}
pub fn load<T>(&self, name: &str) -> Result<T, ConfigError>
where T: Deserialize
{
let config_path = self.xdg_dirs.place_config_file(name)?;
let mut config_file = File::open(config_path)?;
let mut config_contents = String::new();
config_file.read_to_string(&mut config_contents)?;
match serde_json::from_str(config_contents.as_str()) {
Ok(value) => Ok(value),
Err(error) => Err(ConfigError::SerdeJsonError(error)),
}
}
pub fn save<T>(&self, name: &str, content: &T) -> Result<(), ConfigError>
where T: Serialize
{
let config_path = self.xdg_dirs.place_config_file(name)?;
let content_toml = serde_json::to_string_pretty(content)?;
let mut config_file = File::create(&config_path)?;
match config_file.write_all(content_toml.as_bytes()) {
Ok(_) => Ok(()),
Err(error) => Err(ConfigError::IOError(error)),
}
}
pub fn save_to_path<T>(path: &Path, content: &T) -> Result<(), ConfigError>
where T: Serialize
{
let content_toml = serde_json::to_string_pretty(content)?;
let mut config_file = File::create(path)?;
match config_file.write_all(content_toml.as_bytes()) {
Ok(_) => Ok(()),
Err(error) => Err(ConfigError::IOError(error)),
}
}
pub fn load_from_path<T>(path: &Path) -> Result<T, ConfigError>
where T: Deserialize
{
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
match serde_json::from_str(contents.as_str()) {
Ok(value) => Ok(value),
Err(error) => Err(ConfigError::SerdeJsonError(error)),
}
}
}