From cf7e559d9c6de92bc88db367ea325303fef29098 Mon Sep 17 00:00:00 2001
From: peterrabbit <pierre.jarriges@tutanota.com>
Date: Wed, 21 Sep 2022 21:59:01 +0200
Subject: [PATCH] appstate builder

---
 src/app/config.rs      | 45 ++++++++++++++++++++++++++--------------
 src/app/mod.rs         |  2 --
 src/app/preferences.rs |  2 --
 src/app/state.rs       | 47 ++++++++++++++++++++++++++++--------------
 src/main.rs            |  5 +++--
 src/service/files.rs   |  4 ++--
 6 files changed, 66 insertions(+), 39 deletions(-)
 delete mode 100644 src/app/preferences.rs

diff --git a/src/app/config.rs b/src/app/config.rs
index 1a031d4..3c253e5 100644
--- a/src/app/config.rs
+++ b/src/app/config.rs
@@ -33,21 +33,8 @@ impl AppConfig {
             .unwrap()
             .to_string();
 
-        let context = match app_args.context.as_str() {
-            "prod" => AppContext::Production,
-            _ => AppContext::Debug,
-        };
-
-        let storage_dir = match &app_args.app_storage_root {
-            Some(dir) => dir.join(&exec_name),
-            None => match context {
-                AppContext::Production => PathBuf::from("/var").join(&exec_name),
-                AppContext::Debug => dirs::home_dir()
-                    .expect("Unable to get home dir")
-                    .join(&exec_name),
-            },
-        };
-
+        let context = Self::get_context(&app_args);
+        let storage_dir = Self::get_storage_dir(&app_args, &exec_name, &context).unwrap();
         let ssl_certs_dir = app_args.ssl_certs_dir.join(&app_args.host);
 
         AppConfig {
@@ -65,6 +52,34 @@ impl AppConfig {
             admin_cookie_name: app_args.admin_cookie_name,
         }
     }
+
+    fn get_storage_dir(
+        app_args: &AppArgs,
+        exec_name: &String,
+        context: &AppContext,
+    ) -> Result<PathBuf, String> {
+        match &app_args.app_storage_root {
+            Some(dir) => Ok(dir.join(&exec_name)),
+            None => match context {
+                AppContext::Production => Ok(PathBuf::from("/var").join(&exec_name)),
+                AppContext::Debug => {
+                    let home_dir = dirs::home_dir();
+                    if home_dir.is_none() {
+                        return Err(String::from("Unable to get home dir"));
+                    }
+                    Ok(home_dir.unwrap().join(&exec_name))
+                }
+            },
+        }
+    }
+
+    fn get_context(app_args: &AppArgs) -> AppContext {
+        match app_args.context.as_str() {
+            "prod" => AppContext::Production,
+            _ => AppContext::Debug,
+        }
+    }
+
     pub fn get_log_level(&self) -> String {
         match self.context {
             AppContext::Debug => "debug".to_string(),
diff --git a/src/app/mod.rs b/src/app/mod.rs
index e5bee9e..73e03b5 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -1,8 +1,6 @@
 mod args;
 mod config;
-mod preferences;
 mod state;
 pub use args::*;
 pub use config::*;
-pub use preferences::*;
 pub use state::*;
diff --git a/src/app/preferences.rs b/src/app/preferences.rs
deleted file mode 100644
index f097a65..0000000
--- a/src/app/preferences.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#[derive(Clone)]
-pub struct AppPreferences {}
diff --git a/src/app/state.rs b/src/app/state.rs
index 5b4347c..5e137be 100644
--- a/src/app/state.rs
+++ b/src/app/state.rs
@@ -1,4 +1,4 @@
-use crate::app::{AppArgs, AppConfig, AppPreferences};
+use crate::app::{AppArgs, AppConfig};
 use crate::cookie::SecureCookie;
 use actix_web::cookie::Cookie;
 use structopt::StructOpt;
@@ -6,31 +6,46 @@ use structopt::StructOpt;
 #[derive(Clone)]
 pub struct AppState {
     pub config: AppConfig,
-    pub preferences: AppPreferences,
     pub admin_auth_token: AdminAuthToken,
 }
 
-impl AppState {
+pub struct AppStateBuilder {
+    args: Option<AppArgs>,
+}
+
+impl AppStateBuilder {
     pub fn new() -> Self {
-        let config = AppConfig::new(AppArgs::from_args());
-        let admin_cookie_name = config.admin_cookie_name.to_owned();
+        AppStateBuilder { args: None }
+    }
+    pub fn build(&self) -> AppState {
+        let config = self.config();
         AppState {
-            config,
-            preferences: AppPreferences {},
-            admin_auth_token: AdminAuthToken::new(admin_cookie_name),
+            config: config.clone(),
+            admin_auth_token: AdminAuthToken::new(config.admin_cookie_name.to_owned()),
         }
     }
 
-    #[cfg(test)]
-    pub fn testing() -> Self {
-        let config = AppConfig::new(AppArgs::testing());
-        let admin_cookie_name = config.admin_cookie_name.to_owned();
-        AppState {
-            config,
-            preferences: AppPreferences {},
-            admin_auth_token: AdminAuthToken::new(admin_cookie_name),
+    fn config(&self) -> AppConfig {
+        AppConfig::new(self.get_args())
+    }
+
+    fn get_args(&self) -> AppArgs {
+        match &self.args {
+            Some(args) => args.clone(),
+            None => AppArgs::from_args(),
         }
     }
+
+    pub fn use_args(&mut self, args: AppArgs) -> &Self {
+        self.args = Some(args);
+        self
+    }
+}
+
+impl AppState {
+    pub fn builder() -> AppStateBuilder {
+        AppStateBuilder::new()
+    }
 }
 
 #[derive(Clone)]
diff --git a/src/main.rs b/src/main.rs
index 37f1d9e..ba4dd2d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,16 +9,17 @@ mod website;
 use actix_files::Files;
 use actix_web::{web, App, HttpServer};
 use actix_web_lab::middleware::RedirectHttps;
-use app::AppState;
+use app::{AppArgs, AppState};
 use middleware::AuthService;
 use static_files::StaticFilesManager;
 use std::sync::RwLock;
+use structopt::StructOpt;
 use tls_config::tls_config;
 use website::WebSiteBuilder;
 
 #[actix_web::main]
 async fn main() -> std::io::Result<()> {
-    let app_state = AppState::new();
+    let app_state = AppState::builder().use_args(AppArgs::from_args()).build();
 
     env_logger::Builder::from_env(
         env_logger::Env::default().default_filter_or(&app_state.config.get_log_level()),
diff --git a/src/service/files.rs b/src/service/files.rs
index ced55d2..25bb61e 100644
--- a/src/service/files.rs
+++ b/src/service/files.rs
@@ -143,7 +143,7 @@ async fn delete_static_file(
 #[cfg(test)]
 mod test_static_files_services {
     use super::*;
-    use crate::{cookie::*, website::*, AppState};
+    use crate::{app::AppArgs, cookie::*, website::*, AppState};
     use actix_web::{
         http::{Method, StatusCode},
         test,
@@ -172,7 +172,7 @@ mod test_static_files_services {
 
     #[actix_web::test]
     async fn post_files_unauthenticated_should_be_unauthorized() {
-        let app_state = AppState::testing();
+        let app_state = AppState::builder().use_args(AppArgs::testing()).build();
         let static_dir = std::path::PathBuf::from("./test");
         let ws = WebSiteBuilder::testing(&static_dir);
 
-- 
GitLab