limiting_factor_axum/api/replies.rs
1/* -------------------------------------------------------------
2 Limiting Factor :: axum :: API :: replies
3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4 Project: Nasqueron
5 License: BSD-2-Clause
6 ------------------------------------------------------------- */
7
8//! # API standard and JSON responses.
9//!
10//! This module provides useful traits and methods to craft API replies from an existing type.
11
12use axum::http::StatusCode;
13use axum::Json;
14
15#[cfg(feature = "serialization")]
16use serde::Serialize;
17
18/* -------------------------------------------------------------
19 JSON responses
20 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
21
22pub type ApiJsonResponse<T> = Result<Json<T>, (StatusCode, Json<String>)>;
23
24/// This trait allows to consume an object into an HTTP response.
25pub trait ApiResponse<T> {
26 /// Consumes the value and creates a JSON or a Status result response.
27 fn into_json_response(self) -> ApiJsonResponse<T>;
28}
29
30impl<T> ApiResponse<T> for Json<T> {
31 fn into_json_response(self) -> ApiJsonResponse<T> {
32 Ok(self)
33 }
34}
35
36#[cfg(feature = "serialization")]
37impl<T> ApiResponse<T> for T where T: Serialize {
38 fn into_json_response(self) -> ApiJsonResponse<T> {
39 Ok(Json(self))
40 }
41}
42
43// -------------------------------------------------------------
44// Failures
45// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
46
47pub trait FailureResponse {
48 fn status_code(&self) -> StatusCode;
49
50 fn response(&self) -> String;
51}
52
53impl<T, E> ApiResponse<T> for Result<T, E>
54 where T: ApiResponse<T>, E: FailureResponse
55{
56 fn into_json_response(self) -> ApiJsonResponse<T> {
57 match self {
58 Ok(value) => value.into_json_response(),
59 Err(error) => Err((error.status_code(), Json(error.response())))
60 }
61 }
62}