From 279f0bfaa30cacdec3e5206144b0afcf9360f65d Mon Sep 17 00:00:00 2001
From: Philippe Loctaux
Date: Fri, 3 Mar 2023 08:16:06 +0100
Subject: [PATCH] Enum Page to render templates with content from a struct, set
html titles, with rocket responder
For each Struct to be rendered in template, put in a mod called "content" for easy importing
---
Cargo.lock | 10 +++++
crates/ezidam/Cargo.toml | 1 +
crates/ezidam/src/error/mod.rs | 31 +++++++++------
crates/ezidam/src/main.rs | 1 +
crates/ezidam/src/page/content.rs | 2 +
crates/ezidam/src/page/mod.rs | 41 +++++++++++++++++++
crates/ezidam/src/page/responder.rs | 11 ++++++
crates/ezidam/src/page/template.rs | 26 ++++++++++++
crates/ezidam/src/routes/mod.rs | 1 +
crates/ezidam/src/routes/root.rs | 24 ++++++++++-
crates/ezidam/templates/homepage.html.tera | 5 +++
crates/ezidam/templates/setup.html.tera | 46 ++++++++++++++++++++++
12 files changed, 187 insertions(+), 12 deletions(-)
create mode 100644 crates/ezidam/src/page/content.rs
create mode 100644 crates/ezidam/src/page/mod.rs
create mode 100644 crates/ezidam/src/page/responder.rs
create mode 100644 crates/ezidam/src/page/template.rs
create mode 100644 crates/ezidam/templates/homepage.html.tera
create mode 100644 crates/ezidam/templates/setup.html.tera
diff --git a/Cargo.lock b/Cargo.lock
index b879652..d8bb814 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -490,6 +490,15 @@ dependencies = [
"cfg-if 1.0.0",
]
+[[package]]
+name = "erased-serde"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4ca605381c017ec7a5fef5e548f1cfaa419ed0f6df6367339300db74c92aa7d"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "errno"
version = "0.2.8"
@@ -522,6 +531,7 @@ name = "ezidam"
version = "0.1.0"
dependencies = [
"database_pool",
+ "erased-serde",
"infer",
"rocket",
"rocket_db_pools",
diff --git a/crates/ezidam/Cargo.toml b/crates/ezidam/Cargo.toml
index 4449812..519cf49 100644
--- a/crates/ezidam/Cargo.toml
+++ b/crates/ezidam/Cargo.toml
@@ -8,6 +8,7 @@ rocket = "0.5.0-rc.2"
rocket_db_pools = { version = "0.1.0-rc.2", features = ["sqlx_sqlite"] }
rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] }
infer = { version = "0.12.0", default-features = false }
+erased-serde = "0.3"
# local crates
database_pool = { path = "../database_pool" }
diff --git a/crates/ezidam/src/error/mod.rs b/crates/ezidam/src/error/mod.rs
index 4c32bb2..05e109a 100644
--- a/crates/ezidam/src/error/mod.rs
+++ b/crates/ezidam/src/error/mod.rs
@@ -2,8 +2,21 @@ pub(super) mod catchers;
mod conversion;
mod responder;
+use crate::page::Page;
use rocket::http::Status;
-use rocket_dyn_templates::{context, Template};
+use rocket_dyn_templates::Template;
+
+pub mod content {
+ use rocket::serde::Serialize;
+
+ #[derive(Serialize)]
+ #[serde(crate = "rocket::serde")]
+ pub struct Error {
+ pub message: String,
+ pub http_code: u16,
+ pub http_reason: &'static str,
+ }
+}
pub struct Error {
status: Status,
@@ -14,16 +27,12 @@ impl Error {
fn new(status: Status, message: M) -> Self {
Self {
status,
- template: Template::render(
- "error",
- context! {
- title: format!("{} Error", status.code),
- message: message.to_string(),
- version: env!("CARGO_PKG_VERSION"),
- http_code: status.code,
- http_reason: status.reason_lossy()
- },
- ),
+ template: Page::Error(content::Error {
+ message: message.to_string(),
+ http_code: status.code,
+ http_reason: status.reason_lossy(),
+ })
+ .into(),
}
}
diff --git a/crates/ezidam/src/main.rs b/crates/ezidam/src/main.rs
index b8d385c..7acc5dd 100644
--- a/crates/ezidam/src/main.rs
+++ b/crates/ezidam/src/main.rs
@@ -1,6 +1,7 @@
mod database;
mod error;
mod file_from_bytes;
+mod page;
mod response_timer;
mod routes;
mod shutdown;
diff --git a/crates/ezidam/src/page/content.rs b/crates/ezidam/src/page/content.rs
new file mode 100644
index 0000000..d719b1f
--- /dev/null
+++ b/crates/ezidam/src/page/content.rs
@@ -0,0 +1,2 @@
+pub use crate::error::content::*;
+pub use crate::routes::root::content::*;
diff --git a/crates/ezidam/src/page/mod.rs b/crates/ezidam/src/page/mod.rs
new file mode 100644
index 0000000..f0b386c
--- /dev/null
+++ b/crates/ezidam/src/page/mod.rs
@@ -0,0 +1,41 @@
+mod content;
+mod responder;
+mod template;
+
+use self::content::*;
+use erased_serde::Serialize;
+
+pub enum Page {
+ Error(Error),
+ Setup(),
+ Homepage(Homepage),
+}
+
+impl Page {
+ /// Template to render, the names comes from the file in "/templates"
+ fn template_name(&self) -> &'static str {
+ match self {
+ Page::Error(_) => "error",
+ Page::Setup() => "setup",
+ Page::Homepage(_) => "homepage",
+ }
+ }
+
+ /// Title in the html page
+ fn page_title(&self) -> &'static str {
+ match self {
+ Page::Error(_) => "Error",
+ Page::Setup() => "Setup",
+ Page::Homepage(_) => "Home",
+ }
+ }
+
+ /// Structure to render in page
+ fn content(self) -> Box {
+ match self {
+ Page::Error(error) => Box::new(error),
+ Page::Setup() => Box::new(()),
+ Page::Homepage(homepage) => Box::new(homepage),
+ }
+ }
+}
diff --git a/crates/ezidam/src/page/responder.rs b/crates/ezidam/src/page/responder.rs
new file mode 100644
index 0000000..e7e331e
--- /dev/null
+++ b/crates/ezidam/src/page/responder.rs
@@ -0,0 +1,11 @@
+use super::Page;
+use rocket::response::Responder;
+use rocket::{response, Request};
+use rocket_dyn_templates::Template;
+
+impl<'r, 'o: 'r> Responder<'r, 'o> for Page {
+ fn respond_to(self, req: &Request) -> response::Result<'o> {
+ // Render template and respond to http request
+ Template::from(self).respond_to(req)
+ }
+}
diff --git a/crates/ezidam/src/page/template.rs b/crates/ezidam/src/page/template.rs
new file mode 100644
index 0000000..0de4441
--- /dev/null
+++ b/crates/ezidam/src/page/template.rs
@@ -0,0 +1,26 @@
+use super::Page;
+use rocket::serde::Serialize;
+use rocket_dyn_templates::Template;
+
+#[derive(Serialize)]
+#[serde(crate = "rocket::serde")]
+struct TemplateContent {
+ title: &'static str,
+ version: &'static str,
+
+ #[serde(flatten)]
+ content: S,
+}
+
+impl From for Template {
+ fn from(p: Page) -> Self {
+ Self::render(
+ p.template_name(),
+ TemplateContent {
+ title: p.page_title(),
+ version: env!("CARGO_PKG_VERSION"),
+ content: p.content(),
+ },
+ )
+ }
+}
diff --git a/crates/ezidam/src/routes/mod.rs b/crates/ezidam/src/routes/mod.rs
index 0f677ef..5dd17cf 100644
--- a/crates/ezidam/src/routes/mod.rs
+++ b/crates/ezidam/src/routes/mod.rs
@@ -6,6 +6,7 @@ pub(self) mod prelude {
pub use crate::database::Database;
pub use crate::error::Error;
pub use crate::file_from_bytes::FileFromBytes;
+ pub use crate::page::Page;
pub use rocket_db_pools::Connection;
pub type Result = std::result::Result;
diff --git a/crates/ezidam/src/routes/root.rs b/crates/ezidam/src/routes/root.rs
index 4e48c7e..5816699 100644
--- a/crates/ezidam/src/routes/root.rs
+++ b/crates/ezidam/src/routes/root.rs
@@ -3,7 +3,7 @@ use rocket::{get, routes};
use settings::Settings;
pub fn routes() -> Vec {
- routes![logo]
+ routes![logo, setup, homepage]
}
#[get("/logo")]
@@ -14,3 +14,25 @@ async fn logo(mut db: Connection) -> Result {
// HTTP response
Ok(FileFromBytes::from(settings.business_logo()))
}
+
+#[get("/setup")]
+async fn setup() -> Page {
+ Page::Setup()
+}
+
+pub mod content {
+ use rocket::serde::Serialize;
+
+ #[derive(Serialize)]
+ #[serde(crate = "rocket::serde")]
+ pub struct Homepage {
+ pub abc: String,
+ }
+}
+
+#[get("/homepage")]
+async fn homepage() -> Page {
+ Page::Homepage(content::Homepage {
+ abc: "string".to_string(),
+ })
+}
diff --git a/crates/ezidam/templates/homepage.html.tera b/crates/ezidam/templates/homepage.html.tera
new file mode 100644
index 0000000..f0c8c9b
--- /dev/null
+++ b/crates/ezidam/templates/homepage.html.tera
@@ -0,0 +1,5 @@
+{% extends "base" %}
+
+{% block content %}
+homepage goes here {{ abc }}
+{% endblock content %}
diff --git a/crates/ezidam/templates/setup.html.tera b/crates/ezidam/templates/setup.html.tera
new file mode 100644
index 0000000..702a5b7
--- /dev/null
+++ b/crates/ezidam/templates/setup.html.tera
@@ -0,0 +1,46 @@
+{% extends "base" %}
+
+{% block content %}
+
+
+
+
+
+

+
+
+
+
Welcome to Ezidam!
+
Initial setup
+
+
first admin account
+
+
+
+
+
+
+
+
+
+
+{% endblock content %}