feat: implement basic server
This demo can: - Serve a webpage - Serve static assets - Asynchronously fetch html
This commit is contained in:
1658
Cargo.lock
generated
Normal file
1658
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,3 +6,9 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[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"
|
||||||
|
|||||||
75
src/main.rs
75
src/main.rs
@@ -1,3 +1,74 @@
|
|||||||
fn main() {
|
use std::io;
|
||||||
println!("Hello, world!");
|
|
||||||
|
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
3
static/css/style.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
h1 {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
1
static/js/htmx.min.js
vendored
Normal file
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
1
static/js/script.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log("loaded script.js!");
|
||||||
0
templates/fragment/.gitkeep
Normal file
0
templates/fragment/.gitkeep
Normal file
8
templates/fragment/table.html
Normal file
8
templates/fragment/table.html
Normal 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
28
templates/layout.html
Normal 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>
|
||||||
0
templates/partial/.gitkeep
Normal file
0
templates/partial/.gitkeep
Normal file
Reference in New Issue
Block a user