use std::sync::Arc;
use axum::{Json, extract::State, http::StatusCode, response::IntoResponse};
use serde::{Deserialize, Serialize};
use crate::subscriptions::BroadcastManager;
#[derive(Clone)]
pub struct BroadcastState {
manager: Arc<BroadcastManager>,
}
impl BroadcastState {
#[must_use]
pub const fn new(manager: Arc<BroadcastManager>) -> Self {
Self { manager }
}
}
#[derive(Debug, Deserialize)]
pub struct BroadcastRequest {
pub channel: String,
pub event: String,
pub payload: serde_json::Value,
}
#[derive(Debug, Serialize)]
pub struct BroadcastResponse {
pub receivers: usize,
}
pub async fn broadcast_handler(
State(state): State<BroadcastState>,
Json(req): Json<BroadcastRequest>,
) -> impl IntoResponse {
if req.channel.is_empty() {
return (
StatusCode::BAD_REQUEST,
Json(serde_json::json!({"error": "channel must not be empty"})),
)
.into_response();
}
if req.event.is_empty() {
return (
StatusCode::BAD_REQUEST,
Json(serde_json::json!({"error": "event must not be empty"})),
)
.into_response();
}
match state.manager.publish(&req.channel, req.event, req.payload).await {
Ok(receivers) => (StatusCode::OK, Json(BroadcastResponse { receivers })).into_response(),
Err(e) => {
let status =
StatusCode::from_u16(e.status_code()).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
(status, Json(serde_json::json!({"error": e.to_string()}))).into_response()
},
}
}