ayun-server 0.23.0

The RUST Framework for Web Rustceans.
Documentation
use crate::response::status_code;
use axum::{http::StatusCode, response::IntoResponse};
use ayun_config::config;
use ayun_core::SharedString;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;

#[derive(Debug, Deserialize, Serialize)]
pub struct Json {
    code: u16,
    success: bool,
    data: serde_json::Value,
    message: Option<SharedString>,
}

impl Default for Json {
    fn default() -> Self {
        Self::new()
    }
}

impl Json {
    fn new() -> Self {
        let status_code = StatusCode::OK;

        Self {
            code: status_code.as_u16(),
            success: status_code.is_success(),
            data: serde_json::Value::Object(Default::default()),
            message: status_code.canonical_reason().map(Cow::Borrowed),
        }
    }

    pub fn code(mut self, code: StatusCode) -> Self {
        self.code = code.as_u16();
        self.success = code.is_success();

        self
    }

    pub fn data<T>(mut self, data: &T) -> Self
    where
        T: Serialize,
    {
        match serde_json::to_value(data) {
            Ok(value) => self.data = value,
            Err(err) => self.message = Some(Cow::from(err.to_string())),
        }

        self
    }

    pub fn message(mut self, message: impl Into<SharedString>) -> Self {
        self.message = Some(message.into());

        self
    }

    #[cfg(feature = "database")]
    pub fn paginate(
        mut self,
        page: u64,
        limit: u64,
        items: Vec<serde_json::Value>,
        items_and_pages: sea_orm::ItemsAndPagesNumber,
    ) -> Self {
        self.data = serde_json::json!({
            "items": items,
            "per_page": limit,
            "current_page": page,
            "total": items_and_pages.number_of_items,
            "total_pages": items_and_pages.number_of_pages,
        });

        self
    }
}

impl IntoResponse for Json {
    fn into_response(self) -> axum::response::Response {
        let server = config::<crate::config::Server>("server").unwrap_or_default();

        let status_code = match server.response.strict {
            true => status_code(self.code),
            false => StatusCode::OK,
        };

        (status_code, axum::Json(self)).into_response()
    }
}