Browse Source

DataStore agnostic api fun

uniqueNullptr2 3 years ago
parent
commit
89c293abdd
7 changed files with 89 additions and 32 deletions
  1. 1 1
      Cargo.toml
  2. 5 8
      src/endpoints/create.rs
  3. 14 15
      src/endpoints/pasta.rs
  4. 8 5
      src/endpoints/pastalist.rs
  5. 5 1
      src/main.rs
  6. 2 2
      src/pasta.rs
  7. 54 0
      src/util/dbio.rs

+ 1 - 1
Cargo.toml

@@ -33,4 +33,4 @@ env_logger = "0.9.0"
 actix-web-httpauth = "0.6.0"
 lazy_static = "1.4.0"
 syntect = "5.0"
-
+rusqlite = { version = "0.28.0", features = ["bundled"] }

+ 5 - 8
src/endpoints/create.rs

@@ -1,8 +1,8 @@
-use crate::dbio::save_to_file;
 use crate::pasta::PastaFile;
 use crate::util::animalnumbers::to_animal_names;
+use crate::util::dbio::DataStore;
 use crate::util::misc::is_valid_url;
-use crate::{AppState, Pasta, ARGS};
+use crate::{Pasta, ARGS};
 use actix_multipart::Multipart;
 use actix_web::{get, web, Error, HttpResponse, Responder};
 use askama::Template;
