use axum::{response::Response, Router, routing::{post, patch}}; use serde::Deserialize; use crate::types::{extract::{AuthorizedUser, Json, Check, CheckResult}, post::Post, response::ResponseCode}; #[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 } 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_id(body.user_id) 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 fetch posts") }; 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)) }