#![windows_subsystem = "windows"] use actix_web::{body::Body, web, App, HttpRequest, HttpResponse, HttpServer}; use alcro::{Content, UIBuilder}; use mime_guess::from_path; use rust_embed::RustEmbed; use std::{borrow::Cow, sync::mpsc, thread}; #[derive(RustEmbed)] #[folder = "examples/actix-embed"] struct Asset; fn assets(req: HttpRequest) -> HttpResponse { let path = if req.path() == "/" { // if there is no path, return default file "index.html" } else { // trim leading '/' &req.path()[1..] }; // query the file from embedded asset with specified path match Asset::get(path) { Some(content) => { let body: Body = match content.data { Cow::Borrowed(bytes) => bytes.into(), Cow::Owned(bytes) => bytes.into(), }; HttpResponse::Ok() .content_type(from_path(path).first_or_octet_stream().as_ref()) .body(body) } None => HttpResponse::NotFound().body("404 Not Found"), } } fn main() -> anyhow::Result<()> { let (server_tx, server_rx) = mpsc::channel(); let (port_tx, port_rx) = mpsc::channel(); // start actix web server in separate thread thread::spawn(move || { let sys = actix_rt::System::new(); let server = HttpServer::new(|| App::new().route("*", web::get().to(assets))) .bind("127.0.0.1:0") .unwrap(); // we specified the port to be 0, // meaning the operating system // will choose some available port // for us // get the first bound address' port, // so we know where to point at let port = server.addrs().first().unwrap().port(); let server = server.run(); let _ = port_tx.send(port); let _ = server_tx.send(server); let _ = sys.run(); }); let port = port_rx.recv().unwrap(); let server = server_rx.recv().unwrap(); // start in current thread // and point it to a port that was bound // to actix web server let ui = UIBuilder::new() .content(Content::Url(&format!("http://127.0.0.1:{}", port))) .size(400, 400) .run()?; ui.wait_finish(); // gracefully shutdown actix web server futures::executor::block_on(server.stop(true)); Ok(()) }