arcly-http 0.2.1

Enterprise-grade NestJS-inspired web framework on axum: zero-lock DI, declarative controllers, multi-tenant data routing, transactional outbox, ABAC, and a self-documenting OpenAPI surface
Documentation
//! Success response shapes beyond `Json<T>`.
//!
//! Each type implements `axum::response::IntoResponse` and is recognised by
//! the route macro's return-type walker so its inner payload type contributes
//! to the OpenAPI response schema and its status code becomes the operation's
//! default success code.

use axum::http::{HeaderValue, StatusCode};
use axum::response::{IntoResponse, Response};
use serde::Serialize;

/// `201 Created` with an optional `Location` header.
pub struct Created<T> {
    pub body: T,
    pub location: Option<&'static str>,
}

impl<T> Created<T> {
    #[inline]
    pub fn new(body: T) -> Self {
        Self {
            body,
            location: None,
        }
    }
    #[inline]
    pub fn at(body: T, location: &'static str) -> Self {
        Self {
            body,
            location: Some(location),
        }
    }
}

impl<T: Serialize> IntoResponse for Created<T> {
    fn into_response(self) -> Response {
        let mut r = (StatusCode::CREATED, axum::Json(self.body)).into_response();
        if let Some(loc) = self.location {
            if let Ok(v) = HeaderValue::from_str(loc) {
                r.headers_mut().insert("Location", v);
            }
        }
        r
    }
}

/// `204 No Content`. Carries no body.
pub struct NoContent;
impl IntoResponse for NoContent {
    fn into_response(self) -> Response {
        StatusCode::NO_CONTENT.into_response()
    }
}

/// `202 Accepted` — for async / queued work.
pub struct Accepted<T>(pub T);
impl<T: Serialize> IntoResponse for Accepted<T> {
    fn into_response(self) -> Response {
        (StatusCode::ACCEPTED, axum::Json(self.0)).into_response()
    }
}