use crate::types::{AppState, NewPost, Post}; use actix_web::web::{Data, Path}; use actix_web::{get, post, web::Json, HttpResponse, Responder}; use log::*; use serde::{Deserialize, Serialize}; use uuid::Uuid; #[get("/")] pub async fn get_posts(data: Data) -> impl Responder { match data.posts.lock() { Ok(posts) => { let posts: Vec = posts.values().cloned().collect(); HttpResponse::Ok().json(posts) } Err(e) => { warn!("Error: {:?}", e); HttpResponse::InternalServerError().body("Error") } } } #[post("/")] pub async fn new_post(new_post: Json, data: Data) -> impl Responder { let post = Post::from(new_post.into_inner()); info!("Created post {:?}", post.uuid); match data.posts.lock() { Ok(mut posts) => { posts.insert(post.uuid, post); } Err(e) => { warn!("Error: {:?}", e); } }; HttpResponse::Ok().json("Post added!") } // This is a test route, returns "Hello, world!" #[get("/test")] pub async fn test(data: Data) -> impl Responder { match data.posts.lock() { Ok(posts) => { let posts: Vec = posts.values().cloned().collect(); HttpResponse::Ok().body(format!("Hello, world! {:?}", posts)) } Err(e) => { warn!("Error: {:?}", e); HttpResponse::InternalServerError().body("Error") } } } #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum VoteDirection { Up, Down, Unupvote, Undownvote, } #[post("vote/{uuid}/{direction}")] pub async fn vote(params: Path<(Uuid, VoteDirection)>, data: Data) -> impl Responder { let (uuid, direction) = params.into_inner(); println!("Voting {:?} on post {:?}", direction, uuid); match data.posts.lock() { Ok(mut posts) => { let uuid = uuid; if let Some(post) = posts.get_mut(&uuid) { match direction { VoteDirection::Up => post.votes.up += 1, VoteDirection::Unupvote => post.votes.up -= 1, VoteDirection::Down => post.votes.down += 1, VoteDirection::Undownvote => post.votes.down -= 1, } HttpResponse::Ok().body("Downvoted!") } else { HttpResponse::NotFound().body("Post not found!") } } Err(e) => { warn!("Error: {:?}", e); HttpResponse::InternalServerError().body("Error") } } }