2017-08-24 23:38:03 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::fs::File;
|
|
|
|
use std::io::prelude::*;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
2018-07-31 13:17:31 +00:00
|
|
|
use toml::Value as Toml;
|
2017-08-24 23:38:03 +00:00
|
|
|
|
|
|
|
use errors::{Result, ResultExt};
|
|
|
|
|
|
|
|
|
|
|
|
/// Holds the data from a `theme.toml` file.
|
|
|
|
/// There are other fields than `extra` in it but Gutenberg
|
|
|
|
/// itself doesn't care about them.
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Theme {
|
|
|
|
/// All user params set in [extra] in the theme.toml
|
|
|
|
pub extra: HashMap<String, Toml>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Theme {
|
|
|
|
/// Parses a TOML string to our Theme struct
|
|
|
|
pub fn parse(content: &str) -> Result<Theme> {
|
|
|
|
let theme = match content.parse::<Toml>() {
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(e) => bail!(e),
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut extra = HashMap::new();
|
2017-08-31 09:01:26 +00:00
|
|
|
if let Some(theme_table) = theme.as_table() {
|
2017-08-24 23:38:03 +00:00
|
|
|
if let Some(ex) = theme_table.get("extra") {
|
|
|
|
if ex.is_table() {
|
|
|
|
extra = ex.clone().try_into().unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bail!("Expected the `theme.toml` to be a TOML table")
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-31 13:17:31 +00:00
|
|
|
Ok(Theme { extra })
|
2017-08-24 23:38:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Parses a theme file from the given path
|
|
|
|
pub fn from_file(path: &PathBuf) -> Result<Theme> {
|
|
|
|
let mut content = String::new();
|
|
|
|
File::open(path)
|
2018-10-10 11:57:21 +00:00
|
|
|
.chain_err(||
|
|
|
|
"No `theme.toml` file found. \
|
|
|
|
Is the `theme` defined in your `config.toml present in the `themes` directory \
|
|
|
|
and does it have a `theme.toml` inside?"
|
|
|
|
)?
|
2017-08-24 23:38:03 +00:00
|
|
|
.read_to_string(&mut content)?;
|
|
|
|
|
|
|
|
Theme::parse(&content)
|
|
|
|
}
|
|
|
|
}
|