use std::sync::Arc;
use axum::body::Bytes;
use axum::extract::{Path, State};
use axum::http::HeaderMap;
use axum::response::IntoResponse;
use axum::routing::post;
use axum::Router;
use crate::context::ActionContext;
use crate::error::ActionError;
use crate::registry::ActionRegistry;
pub fn action_router(registry: ActionRegistry) -> Router {
let registry = Arc::new(registry);
Router::new()
.route("/_action/:name", post(dispatch))
.with_state(registry)
}
async fn dispatch(
State(registry): State<Arc<ActionRegistry>>,
Path(name): Path<String>,
headers: HeaderMap,
body: Bytes,
) -> impl IntoResponse {
let handler = match registry.get(&name) {
Some(h) => h,
None => return ActionError::NotFound.into_response(),
};
let context = ActionContext::new(headers);
match handler.invoke(context, body).await {
Ok(bytes) => axum::response::Response::builder()
.header("content-type", "application/json")
.body(axum::body::Body::from(bytes))
.unwrap(),
Err(e) => e.into_response(),
}
}