From ca03f043343e78755eb11b538019eb1cfb51ca4c Mon Sep 17 00:00:00 2001 From: Pierre Jarriges <pierre.jarriges@tutanota.com> Date: Tue, 27 Sep 2022 13:36:09 +0200 Subject: [PATCH] pages id --- src/static_files/static_files.rs | 15 +++++--- src/website/page.rs | 21 +++++++++- src/website/website.rs | 66 ++++++++++++++++++++++++++++---- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/static_files/static_files.rs b/src/static_files/static_files.rs index 6a2ed55..ae8c6e6 100644 --- a/src/static_files/static_files.rs +++ b/src/static_files/static_files.rs @@ -110,7 +110,7 @@ impl StaticFilesManager { } fn validate_path(&self, path: &Path) -> bool { - self.dir.join(self.clean_relative_path(path)).exists() + self.dir.join(path).exists() } fn clean_relative_path(&self, path: &Path) -> PathBuf { @@ -121,14 +121,17 @@ impl StaticFilesManager { } pub fn push_asset_path(&mut self, path: &Path) -> Vec<PathBuf> { - if self.validate_path(path) { - self.index - .push(self.clean_relative_path(path).to_str().unwrap().to_owned()); - vec![path.to_path_buf()] + let path = self.clean_relative_path(path); + if self.validate_path(&Path::new(&path)) { + let path_str = path.to_str().unwrap(); + if !self.index.iter().any(|s| s.eq(path_str)) { + self.index.push(path_str.to_owned()); + } + vec![path] } else { println!( "[WARNING] Error building static file index. The file {:?} doesn't exist and will be removed from the index.", - self.dir.join(self.clean_relative_path(path)), + self.dir.join(&path), ); Vec::new() } diff --git a/src/website/page.rs b/src/website/page.rs index 94a7b97..6559b01 100644 --- a/src/website/page.rs +++ b/src/website/page.rs @@ -11,8 +11,18 @@ use serde::{ use std::collections::HashMap; use std::path::PathBuf; +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct PageId(usize); +impl Default for PageId { + fn default() -> Self { + PageId(0) + } +} + #[derive(Debug, Deserialize, Clone)] pub struct Page { + #[serde(default)] + id: PageId, pub template_name: String, pub body: PageBody, pub full_body: Option<PageBody>, @@ -30,11 +40,11 @@ impl Serialize for Page { S: Serializer, { let mut state = serializer.serialize_struct("Page", 5)?; + state.serialize_field("id", &self.id.0)?; state.serialize_field("template_name", &self.template_name)?; state.serialize_field("body", &self.body)?; state.serialize_field("metadata", &self.metadata)?; state.serialize_field("sub_pages", &self.sub_pages)?; - state.serialize_field("template", &self.template)?; state.end() } @@ -243,6 +253,14 @@ impl Page { self.template = Some(template); } + pub fn get_id(&self) -> usize { + self.id.0 + } + + pub fn set_id(&mut self, id: usize) { + self.id.0 = id + } + fn build_html(&mut self) { self.html = HtmlDoc::from_page(self); } @@ -376,6 +394,7 @@ mod test_pages { fn test_page() -> Page { Page { + id: PageId(1), template_name: String::from("test template"), body: PageBody(vec![HtmlElement { tag: "span".to_string(), diff --git a/src/website/website.rs b/src/website/website.rs index 954c9ce..fc53a9b 100644 --- a/src/website/website.rs +++ b/src/website/website.rs @@ -7,15 +7,18 @@ use std::io::prelude::*; use std::path::PathBuf; #[derive(Debug, Serialize, Deserialize, Clone)] -pub struct WebSiteBuilder { +pub struct WebSiteData { root_page: Page, #[serde(default = "Vec::new")] assets_index: Vec<String>, templates: Vec<PageTemplate>, } +pub struct WebSiteBuilder(WebSiteData); + #[derive(Debug, Clone)] pub struct WebSite { + last_generated_page_id: usize, root_page: Page, pub static_files_manager: StaticFilesManager, templates: Vec<PageTemplate>, @@ -35,25 +38,26 @@ impl Serialize for WebSite { } 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(), + 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.add_assets_pathes(&self.assets_index); + static_files_manager.add_assets_pathes(&self.0.assets_index); static_files_manager }, - templates: self.templates.clone(), + templates: self.0.templates.clone(), } } + 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) @@ -74,6 +78,7 @@ impl WebSiteBuilder { if let Some(loaded) = Self::try_load_from_existing_file(config) { return loaded; } + Self::blank_website_template() } }; @@ -105,9 +110,54 @@ impl WebSite { return Err(err); }; + self.generate_pages_ids(); + Ok(self.clone()) } + 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"); -- GitLab