@@ -26,7 +26,7 @@ pub async fn index() -> impl Responder {
 }
 
 pub async fn create(
-    data: web::Data<AppState>,
+    data: web::Data<Box<dyn DataStore + Send + Sync>>,
     mut payload: Multipart,
 ) -> Result<HttpResponse, Error> {
     if ARGS.readonly {
@@ -34,8 +34,7 @@ pub async fn create(
             .append_header(("Location", "/"))
             .finish());
     }
-
-    let mut pastas = data.pastas.lock().unwrap();
+    data.remove_expired();
 
     let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) {
         Ok(n) => n.as_secs(),
@@ -137,9 +136,7 @@ pub async fn create(
 
     let id = new_pasta.id;
 
-    pastas.push(new_pasta);
-
-    save_to_file(&pastas);
+    data.create(new_pasta);
 
     Ok(HttpResponse::Found()
         .append_header(("Location", format!("/pasta/{}", to_animal_names(id))))

+ 14 - 15
src/endpoints/pasta.rs

@@ -1,3 +1,5 @@
+use std::sync::Mutex;
+
 use actix_web::{get, web, HttpResponse};
 use askama::Template;
 
@@ -5,6 +7,7 @@ use crate::args::{Args, ARGS};
 use crate::endpoints::errors::ErrorTemplate;
 use crate::pasta::Pasta;
 use crate::util::animalnumbers::to_u64;
+use crate::util::dbio::DataStore;
 use crate::util::misc::remove_expired;
 use crate::AppState;
 
@@ -16,26 +19,22 @@ struct PastaTemplate<'a> {
 }
 
 #[get("/pasta/{id}")]
-pub async fn getpasta(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
-    let mut pastas = data.pastas.lock().unwrap();
+pub async fn getpasta(data: web::Data<Box<dyn DataStore + Send + Sync>>, id: web::Path<String>) -> HttpResponse {
 
     let id = to_u64(&*id.into_inner()).unwrap_or(0);
 
     println!("{}", id);
+    data.remove_expired();
 
-    remove_expired(&mut pastas);
-
-    for pasta in pastas.iter() {
-        if pasta.id == id {
-            return HttpResponse::Ok().content_type("text/html").body(
-                PastaTemplate {
-                    pasta: &pasta,
-                    args: &ARGS,
-                }
-                .render()
-                .unwrap(),
-            );
-        }
+    if let Some(pasta) = data.get_pasta(id) {
+        return HttpResponse::Ok().content_type("text/html").body(
+            PastaTemplate {
+                pasta: &pasta,
+                args: &ARGS,
+            }
+            .render()
+            .unwrap(),
+        );
     }
 
     HttpResponse::Ok()

+ 8 - 5
src/endpoints/pastalist.rs

@@ -1,8 +1,13 @@
+use std::borrow::Borrow;
+use std::sync::Mutex;
+
 use actix_web::{get, web, HttpResponse};
 use askama::Template;
+use lazy_static::__Deref;
 
 use crate::args::{Args, ARGS};
 use crate::pasta::Pasta;
+use crate::util::dbio::DataStore;
 use crate::util::misc::remove_expired;
 use crate::AppState;
 
@@ -14,17 +19,15 @@ struct PastaListTemplate<'a> {
 }
 
 #[get("/pastalist")]
-pub async fn list(data: web::Data<AppState>) -> HttpResponse {
+pub async fn list(data: web::Data<Box<dyn DataStore + Send + Sync>>) -> HttpResponse {
     if ARGS.no_listing {
         return HttpResponse::Found()
             .append_header(("Location", "/"))
             .finish();
     }
 
-    let mut pastas = data.pastas.lock().unwrap();
-
-    remove_expired(&mut pastas);
-
+    data.remove_expired();
+    let pastas = data.get_pastalist();
     HttpResponse::Ok().content_type("text/html").body(
         PastaListTemplate {
             pastas: &pastas,

+ 5 - 1
src/main.rs

@@ -5,7 +5,7 @@ use crate::endpoints::{
     create, edit, errors, help, pasta as pasta_endpoint, pastalist, remove, static_resources,
 };
 use crate::pasta::Pasta;
-use crate::util::dbio;
+use crate::util::dbio::{self, DataStore, JsonStore};
 use actix_web::middleware::Condition;
 use actix_web::{middleware, web, App, HttpServer};
 use actix_web_httpauth::middleware::HttpAuthentication;
@@ -75,9 +75,13 @@ async fn main() -> std::io::Result<()> {
         pastas: Mutex::new(dbio::load_from_file().unwrap()),
     });
 
+    let boxed: Box<dyn DataStore+ Send + Sync> = Box::new(JsonStore::default()) as Box<dyn DataStore+ Send + Sync>;
+    let new_data = web::Data::new(boxed);
+
     HttpServer::new(move || {
         App::new()
             .app_data(data.clone())
+            .app_data(new_data.clone())
             .wrap(middleware::NormalizePath::trim())
             .service(create::index)
             .service(help::help)

+ 2 - 2
src/pasta.rs

@@ -7,12 +7,12 @@ use bytesize::ByteSize;
 use crate::util::animalnumbers::to_animal_names;
 use crate::util::syntaxhighlighter::html_highlight;
 
-#[derive(Serialize, Deserialize, PartialEq, Eq)]
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
 pub struct PastaFile {
     pub name: String, pub size: ByteSize ,
 }
 
-#[derive(Serialize, Deserialize)]
+#[derive(Serialize, Deserialize, Clone)]
 pub struct Pasta {
     pub id: u64,
     pub content: String,

+ 54 - 0
src/util/dbio.rs

@@ -1,9 +1,63 @@
+use std::borrow::{Cow, Borrow};
 use std::fs::File;
 use std::io;
 use std::io::{BufReader, BufWriter};
+use std::sync::Mutex;
+use std::ops::Deref;
+use actix_web::web::Json;
 
 use crate::Pasta;
 
+pub trait DataStore {
+    fn remove_expired(&self);
+    fn edit(&self, id: u64, content: String);
+    fn create(&self, pasta: Pasta);
+    fn get_pasta(&self, id: u64) -> Option<Pasta>;
+    fn get_pastalist(&self) -> Box<dyn Deref<Target=Vec<Pasta>> + '_>;
+}
+
+
+pub struct JsonStore {
+    pub pastas: Mutex<Vec<Pasta>>
+}
+
+impl Default for JsonStore {
+    fn default() -> Self {
+        Self{pastas: Mutex::new(vec!())}
+    }
+}
+
+impl DataStore for JsonStore {
+    fn remove_expired(&self) {
+        
+    }
+
+    fn edit(&self, id: u64, content: String) {
+        todo!()
+    }
+
+    fn create(&self, pasta: Pasta) {
+        let mut pastas = self.pastas.lock().unwrap();
+        pastas.push(pasta);
+        save_to_file(&pastas);
+    }
+
+    fn get_pasta(&self, id: u64) -> Option<Pasta> {
+        let pastas = self.pastas.lock().unwrap();
+        for pasta in pastas.iter() {
+            if pasta.id == id {
+                return Some(pasta.clone());
+            }
+        }
+        None
+    }
+
+    fn get_pastalist(&self) -> Box<dyn Deref<Target=Vec<Pasta>> + '_>{
+        return Box::new(self.pastas.lock().unwrap());
+    }
+}
+
+
 static DATABASE_PATH: &'static str = "pasta_data/database.json";
 
 pub fn save_to_file(pasta_data: &Vec<Pasta>) {