use figment::{Error, Figment, Metadata, Provider};
use pulldown_cmark::Options;
use serde::{Deserialize, Serialize};
pub const IN_DIR: &str = "content";
pub const OUT_DIR: &str = "_site";
pub const ASSET_DIR: &str = "assets";
pub const TEMPLATE_DIR: &str = "templates";
pub const WORK_DIR: &str = "_work";
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Config {
pub structure: ConfigStructure,
pub options: ConfigOptions,
pub defaults: ConfigDefaults,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ConfigStructure {
pub content: String,
pub assets: String,
pub template: String,
pub work: String,
pub site: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ConfigDefaults {
pub page: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ConfigOptions {
pub math: bool,
}
impl Default for ConfigStructure {
fn default() -> Self {
Self {
content: IN_DIR.into(),
assets: ASSET_DIR.into(),
template: TEMPLATE_DIR.into(),
work: WORK_DIR.into(),
site: OUT_DIR.into(),
}
}
}
impl Default for ConfigDefaults {
fn default() -> Self {
Self {
page: "content".into(),
}
}
}
impl Default for ConfigOptions {
fn default() -> Self {
Self { math: true }
}
}
impl Config {
pub fn figment() -> Figment {
Figment::from(Self::default())
}
pub fn from<T: Provider>(provider: T) -> Result<Self, Error> {
Figment::from(provider).extract()
}
}
impl Provider for Config {
fn metadata(&self) -> Metadata {
Metadata::named("Sitdown config")
}
fn data(&self) -> Result<figment::value::Map<figment::Profile, figment::value::Dict>, Error> {
figment::providers::Serialized::defaults(Self::default()).data()
}
}
impl Provider for ConfigStructure {
fn metadata(&self) -> figment::Metadata {
Metadata::named("Sitdown file structure")
}
fn data(&self) -> Result<figment::value::Map<figment::Profile, figment::value::Dict>, Error> {
figment::providers::Serialized::defaults(Self::default()).data()
}
}
impl Provider for ConfigDefaults {
fn metadata(&self) -> figment::Metadata {
Metadata::named("Sitdown defaults")
}
fn data(&self) -> Result<figment::value::Map<figment::Profile, figment::value::Dict>, Error> {
figment::providers::Serialized::defaults(Self::default()).data()
}
}
impl ConfigOptions {
pub fn options(&self) -> Options {
let mut options = Options::empty();
options.insert(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS);
options.insert(Options::ENABLE_TABLES);
if self.math {
options.insert(Options::ENABLE_MATH);
}
options
}
}
impl Provider for ConfigOptions {
fn metadata(&self) -> Metadata {
Metadata::named("Sitdown parser options")
}
fn data(&self) -> Result<figment::value::Map<figment::Profile, figment::value::Dict>, Error> {
figment::providers::Serialized::defaults(Self::default()).data()
}
}