use axum::{ extract::{Json, Path, State}, http::StatusCode, response::{self, IntoResponse}, }; use crate::{ clock::RequestedAt, conversation::handlers::PathInfo, error::{Internal, NotFound}, message::{ Body, Message, app::{Messages, SendError}, }, token::extract::Identity, }; #[cfg(test)] mod test; pub async fn handler( State(messages): State, Path(conversation): Path, RequestedAt(sent_at): RequestedAt, identity: Identity, Json(request): Json, ) -> Result { let message = 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::Failed(_) => { Internal::from(error).into_response() } } } }