diff --git a/examples/templates/maud/Cargo.toml b/examples/templates/maud/Cargo.toml new file mode 100644 index 00000000..bcc2847e --- /dev/null +++ b/examples/templates/maud/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "template-maud" +version = "0.1.0" +edition.workspace = true +publish = false + +[dependencies] +viz.workspace = true + +tokio = { workspace = true, features = [ "rt-multi-thread", "macros" ] } +maud = "0.25" diff --git a/examples/templates/maud/src/main.rs b/examples/templates/maud/src/main.rs new file mode 100644 index 00000000..16727200 --- /dev/null +++ b/examples/templates/maud/src/main.rs @@ -0,0 +1,67 @@ +#![deny(warnings)] +#![allow(clippy::unused_async)] +#![allow(clippy::must_use_candidate)] +#![allow(clippy::inherent_to_string_shadow_display)] + +use maud::{html, PreEscaped, DOCTYPE}; +use std::{net::SocketAddr, sync::Arc}; +use tokio::net::TcpListener; +use viz::{serve, Request, Response, ResponseExt, Result, Router, Tree}; + +pub struct Todo<'a> { + id: u64, + content: &'a str, +} + +async fn index(_: Request) -> Result { + let items = vec![ + Todo { + id: 1, + content: "Learn Rust", + }, + Todo { + id: 2, + content: "Learn English", + }, + ]; + + let buf = html! { + (DOCTYPE) + head { + title { "Todos" } + } + body { + table { + tr { th { "ID" } th { "Content" } } + @for item in &items { + tr { + td { (item.id) } + td { (PreEscaped(item.content.to_string())) } + } + } + } + } + }; + + Ok(Response::html(buf.into_string())) +} + +#[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); + 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}"); + } + }); + } +}