-
Pierre Jarriges authoredPierre Jarriges authored
website.rs 3.54 KiB
use super::page::{Page, PageTemplate};
use crate::app::AppConfig;
use crate::static_files::StaticFilesManager;
use serde::ser::{SerializeStruct, Serializer};
use serde::{Deserialize, Serialize};
use std::io::prelude::*;
use std::path::PathBuf;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WebSiteBuilder {
root_page: Page,
#[serde(default = "Vec::new")]
assets_index: Vec<String>,
templates: Vec<PageTemplate>,
}
#[derive(Debug, Clone)]
pub struct WebSite {
root_page: Page,
pub static_files_manager: StaticFilesManager,
templates: Vec<PageTemplate>,
}
impl Serialize for WebSite {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("WebSite", 3)?;
state.serialize_field("root_page", &self.root_page)?;
state.serialize_field("templates", &self.templates)?;
state.serialize_field("assets_index", &self.static_files_manager.index)?;
state.end()
}
}
impl WebSiteBuilder {
pub fn from_json(json: &str) -> Self {
serde_json::from_str(json).unwrap()
}
pub fn with_static_files_manager(
&mut self,
static_files_manager: StaticFilesManager,
) -> WebSite {
WebSite {
root_page: self.root_page.clone(),
static_files_manager: {
let mut static_files_manager = static_files_manager;
static_files_manager.add_assets_pathes(&self.assets_index);
static_files_manager
},
templates: self.templates.clone(),
}
}
#[cfg(test)]
pub fn testing(test_dir: &PathBuf) -> WebSite {
Self::from_json(crate::testing::TEST_JSON_WEBSITE)
.with_static_files_manager(StaticFilesManager::testing_new(test_dir).unwrap())
}
fn blank_website_template() -> PathBuf {
std::env::current_dir()
.unwrap()
.join("templates")
.join("new_website.json")
}
pub fn load(config: &AppConfig) -> Self {
let file_path = match &config.load {
Some(pth) => pth.clone(),
None => {
if let Some(loaded) = Self::try_load_from_existing_file(config) {
return loaded;
}
Self::blank_website_template()
}
};
Self::from_json(&std::fs::read_to_string(file_path).unwrap())
}
fn try_load_from_existing_file(config: &AppConfig) -> Option<Self> {
let website_file_path = config.storage_dir.join("website.json");
if website_file_path.exists() {
match &std::fs::read_to_string(&website_file_path) {
Ok(json) => return Some(Self::from_json(&json)),
Err(_) => return None,
}
}
None
}
}
impl WebSite {
pub fn build(&mut self) -> Result<Self, String> {
if let Err(err) = self.root_page.build(
&self.templates,
PathBuf::from("/"),
&self.static_files_manager,
) {
return Err(err);
};
Ok(self.clone())
}
pub fn save(&self, config: &AppConfig) -> std::io::Result<()> {
let save_json = serde_json::to_string(self).unwrap();
let json_path = config.storage_dir.join("website.json");
let mut f = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(&json_path)?;
f.write_all(save_json.as_bytes())?;
f.flush()?;
Ok(())
}
}