volga 0.9.1

Easy & Fast Web Framework for Rust
Documentation
//! Macros for HTML responses

/// Produces `OK 200` response with HTML body
///
/// # Examples
/// ## Default usage
///```no_run
/// # use volga::HttpRequest;
/// use volga::html;
///
/// # async fn dox(request: HttpRequest) -> std::io::Result<()> {
/// html!(
///    r#"
///    <!doctype html>
///    <html>
///        <head>Hello!</head>
///        <body>
///            <p>Hello, World!</p>
///        </body>
///    </html>
///    "#);
/// # Ok(())
/// # }
#[macro_export]
macro_rules! html {
    ($body:expr) => {
        $crate::html!($body; [])
    };
    ($body:expr; [ $( $header:expr ),* $(,)? ]) => {
        $crate::response!(
            $crate::http::StatusCode::OK,
            $crate::HttpBody::full($body);
            [
                $crate::headers::ContentType::html_utf_8(),
                $( $header ),*
            ]
        )
    };
}

/// Produces `OK 200` response with HTML file body
///
/// # Examples
/// ## Default usage
///```no_run
/// # use volga::HttpRequest;
/// use volga::html_file;
/// use tokio::fs::File;
///
/// # async fn dox(request: HttpRequest) -> std::io::Result<()> {
/// let index_name = "index.html";
/// let index_file = File::open(index_name).await?;
/// html_file!(index_name, index_file);
/// # Ok(())
/// # }
#[macro_export]
macro_rules! html_file {
    ($file_name:expr, $body:expr) => {
        $crate::html_file!($file_name, $body; [])
    };
    ($file_name:expr, $body:expr; [ $( $header:expr ),* $(,)? ]) => {{
        let mime = $crate::fs::get_mime_or_octet_stream($file_name);
        $crate::response!(
            $crate::http::StatusCode::OK,
            $crate::HttpBody::file($body);
            [
                ($crate::headers::CONTENT_TYPE, mime.as_ref()),
                $( $header ),*
            ]
        )
    }};
}

/// Produces `NO CONTENT 204` response
///
/// # Examples
/// ## Default usage
///```no_run
/// # use volga::HttpRequest;
/// use volga::no_content;
///
/// # async fn dox(request: HttpRequest) -> std::io::Result<()> {
/// no_content!();
/// # Ok(())
/// # }
#[macro_export]
macro_rules! no_content {
    () => {
        $crate::response!(
            $crate::http::StatusCode::NO_CONTENT,
            $crate::HttpBody::empty()
        )
    };
}

#[cfg(test)]
mod tests {
    use crate::test::utils::read_file_bytes;
    use http_body_util::BodyExt;

    #[tokio::test]
    async fn it_creates_html_response() {
        let html_text = r#"
            <!doctype html>
            <html>
                <head>Hello!</head>
                <body>
                    <p>Hello, World!</p>
                </body>
            </html>
            "#;

        let response = html!(html_text);

        assert!(response.is_ok());

        let mut response = response.unwrap();
        let body = read_file_bytes(&mut response).await;

        assert_eq!(String::from_utf8_lossy(body.as_slice()), html_text);
        assert_eq!(response.status(), 200);
    }

    #[tokio::test]
    async fn it_creates_html_response_with_headers() {
        let html_text = r#"
            <!doctype html>
            <html>
                <head>Hello!</head>
                <body>
                    <p>Hello, World!</p>
                </body>
            </html>
            "#;

        let response = html!(html_text; [
            ("x-api-key", "some api key")
        ]);

        assert!(response.is_ok());

        let mut response = response.unwrap();
        let body = read_file_bytes(&mut response).await;

        assert_eq!(String::from_utf8_lossy(body.as_slice()), html_text);
        assert_eq!(response.headers()["x-api-key"], "some api key");
        assert_eq!(response.status(), 200);
    }

    #[tokio::test]
    async fn it_creates_no_content_response() {
        let response = no_content!();

        assert!(response.is_ok());

        let mut response = response.unwrap();
        let body = response.body_mut().collect().await.unwrap().to_bytes();

        assert_eq!(body.len(), 0);
        assert_eq!(response.status(), 204);
    }
}