Newer
Older
use super::page::{Page, PageTemplate};
use crate::static_files::StaticFilesManager;
use serde::ser::{SerializeStruct, Serializer};
root_page: Page,
#[serde(default = "Vec::new")]
assets_index: Vec<String>,
templates: Vec<PageTemplate>,
}
#[derive(Debug, Clone)]
pub static_files_manager: StaticFilesManager,
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 with_static_files_manager(
&mut self,
static_files_manager: StaticFilesManager,
) -> WebSite {
WebSite {
last_generated_page_id: 0,
root_page: self.0.root_page.clone(),
static_files_manager: {
let mut static_files_manager = static_files_manager;
static_files_manager
},
pub fn from_json(json: &str) -> Self {
WebSiteBuilder(serde_json::from_str(json).unwrap())
}
#[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::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
}
pub fn build(&mut self) -> Result<Self, String> {
if let Err(err) = self.root_page.build(
&self.templates,
PathBuf::from("/"),
&self.static_files_manager,
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
fn init_last_generated_page_id(&mut self) {
let mut ids = vec![self.root_page.get_id()];
fn collect_ids(p: &Page, ids: &mut Vec<usize>) {
for sp in p.sub_pages.iter() {
ids.push(sp.get_id());
collect_ids(sp, ids);
}
}
collect_ids(&self.root_page, &mut ids);
self.last_generated_page_id = *ids.iter().max().unwrap();
}
fn generate_pages_ids(&mut self) {
self.init_last_generated_page_id();
fn generate_page_id(page: &mut Page, last_generated_page_id: &mut usize) {
if page.get_id() == 0 {
*last_generated_page_id += 1;
page.set_id(*last_generated_page_id);
}
}
fn rec_gen_ids(
p: &mut Page,
gen_id: fn(&mut Page, &mut usize),
last_generated_page_id: &mut usize,
) {
gen_id(p, last_generated_page_id);
for sp in p.sub_pages.iter_mut() {
rec_gen_ids(sp, gen_id, last_generated_page_id)
}
}
rec_gen_ids(
&mut self.root_page,
generate_page_id,
&mut self.last_generated_page_id,
);
}
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(())
}