From 49433399647a3e6adef22312e7c765925b4f98fb Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 23 Dec 2023 03:14:18 +0100 Subject: [PATCH] feat: richer guest page rows --- src/model.rs | 13 ++++++++++++- src/notifications/console.rs | 10 +++++----- src/routes.rs | 22 +++++++++++----------- src/storage.rs | 12 ++++++------ 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/model.rs b/src/model.rs index 4615b8f..9b38d9b 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,7 +1,18 @@ use serde::{Serialize, Deserialize}; +use chrono::{DateTime, Utc}; #[derive(Debug, Clone, Default, Serialize, Deserialize)] -pub struct Suggestion { +pub struct GuestBookPage { + pub author: Option, + pub contact: Option, + pub body: String, + pub date: DateTime, + pub avatar: String, + pub url: Option, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct Insertion { pub author: Option, pub contact: Option, pub body: String, diff --git a/src/notifications/console.rs b/src/notifications/console.rs index c4c64cc..bc6e6be 100644 --- a/src/notifications/console.rs +++ b/src/notifications/console.rs @@ -1,4 +1,4 @@ -use crate::model::Suggestion; +use crate::model::GuestBookPage; use super::NotificationProcessor; @@ -6,8 +6,8 @@ use super::NotificationProcessor; pub struct ConsoleTracingNotifier {} #[async_trait::async_trait] -impl NotificationProcessor for ConsoleTracingNotifier { - async fn process(&self, suggestion: &Suggestion) { +impl NotificationProcessor for ConsoleTracingNotifier { + async fn process(&self, suggestion: &GuestBookPage) { tracing::info!(" >> {:?}", suggestion); } } @@ -15,8 +15,8 @@ impl NotificationProcessor for ConsoleTracingNotifier { pub struct ConsolePrettyNotifier {} #[async_trait::async_trait] -impl NotificationProcessor for ConsolePrettyNotifier { - async fn process(&self, suggestion: &Suggestion) { +impl NotificationProcessor for ConsolePrettyNotifier { + async fn process(&self, suggestion: &GuestBookPage) { println!("{} -- {} <{}>", suggestion.body, suggestion.author.as_deref().unwrap_or("anon"), suggestion.contact.as_deref().unwrap_or("")); } } diff --git a/src/routes.rs b/src/routes.rs index 65ac2f7..3fad4b0 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use axum::{http::StatusCode, Json, Form, Router, routing::{put, post, get}, extract::{State, Query}, response::IntoResponse}; use tokio::sync::RwLock; -use crate::{notifications::NotificationProcessor, model::{Suggestion, Acknowledgement, PageOptions}, storage::StorageStrategy}; +use crate::{notifications::NotificationProcessor, model::{GuestBookPage, Acknowledgement, PageOptions, Insertion}, storage::StorageStrategy}; pub fn create_router_with_app_routes(state: Context) -> Router { Router::new() @@ -16,21 +16,21 @@ pub fn create_router_with_app_routes(state: Context) -> Router { type SafeContext = Arc>; pub struct Context { - providers: Vec>>, - storage: Box>, + providers: Vec>>, + storage: Box>, } impl Context { - pub fn new(storage: Box>) -> Self { + pub fn new(storage: Box>) -> Self { Context { providers: Vec::new(), storage } } - pub fn register(mut self, notifier: Box>) -> Self { + pub fn register(mut self, notifier: Box>) -> Self { self.providers.push(notifier); self } - async fn process(&self, x: &Suggestion) { + async fn process(&self, x: &GuestBookPage) { for p in self.providers.iter() { p.process(x).await; } @@ -39,18 +39,18 @@ impl Context { async fn send_suggestion(payload: Suggestion, state: SafeContext) -> impl IntoResponse { let mut lock = state.write().await; - lock.process(&payload).await; - match lock.storage.archive(payload).await { + lock.process(&page).await; + match lock.storage.archive(page).await { Ok(()) => (StatusCode::OK, Json(Acknowledgement::Sent("".into()))), Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, Json(Acknowledgement::Refused(e.to_string()))), } } -async fn send_suggestion_json(State(state): State, Json(payload): Json) -> impl IntoResponse { send_suggestion(payload, state).await } -async fn send_suggestion_form(State(state): State, Form(payload): Form) -> impl IntoResponse { send_suggestion(payload, state).await } +async fn send_suggestion_json(State(state): State, Json(payload): Json) -> impl IntoResponse { send_suggestion(payload, state).await } +async fn send_suggestion_form(State(state): State, Form(payload): Form) -> impl IntoResponse { send_suggestion(payload, state).await } -async fn get_suggestion(State(state): State, Query(page): Query) -> Result>, String> { +async fn get_suggestion(State(state): State, Query(page): Query) -> Result>, String> { let offset = page.offset.unwrap_or(0); let limit = std::cmp::min(page.limit.unwrap_or(20), 20); diff --git a/src/storage.rs b/src/storage.rs index 7c71e95..b27ee94 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,4 +1,4 @@ -use crate::model::Suggestion; +use crate::model::GuestBookPage; #[derive(Debug, thiserror::Error)] @@ -30,19 +30,19 @@ impl JsonFileStorageStrategy { #[async_trait::async_trait] -impl StorageStrategy for JsonFileStorageStrategy { - async fn archive(&mut self, payload: Suggestion) -> Result<(), StorageStrategyError> { +impl StorageStrategy for JsonFileStorageStrategy { + async fn archive(&mut self, payload: GuestBookPage) -> Result<(), StorageStrategyError> { let file_content = std::fs::read_to_string(&self.path)?; - let mut current_content : Vec = serde_json::from_str(&file_content)?; + let mut current_content : Vec = serde_json::from_str(&file_content)?; current_content.push(payload); let updated_content = serde_json::to_string(¤t_content)?; std::fs::write(&self.path, updated_content)?; Ok(()) } - async fn extract(&self, offset: usize, window: usize) -> Result, StorageStrategyError> { + async fn extract(&self, offset: usize, window: usize) -> Result, StorageStrategyError> { let file_content = std::fs::read_to_string(&self.path)?; - let current_content : Vec = serde_json::from_str(&file_content)?; + let current_content : Vec = serde_json::from_str(&file_content)?; let mut out = Vec::new(); for sugg in current_content.iter().rev().skip(offset) { out.push(sugg.clone());