use axum::{ extract::{Json, State}, http::StatusCode, response::{self, IntoResponse}, }; use crate::{ clock::RequestedAt, conversation::{Conversation, app, app::Conversations}, error::Internal, name::Name, token::extract::Identity, }; #[cfg(test)] mod test; pub async fn handler( State(conversations): State, _: Identity, // requires auth, but doesn't actually care who you are RequestedAt(created_at): RequestedAt, Json(request): Json, ) -> Result { let conversation = conversations .create(&request.name, &created_at) .await .map_err(Error)?; Ok(Response(conversation)) } #[derive(serde::Deserialize)] pub struct Request { pub name: Name, } #[derive(Debug)] pub struct Response(pub Conversation); impl IntoResponse for Response { fn into_response(self) -> response::Response { let Self(conversation) = self; (StatusCode::ACCEPTED, Json(conversation)).into_response() } } #[derive(Debug)] pub struct Error(pub app::CreateError); impl IntoResponse for Error { fn into_response(self) -> response::Response { let Self(error) = self; match error { app::CreateError::DuplicateName(_) => { (StatusCode::CONFLICT, error.to_string()).into_response() } app::CreateError::InvalidName(_) => { (StatusCode::BAD_REQUEST, error.to_string()).into_response() } app::CreateError::Name(_) | app::CreateError::Database(_) => { Internal::from(error).into_response() } } } }