feat: implement basic server

This demo can:
- Serve a webpage
- Serve static assets
- Asynchronously fetch html
This commit is contained in:
2023-05-09 20:56:09 +02:00
parent 351d6d2f64
commit ea59f1ed1e
10 changed files with 1778 additions and 2 deletions

1658
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,3 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-files = "0.6.2"
actix-web = "4.3.1"
actix-web-lab = "0.19.1"
askama = "0.12.0"
env_logger = "0.10.0"
log = "0.4.17"

View File

@@ -1,3 +1,74 @@
fn main() {
println!("Hello, world!");
use std::io;
use actix_files as fs;
use actix_web::{get, middleware, App, HttpRequest, HttpServer, Responder};
use actix_web_lab::respond::Html;
use askama::Template;
#[derive(Template)]
#[template(path = "layout.html")]
struct Index;
#[derive(Clone, Debug)]
struct Row {
foo: String,
bar: String,
baz: String,
}
#[derive(Template)]
#[template(path = "fragment/table.html")]
struct Table {
table: Vec<Row>,
}
#[get("/")]
async fn index() -> actix_web::Result<impl Responder> {
Ok(Html(Index.render().expect("Valid template")))
}
#[get("/table")]
async fn table(req: HttpRequest) -> actix_web::Result<impl Responder> {
match req.headers().get("hx-request") {
Some(_) => {
// Render the hypermedia fragment.
Ok(Html(
Table {
table: vec![
Row {
foo: "foo".into(),
bar: "bar".into(),
baz: "baz".into()
};
10
],
}
.render()
.expect("Valid template"),
))
}
None => {
// Render the whole document
// FIXME: Render the fragment in place...
Ok(Html(Index.render().expect("Valid template")))
}
}
}
#[actix_web::main]
async fn main() -> io::Result<()> {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
log::info!("Starting HTTP Server at http://localhost:8080");
HttpServer::new(move || {
App::new()
.wrap(middleware::Logger::default())
.service(fs::Files::new("/static", "static").show_files_listing())
.service(index)
.service(table)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}

3
static/css/style.css Normal file
View File

@@ -0,0 +1,3 @@
h1 {
color: blue;
}

1
static/js/htmx.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
static/js/script.js Normal file
View File

@@ -0,0 +1 @@
console.log("loaded script.js!");

View File

View File

@@ -0,0 +1,8 @@
<thead>
<tr><th>foo</th><th>bar</th><th>baz</th></tr>
</thead>
<tbody>
{% for row in table %}
<tr><td>{{ row.foo }}</td><td>{{ row.bar }}</td><td>{{ row.baz }}</td></tr>
{% endfor %}
</tbody>

28
templates/layout.html Normal file
View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="/static/css/style.css" />
<script src="/static/js/htmx.min.js"></script>
<script src="/static/js/script.js"></script>
<title>Hello htmx!</title>
</head>
<body>
<hgroup>
<h1>Hello htmx!</h1>
<p>A new old way to build web applications</p>
</hgroup>
<table>
<tr><td>
<button hx-get="/table" hx-target="table" hx-push-url="true">
Load data
</button>
</td></tr>
</table>
</body>
</html>

View File