credence_lib/render/
context.rs1use super::{
2 super::{configuration::*, middleware::*},
3 constants::*,
4 default_preparer::*,
5 preparer::*,
6 rendered_page::*,
7 renderer::*,
8 templates::*,
9};
10
11use {
12 ::axum::{
13 http::{header::*, *},
14 response::Response,
15 },
16 bytestring::*,
17 compris::{normal::*, ser::*, *},
18 httpdate::*,
19 kutil_http::*,
20 kutil_std::collections::*,
21 std::result::Result,
22};
23
24#[derive(Debug)]
26pub struct RenderContext<'own> {
27 pub rendered_page: &'own RenderedPage,
29
30 pub variables: FastHashMap<ByteString, Value>,
32
33 pub socket: Option<Socket>,
35
36 pub uri_path: ByteString,
38
39 pub original_uri_path: Option<ByteString>,
41
42 pub last_modified: Option<HttpDate>,
44
45 pub is_json: (bool, bool),
47
48 pub renderer: Renderer,
50
51 pub templates: &'own Templates,
53
54 pub configuration: &'own CredenceConfiguration,
56}
57
58impl<'own> RenderContext<'own> {
59 pub fn new(
61 rendered_page: &'own RenderedPage,
62 variables: FastHashMap<ByteString, Value>,
63 socket: Option<Socket>,
64 uri_path: ByteString,
65 original_uri_path: Option<ByteString>,
66 last_modified: Option<HttpDate>,
67 is_json: (bool, bool),
68 renderer: Renderer,
69 templates: &'own Templates,
70 configuration: &'own CredenceConfiguration,
71 ) -> Self {
72 Self {
73 rendered_page,
74 variables,
75 socket,
76 uri_path,
77 original_uri_path,
78 last_modified,
79 is_json,
80 renderer,
81 templates,
82 configuration,
83 }
84 }
85
86 pub async fn prepare<PreparerT>(&mut self, preparer: PreparerT) -> Result<(), StatusCode>
88 where
89 PreparerT: RenderPreparer,
90 {
91 preparer.prepare(self).await
92 }
93
94 pub async fn prepare_default(&mut self) -> Result<(), StatusCode> {
96 self.prepare(DefaultRenderedPageHandler).await
97 }
98
99 pub async fn into_response(self) -> Result<Response, StatusCode> {
101 let template = self.rendered_page.annotations.template(&self.configuration.render);
102 let html = self.templates.render(template, &self.variables).await?;
103 let mut headers = self.rendered_page.merged_headers()?;
104
105 if let Some(last_modified) = &self.last_modified {
106 headers
107 .set_string_value(LAST_MODIFIED, &last_modified.to_string())
108 .map_err_internal_server("set Last-Modified")?;
109 }
110
111 if self.is_json.0 {
112 let json = self.into_json()?;
113 response_from_bytes(json.into_bytes(), JSON_MEDIA_TYPE_STRING, headers)
114 } else {
115 response_from_bytes(html.into_bytes(), HTML_MEDIA_TYPE_STRING, headers)
116 }
117 }
118
119 fn into_json(self) -> Result<ByteString, StatusCode> {
120 Serializer::new(Format::JSON)
121 .with_pretty(self.is_json.1)
122 .stringify_modal(&self.variables_into_value(), &SerializationMode::for_json())
123 .map_err_internal_server("serialize JSON")
124 }
125
126 fn variables_into_value(self) -> Value {
127 self.variables.into_iter().map(|(key, value)| (key.into(), value.clone())).collect()
128 }
129}