use axum::{ response::Response, routing::{patch, post}, Router, }; use serde::Deserialize; use crate::types::{ extract::{AuthorizedUser, Check, CheckResult, Json}, http::ResponseCode, post::Post, }; #[derive(Deserialize)] struct PostCreateRequest { content: String, } impl Check for PostCreateRequest { fn check(&self) -> CheckResult { Self::assert_length( &self.content, 1, 500, "Comments must be between 1-500 characters long", )?; Ok(()) } } async fn create( AuthorizedUser(user): AuthorizedUser, Json(body): Json, ) -> Response { let Ok(post) = Post::new(user.user_id, body.content) else { return ResponseCode::InternalServerError.text("Failed to create post") }; let Ok(json) = serde_json::to_string(&post) else { return ResponseCode::InternalServerError.text("Failed to create post") }; ResponseCode::Created.json(&json) } #[derive(Deserialize)] struct PostPageRequest { page: u64, } impl Check for PostPageRequest { fn check(&self) -> CheckResult { Ok(()) } } async fn page( AuthorizedUser(_user): AuthorizedUser, Json(body): Json, ) -> Response { let Ok(posts) = Post::from_post_page(body.page) else { return ResponseCode::InternalServerError.text("Failed to fetch posts") }; let Ok(json) = serde_json::to_string(&posts) else { return ResponseCode::InternalServerError.text("Failed to fetch posts") }; ResponseCode::Success.json(&json) } #[derive(Deserialize)] struct UsersPostsRequest { user_id: u64, page: u64 } impl Check for UsersPostsRequest { fn check(&self) -> CheckResult { Ok(()) } } async fn user( AuthorizedUser(_user): AuthorizedUser, Json(body): Json, ) -> Response { let Ok(posts) = Post::from_user_post_page(body.user_id, body.page) else { return ResponseCode::InternalServerError.text("Failed to fetch posts") }; let Ok(json) = serde_json::to_string(&posts) else { return ResponseCode::InternalServerError.text("Failed to fetch posts") }; ResponseCode::Success.json(&json) } #[derive(Deserialize)] struct PostCommentRequest { content: String, post_id: u64, } impl Check for PostCommentRequest { fn check(&self) -> CheckResult { Self::assert_length( &self.content, 1, 255, "Comments must be between 1-255 characters long", )?; Ok(()) } } async fn comment( AuthorizedUser(user): AuthorizedUser, Json(body): Json, ) -> Response { let Ok(mut post) = Post::from_post_id(body.post_id) else { return ResponseCode::InternalServerError.text("Failed to add comment") }; if let Err(err) = post.comment(user.user_id, body.content) { return err; } ResponseCode::Success.text("Successfully commented on post") } #[derive(Deserialize)] struct PostLikeRequest { state: bool, post_id: u64, } impl Check for PostLikeRequest { fn check(&self) -> CheckResult { Ok(()) } } async fn like(AuthorizedUser(user): AuthorizedUser, Json(body): Json) -> Response { let Ok(mut post) = Post::from_post_id(body.post_id) else { return ResponseCode::InternalServerError.text("Failed to fetch posts") }; if let Err(err) = post.like(user.user_id, body.state) { return err; } ResponseCode::Success.text("Successfully changed like status on post") } pub fn router() -> Router { Router::new() .route("/create", post(create)) .route("/page", post(page)) .route("/user", post(user)) .route("/comment", patch(comment)) .route("/like", patch(like)) }