use ::app::get_router; use axum::body::Body; use axum::http::Request; use listenfd::ListenFd; use notify::Watcher; use std::env; use std::path::Path; use tokio::net::TcpListener; use tower_livereload::predicate::Predicate; use tower_livereload::LiveReloadLayer; /// Nous filtrons les requêtes de `htmx` pour ne pas inclure le script _JS_ qui gère le rechargement /// Voir https://github.com/leotaku/tower-livereload/pull/3 #[derive(Copy, Clone)] struct NotHtmxPredicate; impl Predicate> for NotHtmxPredicate { fn check(&mut self, req: &Request) -> bool { !(req.headers().contains_key("hx-request")) } } const DEFAULT_LISTENER: &str = "localhost:3000"; async fn get_tcp_listener() -> TcpListener { let mut listenfd = ListenFd::from_env(); match listenfd.take_tcp_listener(0).unwrap() { // if we are given a tcp listener on listen fd 0, we use that one Some(listener) => { listener.set_nonblocking(true).unwrap(); TcpListener::from_std(listener).unwrap() } // otherwise fall back to local listening None => TcpListener::bind(DEFAULT_LISTENER).await.unwrap(), } } fn get_livereload_layer(templates_path: &Path) -> LiveReloadLayer { let livereload = LiveReloadLayer::new(); let reloader = livereload.reloader(); let mut watcher = notify::recommended_watcher(move |_| reloader.reload()).unwrap(); watcher .watch(templates_path, notify::RecursiveMode::Recursive) .unwrap(); livereload.request_predicate::(NotHtmxPredicate) } #[tokio::main] async fn main() { let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let assets_path = Path::new(&manifest_dir).join("assets"); let templates_path = Path::new(&manifest_dir).join("templates"); let livereload_layer = get_livereload_layer(&templates_path); let router = get_router(assets_path.as_path()).layer(livereload_layer); let listener: TcpListener = get_tcp_listener().await; println!("Listening on: http://{}", listener.local_addr().unwrap()); // Run the server with the router axum::serve(listener, router.into_make_service()) .await .unwrap(); }