From f39608b56b4046116c7259fec85685b0fa96e503 Mon Sep 17 00:00:00 2001
From: Pierre Jarriges <pierre.jarriges@tutanota.com>
Date: Tue, 27 Sep 2022 09:45:53 +0200
Subject: [PATCH] fix assets dir & WebSite impl Serialize

---
 Cargo.toml                       |  2 +-
 src/main.rs                      | 18 +++++++------
 src/service/files.rs             | 12 ++++++---
 src/static_files/static_files.rs | 32 ++++++++++++++---------
 src/website/website.rs           | 45 +++++++++++++++++++++-----------
 5 files changed, 70 insertions(+), 39 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index c068763..a52c7c8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,7 +11,7 @@ readme = "README.md"
 actix-web = { version = "4.1.0", features = ["rustls", "secure-cookies"] }
 rustls = "0.20.6"
 rustls-pemfile = "1.0.1"
-serde = { version = "1.0.144", features = ["derive"] }
+serde = { version = "1", features = ["derive"] }
 serde_json = "1.0.83"
 regex = "1.6"
 fs_extra = "1.2"
diff --git a/src/main.rs b/src/main.rs
index 1edfb00..ee1186c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -26,14 +26,16 @@ async fn main() -> std::io::Result<()> {
     )
     .init();
 
-    let website = {
-        let mut wb = WebSiteBuilder::load(&app_state.config);
-        let static_manager = StaticFilesManager::new(&app_state).unwrap().build();
-        wb.save(&app_state.config).unwrap();
-        wb.with_static_files_manager(static_manager)
-            .build()
-            .unwrap()
-    };
+    let website = WebSiteBuilder::load(&app_state.config)
+        .with_static_files_manager(
+            StaticFilesManager::new(&app_state)
+                .unwrap()
+                .build_assets_index(),
+        )
+        .build()
+        .unwrap();
+
+    website.save(&app_state.config).unwrap();
 
     let host = app_state.config.host.clone();
     let port = app_state.config.port;
diff --git a/src/service/files.rs b/src/service/files.rs
index d961eae..e55c419 100644
--- a/src/service/files.rs
+++ b/src/service/files.rs
@@ -48,7 +48,7 @@ async fn write_uploaded_file(
     filename: &String,
     upload_type: UploadFileType,
 ) -> Result<String, String> {
-    let root = &website.static_files_manager.dir.join("assets");
+    let root = &website.static_files_manager.assets_dir();
     let sub_dir = dirname_from_type(&upload_type);
     let filepath = root.join(sub_dir).join(&filename);
 
@@ -100,7 +100,7 @@ pub async fn post_files(website: Data<RwLock<WebSite>>, mut payload: Multipart)
                     Ok(filepath) => uploaded_filepathes.extend(
                         website
                             .static_files_manager
-                            .push_path(std::path::Path::new(&filepath)),
+                            .push_asset_path(std::path::Path::new(&filepath)),
                     ),
                 }
             }
@@ -115,7 +115,13 @@ pub async fn post_files(website: Data<RwLock<WebSite>>, mut payload: Multipart)
 
 #[get("/static-files-index")]
 async fn get_static_files_index(website: Data<RwLock<WebSite>>) -> impl Responder {
-    HttpResponse::Ok().json(website.read().unwrap().static_files_manager.get_index())
+    HttpResponse::Ok().json(
+        website
+            .read()
+            .unwrap()
+            .static_files_manager
+            .get_assets_index(),
+    )
 }
 
 #[delete("/delete-file/{category}/{filename}")]
diff --git a/src/static_files/static_files.rs b/src/static_files/static_files.rs
index 00e42d5..6a2ed55 100644
--- a/src/static_files/static_files.rs
+++ b/src/static_files/static_files.rs
@@ -103,7 +103,7 @@ impl StaticFilesManager {
                 if entry.path().is_dir() {
                     self.rec_read_dir(&entry.path(), strip_from);
                 } else {
-                    self.push_path(&entry.path().strip_prefix(strip_from).unwrap());
+                    self.push_asset_path(&entry.path().strip_prefix(strip_from).unwrap());
                 }
             }
         }
