Skip to content

Commit

Permalink
feat(examples): htmlx
Browse files Browse the repository at this point in the history
  • Loading branch information
fundon committed Dec 10, 2023
1 parent a3b604f commit 0c9289e
Show file tree
Hide file tree
Showing 22 changed files with 173 additions and 42 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"viz",
"viz-core",
Expand Down Expand Up @@ -30,8 +31,8 @@ members = [
"examples/tracing",
"examples/graceful-shutdown",
"examples/databases/*",
"examples/htmlx",
]
resolver = "2"

[workspace.package]
version = "0.5.1"
Expand Down
2 changes: 1 addition & 1 deletion examples/databases/sea-orm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ publish = false
viz = { workspace = true, features = ["serve"] }
serde.workspace = true

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sea-orm = { version = "0.12", features = ["runtime-tokio-rustls", "sqlx-sqlite"] }

[lints]
Expand Down
5 changes: 1 addition & 4 deletions examples/forms/form/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,4 @@ publish = false
viz.workspace = true

serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = [
"rt-multi-thread",
"macros",
] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
2 changes: 1 addition & 1 deletion examples/graceful-shutdown/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ publish = false
[dependencies]
viz.workspace = true

tokio = { workspace = true, features = [ "rt-multi-thread", "macros", "time" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "time"] }
2 changes: 1 addition & 1 deletion examples/hello-world/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ publish = false
[dependencies]
viz.workspace = true

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
9 changes: 7 additions & 2 deletions examples/htmlx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ edition.workspace = true
publish = false

[dependencies]
viz.workspace = true
viz = { workspace = true, features = ["serve"] }

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }

handlebars = { version = "4.5", features = ["dir_source"] }
once_cell = "1.19"
12 changes: 0 additions & 12 deletions examples/htmlx/public/index.html

This file was deleted.

