use std::{ cell::OnceCell, path::{Path, PathBuf}, str::FromStr, }; use tokio::sync::mpsc::channel; use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher}; mod observe { use tracing::level_filters::LevelFilter; use tracing_subscriber::EnvFilter; pub fn setup_logging() { color_eyre::install().expect("Failed to install color_eyre"); let filter = EnvFilter::builder() .with_default_directive(LevelFilter::TRACE.into()) .parse_lossy("info,chatbot=trace"); tracing_subscriber::fmt().with_env_filter(filter).init(); } } mod prelude { #![allow(unused_imports)] pub use tracing::{debug, error, info, warn}; } use axum::{serve, Router}; use tower_http::services::ServeDir; use tower_livereload::LiveReloadLayer; use crate::prelude::*; const LIVE_RELOADING: bool = true; const STATIC_FILE_PATH: OnceCell = OnceCell::new(); fn static_file_dir() -> &'static Path { STATIC_FILE_PATH.get_or_init(|| PathBuf::from_str("static").unwrap()) } #[tokio::main] async fn main() -> Result<(), Box> { // load configuration? observe::setup_logging(); info!("Creating async watcher..."); let (tx, mut rx) = channel(1); info!("Creating watcher..."); let mut watcher = RecommendedWatcher::new( move |res| { info!("Res from watcher: {res:#?}"); futures::executor::block_on(async { tx.send(res).await.unwrap(); }) }, Config::default(), )?; info!("Created watcher"); watcher.watch(static_file_dir(), RecursiveMode::Recursive)?; let rl_layer = LiveReloadLayer::new(); let rl = rl_layer.reloader(); tokio::spawn(async move { info!("Recieving..."); while let Some(res) = rx.recv().await { info!("Recieved! {res:#?}"); match res { Ok(event) => { info!("fs event: {event:#?}"); rl.reload() } Err(e) => println!("watch error: {:?}", e), } } }); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); info!("Listening on {listener:#?}"); Ok(serve(listener, static_files()?.layer(rl_layer)).await?) } fn static_files() -> Result { let static_file_path = Path::new("./static/"); // serve the file in the "assets" directory under `/assets` info!("Starting static file server..."); Ok(Router::new().nest_service("/static", ServeDir::new(static_file_path))) }