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:    String,
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(), etag: etag.to_string()
32            }),
33        }
34    }
35
36    #[doc(hidden)]
37    #[inline]
38    pub const fn not_modified() -> TeraResponse {
39        TeraResponse {
40            inner: None
41        }
42    }
43
44    #[doc(hidden)]
45    #[inline]
46    pub fn weak_eq(&self, etag_if_none_match: &EtagIfNoneMatch<'_>) -> bool {
47        self.inner
48            .as_ref()
49            .map(|inner| {
50                etag_if_none_match.weak_eq(unsafe {
51                    &EntityTag::with_str_unchecked(false, &inner.etag[1..(inner.etag.len() - 1)])
52                })
53            })
54            .unwrap_or(false)
55    }
56}
57
58impl<'r, 'o: 'r> Responder<'r, 'o> for TeraResponse {
59    #[inline]
60    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
61        let mut response = Response::build();
62
63        if let Some(inner) = self.inner {
64            response.raw_header("Content-Type", "text/html; charset=utf-8");
65            response.raw_header("Etag", inner.etag);
66
67            response.sized_body(inner.content.len(), Cursor::new(inner.content));
68        } else {
69            response.status(Status::NotModified);
70        }
71
72        response.ok()
73    }
74}