@@ -120,7 +120,7 @@ impl StaticFilesManager {
         }
     }
 
-    pub fn push_path(&mut self, path: &Path) -> Vec<PathBuf> {
+    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());
@@ -134,18 +134,18 @@ impl StaticFilesManager {
         }
     }
 
-    pub fn add_pathes(&mut self, pathes: &Vec<String>) -> Vec<PathBuf> {
+    pub fn add_assets_pathes(&mut self, pathes: &Vec<String>) -> Vec<PathBuf> {
         let mut added: Vec<PathBuf> = Vec::new();
         for pth in pathes.iter() {
-            let p = self.push_path(Path::new(pth));
+            let p = self.push_asset_path(Path::new(pth));
             added.extend(p.iter().map(|pb| pb.clone()));
         }
         added
     }
 
-    pub fn build(&mut self) -> Self {
+    pub fn build_assets_index(&mut self) -> Self {
         self.index = Vec::new();
-        self.rec_read_dir(&self.dir.clone(), &self.dir.clone());
+        self.rec_read_dir(&self.assets_dir(), &self.dir.clone());
         self.clone()
     }
 
@@ -158,10 +158,14 @@ impl StaticFilesManager {
             .collect();
     }
 
-    pub fn get_index(&self) -> Vec<String> {
+    pub fn get_assets_index(&self) -> Vec<String> {
         self.index.clone()
     }
 
+    pub fn assets_dir(&self) -> PathBuf {
+        self.dir.join("assets")
+    }
+
     pub fn write_html_page(&self, url: &PathBuf, page: &Page) -> std::io::Result<()> {
         let dir = self.dir.join(self.clean_relative_path(url));
 
@@ -221,7 +225,7 @@ mod test_static_files_manager {
         let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap();
         let file_pth = test_dir.join("assets").join("docs").join("testing.txt");
         std::fs::File::create(&file_pth).unwrap();
-        manager = manager.build();
+        manager = manager.build_assets_index();
 
         assert!(
             manager
@@ -237,11 +241,13 @@ mod test_static_files_manager {
     #[test]
     fn test_push_and_remove_path() {
         let test_dir = create_test_dir();
-        let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap().build();
+        let mut manager = StaticFilesManager::testing_new(&test_dir)
+            .unwrap()
+            .build_assets_index();
         let file_pth = test_dir.join("assets").join("docs").join("testing.txt");
         std::fs::File::create(&file_pth).unwrap();
         let indexed_path = Path::new("assets/docs/testing.txt");
-        let added = manager.push_path(&indexed_path);
+        let added = manager.push_asset_path(&indexed_path);
 
         assert_eq!(
             added,
@@ -274,9 +280,11 @@ mod test_static_files_manager {
     #[test]
     fn test_push_unexisting_path() {
         let test_dir = create_test_dir();
-        let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap().build();
+        let mut manager = StaticFilesManager::testing_new(&test_dir)
+            .unwrap()
+            .build_assets_index();
         let indexed_path = Path::new("assets/images/unexisting.png");
-        let added = manager.push_path(&indexed_path);
+        let added = manager.push_asset_path(&indexed_path);
 
         assert_eq!(
             added.len(),
diff --git a/src/website/website.rs b/src/website/website.rs
index 970451d..954c9ce 100644
--- a/src/website/website.rs
+++ b/src/website/website.rs
@@ -1,6 +1,7 @@
 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;
@@ -20,6 +21,19 @@ pub struct WebSite {
     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()
@@ -33,7 +47,7 @@ impl WebSiteBuilder {
             root_page: self.root_page.clone(),
             static_files_manager: {
                 let mut static_files_manager = static_files_manager;
-                static_files_manager.add_pathes(&self.assets_index);
+                static_files_manager.add_assets_pathes(&self.assets_index);
                 static_files_manager
             },
             templates: self.templates.clone(),
@@ -79,20 +93,6 @@ impl WebSiteBuilder {
 
         None
     }
-
-    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(())
-    }
 }
 
 impl WebSite {
@@ -107,4 +107,19 @@ impl WebSite {
 
         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(())
+    }
 }
-- 
GitLab