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