teascade-generator/src/builder.rs

107 lines
3.7 KiB
Rust

use config::Config;
use template::Template;
use renderer;
use logger::{LogLevel, Logger};
use error::Error;
use std::fs::{create_dir_all, File};
use std::io::prelude::*;
use std::path::{Path, PathBuf};
const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css");
const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html");
const NAVBAR_ITEM: &'static str = include_str!("templates/navbar/item-template.html");
const NAVBAR_IMAGE_ITEM: &'static str = include_str!("templates/navbar/image-item-template.html");
fn fetch_config() -> Result<Config, Error> {
match Config::new() {
Ok(config) => Ok(config),
Err(err) => Err(Error::from(err)),
}
}
fn write_file<T: Into<String>, U: Into<String>>(path_str: T, content: U) -> Result<(), Error> {
let path_str = path_str.into();
let content = content.into();
let mut path = PathBuf::from(&path_str);
if let (Some(parent), Some(file_name)) = (path.clone().parent(), path.clone().file_name()) {
let parent = Path::new("public").join(parent);
create_dir_all(parent.clone())?;
path = parent.join(file_name);
} else {
return Err(Error::new(
LogLevel::SEVERE,
format!("Could not find parent folder or file name for {}", path_str),
));
}
if path.exists() {
Err(Error::new(
LogLevel::SEVERE,
format!(
"File already exists: {} -- Consider using overwrite-flag",
path_str
),
))
} else {
match File::create(path) {
Ok(mut file) => Ok(file.write_all(content.as_bytes()).unwrap()),
Err(err) => Err(Error::from(err)),
}
}
}
pub fn build(logger: &Logger) -> Result<(), Error> {
logger.log(LogLevel::INFO, "Starting build");
let config = fetch_config()?;
if config.global_config.website.use_default_css {
let css_path = "css/default.css";
logger.log(LogLevel::DETAIL, format!("Adding public/{}", css_path));
write_file(css_path, DEFAULT_CSS)?;
}
logger.log(LogLevel::INFO, "Generating page templates");
let page_template = Template::new(PAGE_TEMPLATE);
let mut navbar_content = String::new();
if config.global_config.navbar.is_some() {
let navbar_item_template = Template::new(NAVBAR_ITEM);
let navbar_image_item_template = Template::new(NAVBAR_IMAGE_ITEM);
logger.log(LogLevel::DETAIL, "Rendering Navbar");
navbar_content =
renderer::render_navbar(&config, navbar_item_template, navbar_image_item_template)?;
}
logger.log(LogLevel::INFO, "Rendering");
let configs = config.get_configs()?;
let mut renders = Vec::new();
for config in configs.clone() {
logger.log(
LogLevel::DETAILER,
format!("Rendering {}", config.page_config.page.html_path),
);
let markdown = renderer::render_markdown_content(&config)?;
let data = Template::page_data_from(config.clone(), navbar_content.clone(), markdown);
let rendered = page_template.render(&data);
renders.push(rendered);
}
logger.log(LogLevel::INFO, "Writing");
for (idx, config) in configs.clone().iter().enumerate() {
let html_path = config.clone().page_config.page.html_path;
logger.log(LogLevel::DETAILER, format!("Writing public/{}", html_path));
if let Some(render) = renders.get(idx) {
write_file(html_path, render.clone())?;
} else {
return Err(Error::new(
LogLevel::SEVERE,
format!("Internal error; Render not found for file: {}", html_path),
));
}
}
logger.log(LogLevel::INFO, "Done!");
Ok(())
}