added web server
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

This commit is contained in:
Jake Hillion 2022-07-21 11:43:35 +01:00
parent 3f2fea0447
commit 72a4120451
5 changed files with 1915 additions and 2 deletions

1828
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,3 +6,11 @@ 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]
log = "0.4"
env_logger = "0.9"
async-std = "1"
tide = "0.16.0"
rust-embed = { version = "6.2.0", features = ["interpolate-folder-path"]}

7
src/api.rs Normal file
View File

@ -0,0 +1,7 @@
pub fn serve() -> tide::Server<()> {
let mut app = tide::new();
app.at("/hello").get(|_| async { Ok("Hello, Jake!") });
app
}

View File

@ -1,3 +1,20 @@
fn main() { mod api;
println!("Hello, world!"); mod react;
use api::serve as serve_api;
use react::serve as serve_react;
use async_std::task;
use std::io;
fn main() -> Result<(), io::Error> {
let env = env_logger::Env::new().filter_or("LOG", "info");
env_logger::init_from_env(env);
let mut app = tide::new();
app.at("/_api").nest(serve_api());
app.at("/").nest(serve_react());
task::block_on(app.listen("127.0.0.1:8080"))
} }

53
src/react.rs Normal file
View File

@ -0,0 +1,53 @@
use log::info;
use rust_embed::RustEmbed;
use tide::{Request, Response};
#[derive(RustEmbed)]
#[folder = "$CARGO_MANIFEST_DIR/gui/build"]
struct React;
static INDEX: &str = "index.html";
pub fn serve() -> tide::Server<()> {
let mut app = tide::new();
app.at("/").get(|_| async { serve_internal(INDEX) });
app.at("/*path").get(|r: Request<()>| {
let path = r.param("path").unwrap().to_string();
async move { serve_internal(path.as_str()) }
});
app
}
fn serve_internal(path: &str) -> tide::Result<Response> {
let file = React::get(path);
if let Some(file) = file {
Ok(Response::builder(200)
.content_type(get_content_type(path))
.body(file.data.as_ref())
.build())
} else {
serve_internal(INDEX)
}
}
fn get_content_type(path: &str) -> &str {
let ext = match path.rfind('.') {
None => return "application/octet-stream",
Some(e) => e,
};
info!("{}", path.split_at(ext).1);
match path.split_at(ext).1 {
".html" => "text/html",
".js" => "text/javascript",
".css" => "text/css",
".svg" => "image/svg+xml",
_ => "application/octet-stream",
}
}