mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2024-12-29 13:07:10 +01:00
112 lines
2.5 KiB
Rust
112 lines
2.5 KiB
Rust
|
/*
|
||
|
* This is the echoip-slatecave templating engine.
|
||
|
* It wraps around tera in is specialized for echoip-slatecave.
|
||
|
*/
|
||
|
|
||
|
use axum::{
|
||
|
http::StatusCode,
|
||
|
response::Html,
|
||
|
response::IntoResponse,
|
||
|
response::Response,
|
||
|
response::Json,
|
||
|
};
|
||
|
use tera::Tera;
|
||
|
|
||
|
use crate::simple_dns;
|
||
|
use crate::IpResult;
|
||
|
use crate::IpQuery;
|
||
|
use crate::DigQuery;
|
||
|
|
||
|
/* Response format */
|
||
|
|
||
|
#[derive(serde::Deserialize, serde::Serialize, Clone, Copy)]
|
||
|
pub enum ResponseFormat {
|
||
|
#[serde(rename="text/plain", alias="text")]
|
||
|
TextPlain,
|
||
|
#[serde(rename="text/html", alias="html")]
|
||
|
TextHtml,
|
||
|
#[serde(rename="application/json", alias="json")]
|
||
|
ApplicationJson,
|
||
|
}
|
||
|
|
||
|
impl ToString for ResponseFormat {
|
||
|
fn to_string(&self) -> String {
|
||
|
match self {
|
||
|
ResponseFormat::TextPlain => "text/plain",
|
||
|
ResponseFormat::TextHtml => "text/html",
|
||
|
ResponseFormat::ApplicationJson => "application/json",
|
||
|
}.to_string()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* The echoip view */
|
||
|
|
||
|
#[derive(serde::Deserialize, serde::Serialize)]
|
||
|
#[serde(untagged)]
|
||
|
pub enum View {
|
||
|
Dig { query: DigQuery, result: simple_dns::DnsLookupResult },
|
||
|
Index { query: IpQuery, result: IpResult },
|
||
|
Ip { query: IpQuery, result: IpResult },
|
||
|
Message(String),
|
||
|
#[serde(rename="404")]
|
||
|
NotFound,
|
||
|
}
|
||
|
|
||
|
impl View {
|
||
|
pub fn template_name(&self) -> String {
|
||
|
match self {
|
||
|
View::Dig{..} => "dig",
|
||
|
View::Index{..} => "index",
|
||
|
View::Ip{..} => "ip",
|
||
|
View::Message(..) => "message",
|
||
|
View::NotFound => "404",
|
||
|
}.to_string()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* The engine itself */
|
||
|
|
||
|
pub struct Engine {
|
||
|
pub tera: Tera,
|
||
|
}
|
||
|
|
||
|
impl Engine {
|
||
|
pub async fn render_view(
|
||
|
&self,
|
||
|
format: ResponseFormat,
|
||
|
view: View,
|
||
|
) -> Response {
|
||
|
match format {
|
||
|
ResponseFormat::TextHtml => {
|
||
|
let template_name = view.template_name();
|
||
|
|
||
|
let mut context = tera::Context::new();
|
||
|
context.insert("view", &template_name);
|
||
|
//intented for shared macros
|
||
|
context.insert("format", &format.to_string());
|
||
|
context.insert("data", &view);
|
||
|
|
||
|
match self.tera.render(&(template_name+".html"), &context) {
|
||
|
Ok(html) => Html(html).into_response(),
|
||
|
Err(e) => {
|
||
|
println!("There was an error while rendering index.html: {e:?}");
|
||
|
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//TODO: Plain Text should have its own matcher
|
||
|
ResponseFormat::ApplicationJson | ResponseFormat::TextPlain => {
|
||
|
match view {
|
||
|
View::Dig{result, ..} => {
|
||
|
Json(result).into_response()
|
||
|
},
|
||
|
View::Index{result, ..} | View::Ip{result, ..} => {
|
||
|
Json(result).into_response()
|
||
|
},
|
||
|
_ => Json(view).into_response(),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|