use std::env;
use std::sync::{Arc, RwLock};
use actix_web::{HttpRequest, HttpResponse};
use serde::Serialize;
use tera::{Context, Tera};
use crate::error::Error;
pub trait Render {
fn render(&self, code: usize, template: &str, context: Context) -> std::result::Result<HttpResponse, Error>;
fn json<S: Serialize>(&self, code: usize, payload: S) -> std::result::Result<HttpResponse, Error>;
fn text<S: Serialize>(&self, code: usize, payload: S) -> std::result::Result<HttpResponse, Error>;
fn redirect(&self, location: &str) -> std::result::Result<HttpResponse, Error>;
}
impl Render for HttpRequest {
fn render(
&self,
code: usize,
template: &str,
mut context: Context,
) -> std::result::Result<HttpResponse, Error> {
let data: Option<&Arc<RwLock<Tera>>> = self.app_data();
for (k, v) in env::vars() {
if k.starts_with("JELLY_") {
context.insert(&k, &v);
}
}
if let Some(eng) = data {
let engine = eng.read().map_err(|e| {
Error::Generic(format!("Error acquiring template read lock: {:?}", e))
})?;
let body = engine.render(template, &context).map_err(Error::from)?;
Ok(match code {
200 => HttpResponse::Ok(),
400 => HttpResponse::BadRequest(),
404 => HttpResponse::NotFound(),
_ => HttpResponse::Ok(),
}
.content_type("text/html; charset=utf-8")
.body(body))
} else {
Err(Error::Generic(
"Unable to locate Templates cache".to_string(),
))
}
}
fn json<S: Serialize>(&self, code: usize, payload: S) -> std::result::Result<HttpResponse, Error> {
let o = serde_json::to_string(&payload)?;
Ok(match code {
200 => HttpResponse::Ok(),
400 => HttpResponse::BadRequest(),
404 => HttpResponse::NotFound(),
_ => HttpResponse::Ok(),
}
.content_type("application/json")
.body(o))
}
fn text<S: Serialize>(&self, code: usize, payload: S) -> std::result::Result<HttpResponse, Error> {
let o = serde_json::to_string(&payload)?;
Ok(match code {
200 => HttpResponse::Ok(),
400 => HttpResponse::BadRequest(),
404 => HttpResponse::NotFound(),
_ => HttpResponse::Ok(),
}
.content_type("text/plain")
.body(o))
}
fn redirect(&self, location: &str) -> std::result::Result<HttpResponse, Error> {
Ok(HttpResponse::Found()
.append_header((actix_web::http::header::LOCATION, location))
.finish())
}
}