shrike 0.1.1

AT Protocol library for Rust
Documentation
use axum::Json;
use axum::response::{IntoResponse, Response};
use http::StatusCode;
use serde_json::json;

/// XRPC server errors that map to standard HTTP status codes.
///
/// Implements `IntoResponse` to produce JSON error bodies matching the
/// AT Protocol XRPC error format: `{"error": "...", "message": "..."}`.
#[derive(Debug, thiserror::Error)]
pub enum ServerError {
    #[error("auth required")]
    AuthRequired,
    #[error("forbidden")]
    Forbidden,
    #[error("not found")]
    NotFound,
    #[error("method not allowed")]
    MethodNotAllowed,
    #[error("payload too large")]
    TooLarge,
    #[error("rate limited")]
    RateLimited {
        retry_after: Option<std::time::Duration>,
    },
    #[error("internal error: {0}")]
    Internal(String),
}

impl IntoResponse for ServerError {
    fn into_response(self) -> Response {
        let (status, error_name) = match &self {
            ServerError::AuthRequired => (StatusCode::UNAUTHORIZED, "AuthRequired"),
            ServerError::Forbidden => (StatusCode::FORBIDDEN, "Forbidden"),
            ServerError::NotFound => (StatusCode::NOT_FOUND, "NotFound"),
            ServerError::MethodNotAllowed => (StatusCode::METHOD_NOT_ALLOWED, "MethodNotAllowed"),
            ServerError::TooLarge => (StatusCode::PAYLOAD_TOO_LARGE, "TooLarge"),
            ServerError::RateLimited { .. } => (StatusCode::TOO_MANY_REQUESTS, "RateLimited"),
            ServerError::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "InternalError"),
        };
        let body = json!({"error": error_name, "message": self.to_string()});
        (status, Json(body)).into_response()
    }
}