rocket_include_tera/debug/
tera_response.rs1use 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)]
18pub 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}