askamaクレートを使用することにより、htmlテンプレートを使用してWebページを作成することができます。
表示するデータは将来的にはデータベースを使用するのですが、
それはまた次回の話なので、今回はダミーデータを使用しています。
[package]
name = "todo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = { version = "4.1" }
actix-rt = { version = "2.7" }
thiserror = { version = "1.0" }
askama = { version = "0.11" }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Todo App</Applet></title>
</head>
<body>
<div>
{% for entry in entries %}
<div>
<div>id: {{ entry.id }}, text: {{ entry.text }}</div>
<form action="/delete" method="post">
<input type="hidden" name=""id" value="{{ entry.id }}">
<button>delete</button>
</form>
</div>
{% endfor %}
</div>
<form action="/add" method="post">
<div>
<input name="text">
</div>
<div>
<button>add</button>
</div>
</form>
</body>
</html>
use actix_web::{get, App, HttpResponse, HttpServer, ResponseError};
use thiserror::Error;
use askama::Template;
struct TodoEntry {
id: u32,
text: String,
}
#[derive(Template)]
#[template(path = "index.html")]
struct IndexTemplate {
entries: Vec<TodoEntry>,
}
#[derive(Error, Debug)]
enum MyError {
#[error("Failed to render HTML")]
AskamaError(#[from] askama::Error),
}
impl ResponseError for MyError {}
#[get("/")]
async fn index() -> Result<HttpResponse, MyError> {
let mut entries = Vec::new();
entries.push(TodoEntry {
id: 1,
text: "First entry".to_string(),
});
entries.push(TodoEntry {
id: 2,
text: "Second entry".to_string(),
});
let html = IndexTemplate { entries };
let response_body = html.render()?;
Ok(HttpResponse::Ok()
.content_type("text/html")
.body(response_body))
}
#[actix_rt::main]
async fn main() -> Result<(), actix_web::Error> {
HttpServer::new(move || App::new().service(index))
.bind("0.0.0.0:8080")?
.run()
.await?;
Ok(())
}