use super::{
super::{configuration::*, middleware::*},
constants::*,
default_preparer::*,
preparer::*,
rendered_page::*,
renderer::*,
templates::*,
};
use {
::axum::{
http::{header::*, *},
response::Response,
},
compris::{annotate::*, normal::*, ser::*, *},
httpdate::*,
kutil::{
http::*,
std::{collections::*, immutable::*},
},
std::result::Result,
};
#[derive(Debug)]
pub struct RenderContext<'own> {
pub rendered_page: &'own RenderedPage,
pub variables: FastHashMap<ByteString, Variant<WithAnnotations>>,
pub socket: Option<Socket>,
pub uri_path: ByteString,
pub original_uri_path: Option<ByteString>,
pub query: Option<QueryMap>,
pub last_modified: Option<HttpDate>,
pub is_json: (bool, bool),
pub renderer: Renderer,
pub templates: &'own Templates,
pub configuration: &'own CredenceConfiguration,
}
impl<'own> RenderContext<'own> {
pub fn new(
rendered_page: &'own RenderedPage,
variables: FastHashMap<ByteString, Variant<WithAnnotations>>,
socket: Option<Socket>,
uri_path: ByteString,
original_uri_path: Option<ByteString>,
query: Option<QueryMap>,
last_modified: Option<HttpDate>,
is_json: (bool, bool),
renderer: Renderer,
templates: &'own Templates,
configuration: &'own CredenceConfiguration,
) -> Self {
Self {
rendered_page,
variables,
socket,
uri_path,
original_uri_path,
query,
last_modified,
is_json,
renderer,
templates,
configuration,
}
}
pub async fn prepare<PreparerT>(&mut self, preparer: PreparerT) -> Result<(), StatusCode>
where
PreparerT: RenderPreparer,
{
preparer.prepare(self).await
}
pub async fn prepare_default(&mut self) -> Result<(), StatusCode> {
self.prepare(DefaultRenderedPageHandler).await
}
pub async fn into_response(self) -> Result<Response, StatusCode> {
let template = self.rendered_page.annotations.template(&self.configuration.render);
let html = self.templates.render(template, &self.variables).await?;
let mut headers = self.rendered_page.merged_headers()?;
if let Some(last_modified) = &self.last_modified {
headers
.set_string_value(LAST_MODIFIED, &last_modified.to_string())
.map_err_internal_server("set Last-Modified")?;
}
if self.is_json.0 {
let json = self.into_json()?;
response_from_bytes(json.into_bytes(), JSON_MEDIA_TYPE_STRING, headers)
} else {
response_from_bytes(html.into_bytes(), HTML_MEDIA_TYPE_STRING, headers)
}
}
fn into_json(self) -> Result<ByteString, StatusCode> {
Serializer::new(Format::JSON)
.with_pretty(self.is_json.1)
.stringify_modal(&self.variables_into_variant(), &SerializationMode::for_json())
.map_err_internal_server("serialize JSON")
}
fn variables_into_variant(self) -> Variant<WithAnnotations> {
self.variables.into_iter().map(|(key, value)| (key.into(), value.clone())).collect()
}
}