Skip to main content

rocket_include_tera/debug/
tera_response.rs

1use std::io::Cursor;
2
3use rocket::{
4    http::Status,
5    request::Request,
6    response::{self, Responder, Response},
7};
8
9use crate::{EntityTag, EtagIfNoneMatch};
10
11#[derive(Debug)]
12struct TeraResponseInner {
13    content: String,
14    etag:    EntityTag<'static>,
15}
16
17#[derive(Debug)]
18/// To respond HTML.
19pub struct TeraResponse {
20    inner: Option<TeraResponseInner>,
21}
22
23impl TeraResponse {
24    #[inline]
25    pub(crate) fn build_not_cache<S: Into<String>>(
26        content: S,
27        etag: EntityTag<'static>,
28    ) -> TeraResponse {
29        TeraResponse {
30            inner: Some(TeraResponseInner {
31                content: content.into(),
32                etag,
33            }),
34        }
35    }
36
37    #[doc(hidden)]
38    #[inline]
39    pub const fn not_modified() -> TeraResponse {
40        TeraResponse {
41            inner: None
42        }
43    }
44
45    #[doc(hidden)]
46    #[inline]
47    pub fn weak_eq(&self, etag_if_none_match: &EtagIfNoneMatch<'_>) -> bool {
48        self.inner.as_ref().is_some_and(|inner| etag_if_none_match.weak_eq(&inner.etag))
49    }
50}
51
52impl<'r, 'o: 'r> Responder<'r, 'o> for TeraResponse {
53    #[inline]
54    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
55        let mut response = Response::build();
56
57        if let Some(inner) = self.inner {
58            response.raw_header("Content-Type", "text/html; charset=utf-8");
59            response.raw_header("Etag", inner.etag.to_string());
60
61            response.sized_body(inner.content.len(), Cursor::new(inner.content));
62        } else {
63            response.status(Status::NotModified);
64        }
65
66        response.ok()
67    }
68}