lib-humus 0.5.0

Helps creating configurable frontends for humans and computers using axum, Tera and toml.
use axum::http::status::StatusCode;
use axum::response::IntoResponse;
use axum::response::Json;
use axum::response::Response;
use serde::Serialize;

use crate::HumusFormat;
use crate::HumusQuerySettings;

/// 👁 Provides data and logic for the [HumusEngine] and
/// knows how to put information together.
///
/// It is recommended to implement this as an enum carrying additional information.
///
/// 💡Also have a look at the provided methods, while they may be sane defaults
/// they are probably not always the desired behavior.
///
/// [HumusEngine]: ./struct.HumusEngine.html
pub trait HumusView<S, F>: Serialize + Sized
where
    S: HumusQuerySettings<F>,
    F: HumusFormat,
{
    /// Returns the template name that will be used to select
    /// the template file.
    ///
    /// If the name is "404" for an html response the template
    /// file "404.html" will be used.
    ///
    /// Also ends up as the `view` variable in the template.
    /// Example:
    /// ```rust,ignore
    /// fn get_template_name(&self) -> String {
    /// 	match self {
    /// 		Self::Index{..} => "index",
    /// 		Self::Results{..} => "results",
    /// 		Self::NotFound => "404",
    /// 		Self::InternalError{..} => "500",
    /// 	}.to_string()
    /// }
    /// ```
    fn get_template_name(&self) -> String;

    /// Returns the reponse code for the view.
    ///
    /// The numeric value will be useable as `http_status` in the template.
    ///
    /// Example:
    /// ```rust,ignore
    /// use axum::http::StatusCode;
    ///
    /// fn get_status_code(&self, settings: &SomeSettings) -> StatusCode {
    /// 	match self {
    /// 		Self::NotFound => StatusCode::NOT_FOUND,
    /// 		Self::InternalError{..} => StatusCode::INTERNAL_SERVER_ERROR,
    /// 		_ => StatusCode::OK,
    /// 	}
    /// }
    /// ```
    fn get_status_code(&self, settings: &S) -> StatusCode;

    /// If this returns a String it will be used as the cookie header.
    ///
    /// Only available when the `axum-view+cookie` feature is enabled.
    ///
    /// See: [axum: Constructing a Cookie](https://docs.rs/axum-extra/0.8.0/axum_extra/extract/cookie/struct.Cookie.html#constructing-a-cookie)
    ///
    /// ⚠️ *Warning:* When setting cookies in the
    ///              `update_response()` or `get_api_response()`
    ///              this should return `None`, otherise you are in
    ///              undefined behavior territory.
    #[cfg(feature = "axum-view+cookie")]
    fn get_cookie_header(&self, _settings: &S) -> Option<String> {
        None
    }

    /// Update non-API responses after they have been built.
    ///
    /// Useful for setting extra headers. Does noting by default.
    fn update_response(&self, _response: &mut Response, _settings: &S) {}

    /// Return an API-Response
    ///
    /// By default causes the view to Serialize itself
    /// to a json response using serde.
    ///
    /// Response code and cookie headers are queried in
    /// advance and set on the reulting response if it has a status code of 200.
    /// Otherwise it is assumed that the response genrating logic
    /// alredy took care of that.
    ///
    /// You'll need the following imports when implementing:
    /// ```
    /// use axum::Json;
    /// use axum::response::IntoResponse;
    /// ```
    fn get_api_response(self, _settings: &S) -> Response {
        Json(self).into_response()
    }
}