forked from pyrossh/rust-embed
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rs
57 lines (46 loc) · 1.33 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use axum::{
http::{header, StatusCode, Uri},
response::{Html, IntoResponse, Response},
routing::Router,
};
use rust_embed::Embed;
use std::net::SocketAddr;
static INDEX_HTML: &str = "index.html";
#[derive(Embed)]
#[folder = "examples/axum-spa/assets/"]
struct Assets;
#[tokio::main]
async fn main() {
let app = Router::new().fallback(static_handler);
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
println!("listening on {}", addr);
axum::serve(listener, app.into_make_service()).await.unwrap();
}
async fn static_handler(uri: Uri) -> impl IntoResponse {
let path = uri.path().trim_start_matches('/');
if path.is_empty() || path == INDEX_HTML {
return index_html().await;
}
match Assets::get(path) {
Some(content) => {
let mime = mime_guess::from_path(path).first_or_octet_stream();
([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response()
}
None => {
if path.contains('.') {
return not_found().await;
}
index_html().await
}
}
}
async fn index_html() -> Response {
match Assets::get(INDEX_HTML) {
Some(content) => Html(content.data).into_response(),
None => not_found().await,
}
}
async fn not_found() -> Response {
(StatusCode::NOT_FOUND, "404").into_response()
}