use axum::{ extract::{Json, Path, State}, http::StatusCode, response::{self, IntoResponse}, }; use crate::{ app::App, clock::RequestedAt, conversation::handlers::PathInfo, error::{Internal, NotFound}, message::{Body, Message, app::SendError}, token::extract::Identity, }; #[cfg(test)] mod test; pub async fn handler( State(app): State, Path(conversation): Path, RequestedAt(sent_at): RequestedAt, identity: Identity, Json(request): Json, ) -> Result { let message = app .messages() .send(&conversation, &identity.login, &sent_at, &request.body) .await?; Ok(Response(message)) } #[derive(serde::Deserialize)] pub struct Request { pub body: Body, } #[derive(Debug)] pub struct Response(pub Message); impl IntoResponse for Response { fn into_response(self) -> response::Response { let Self(message) = self; (StatusCode::ACCEPTED, Json(message)).into_response() } } #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct Error(#[from] pub SendError); impl IntoResponse for Error { fn into_response(self) -> response::Response { let Self(error) = self; match error { SendError::ConversationNotFound(_) | SendError::ConversationDeleted(_) => { NotFound(error).into_response() } SendError::SenderNotFound(_) | SendError::SenderDeleted(_) | SendError::Name(_) | SendError::Database(_) => Internal::from(error).into_response(), } } }