112 changes: 110 additions & 2 deletions examples/htmlx/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,111 @@
fn main() {
println!("Hello, world!");
// #![deny(warnings)]

use handlebars::Handlebars;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::{
net::SocketAddr,
sync::{Arc, Mutex, PoisonError},
};
use tokio::net::TcpListener;
use viz::{
header::HeaderValue, middleware::limits, serve, types::State, Error, IntoResponse, Request,
RequestExt, Response, ResponseExt, Result, Router, StatusCode, Tree,
};

/// In-memory todo store
type DB = Arc<Mutex<Vec<Todo>>>;

#[derive(Debug, Clone, Deserialize, Serialize)]
struct Todo {
pub text: String,
pub completed: bool,
}

static TPLS: Lazy<Handlebars> = Lazy::new(|| {
let mut h = Handlebars::new();
h.register_templates_directory(".html", "examples/htmlx/templates")
.unwrap();
h
});

#[allow(clippy::needless_pass_by_value)]
fn into_error<T>(e: PoisonError<T>) -> Error {
e.to_string().into_error()
}

async fn index(req: Request) -> Result<Response> {
let todos = req
.state::<DB>()
.unwrap()
.lock()
.map_err(into_error)?
.clone();
let body = TPLS
.render(
"index",
&json!({
"todos": todos
}),
)
.map_err(Error::normal)?;
Ok(Response::html(body))
}

async fn list(req: Request) -> Result<Response> {
let todos = req
.state::<DB>()
.unwrap()
.lock()
.map_err(into_error)?
.clone();
let body = TPLS
.render(
"todos",
&json!({
"todos": todos
}),
)
.map_err(Error::normal)?;
Ok(Response::html(body))
}

async fn create(mut req: Request) -> Result<Response> {
let todo = req.form::<Todo>().await?;
let db = req.state::<DB>().unwrap();

let mut todos = db.lock().map_err(into_error)?;
todos.push(todo);

let mut resp = StatusCode::CREATED.into_response();
resp.headers_mut()
.insert("HX-Trigger", HeaderValue::from_static("newTodo"));
Ok(resp)
}

#[tokio::main]
async fn main() -> Result<()> {
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let listener = TcpListener::bind(addr).await?;
println!("listening on http://{addr}");

let app = Router::new()
.get("/", index)
.get("/todos", list)
.post("/todos", create)
.any("/*", |_| async { Ok(Response::text("Welcome!")) })
.with(State::new(DB::default()))
.with(limits::Config::default());
let tree = Arc::new(Tree::from(app));

loop {
let (stream, addr) = listener.accept().await?;
let tree = tree.clone();
tokio::task::spawn(async move {
if let Err(err) = serve(stream, tree, Some(addr)).await {
eprintln!("Error while serving HTTP connection: {err}");
}
});
}
}
30 changes: 30 additions & 0 deletions examples/htmlx/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<title>Viz & htmlx</title>
<script src="https://unpkg.com/[email protected]" integrity="sha384-QFjmbokDn2DjBjq+fM+8LUIVrAgqcNW2s0PjAxHETgRn9l4fvX31ZxDxvwQnyMOX" crossorigin="anonymous"></script>
</head>
<body>
<form
hx-post="/todos"
hx-on="htmx:configRequest: event.detail.parameters.completed = completed.checked"
hx-swap="none"
id="form">
<input type="checkbox" name="completed" id="completed" />
<label for="completed">Done</label>
<input type="text" name="text" id="text" />
<button type="submit">Add</button>
</form>
<div
hx-get="/todos"
hx-trigger="newTodo from:form"
id="todos"
>
<ul id="list">
{{#each todos as | todo |}}
<li>{{text}}</li>
{{/each}}
</ul>
</div>
</body>
</html>
5 changes: 5 additions & 0 deletions examples/htmlx/templates/todos.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ul>
{{#each todos as | todo |}}
<li>{{text}} {{complated}}</li>
{{/each}}
</ul>
7 changes: 2 additions & 5 deletions examples/limits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,5 @@ publish = false
[dependencies]
viz = { workspace = true, features = ["limits", "json", "form", "multipart"] }

serde = {version = "1.0", features = ["derive"] }
tokio = { workspace = true, features = [
"rt-multi-thread",
"macros",
] }
serde = { version = "1.0", features = ["derive"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
2 changes: 1 addition & 1 deletion examples/otel/metrics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ publish = false
[dependencies]
viz = { workspace = true, features = ["otel-metrics", "otel-prometheus"] }

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
opentelemetry = { workspace = true, features = ["metrics"]}
opentelemetry_sdk = { workspace = true, features = ["metrics"] }
2 changes: 1 addition & 1 deletion examples/otel/tracing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish = false
[dependencies]
viz = { workspace = true, features = ["otel-tracing"] }

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
opentelemetry.workspace = true
opentelemetry_sdk = { workspace = true, features = ["trace", "rt-tokio-current-thread"] }
opentelemetry-jaeger = { version = "0.20", features = ["rt-tokio-current-thread"]}
1 change: 1 addition & 0 deletions examples/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
## Examples

* [askama](askama)
* [handlebars](../htmlx)
* [markup](markup)
* [maud](maud)
* [minijinja](minijinja)
Expand Down
2 changes: 1 addition & 1 deletion examples/templates/askama/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ publish = false
[dependencies]
viz.workspace = true

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
askama = "0.12"
2 changes: 1 addition & 1 deletion examples/templates/markup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish = false
[dependencies]
viz.workspace = true

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }

markup = "0.15"
v_htmlescape = "0.15"
2 changes: 1 addition & 1 deletion examples/templates/maud/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ publish = false
[dependencies]
viz.workspace = true

tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
maud = "0.25"
2 changes: 1 addition & 1 deletion examples/templates/minijinja/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ publish = false
viz.workspace = true

serde.workspace = true
tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
minijinja = { version = "1", features = ["loader"] }
once_cell = "1.19"
5 changes: 2 additions & 3 deletions examples/templates/minijinja/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::Serialize;
use tokio::net::TcpListener;
use viz::{serve, BytesMut, Error, Request, Response, ResponseExt, Result, Router, Tree};

static MINIJINJA: Lazy<Environment> = Lazy::new(|| {
static TPLS: Lazy<Environment> = Lazy::new(|| {
let mut env = Environment::new();
env.set_loader(path_loader("examples/templates/minijinja/templates"));
env
Expand All @@ -24,8 +24,7 @@ struct User<'a> {
async fn index(_: Request) -> Result<Response> {
let mut buf = BytesMut::with_capacity(512);
buf.extend(
MINIJINJA
.get_template("index.html")
TPLS.get_template("index.html")
.map_err(Error::normal)?
.render(context! {
title => "Viz.rs",
Expand Down
2 changes: 1 addition & 1 deletion examples/templates/tera/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ publish = false
viz.workspace = true

serde.workspace = true
tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tera = "1.18"
once_cell = "1.19"
4 changes: 2 additions & 2 deletions examples/templates/tera/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use tera::{Context, Tera};
use tokio::net::TcpListener;
use viz::{serve, BytesMut, Error, Request, Response, ResponseExt, Result, Router, Tree};

static TERA: Lazy<Tera> =
static TPLS: Lazy<Tera> =
Lazy::new(|| Tera::new("examples/templates/tera/templates/**/*").unwrap());

#[derive(Serialize)]
Expand All @@ -36,7 +36,7 @@ async fn index(_: Request) -> Result<Response> {
);
let mut buf = BytesMut::with_capacity(512);
buf.extend(
TERA.render("index.html", &ctx)
TPLS.render("index.html", &ctx)
.map_err(Error::normal)?
.as_bytes(),
);
Expand Down
2 changes: 1 addition & 1 deletion viz-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ serde.workspace = true
sessions = { version = "0.5", features = ["memory"] }
nano-id = "0.3"

http = "0.2"
http = "=0.2"
reqwest = { version = "0.11", features = ["cookies", "json", "multipart"]}
tokio = { workspace = true, features = ["full"] }

0 comments on commit 0c9289e

Please sign in to comment.