|
@@ -1,34 +1,40 @@
|
|
use axum::{
|
|
use axum::{
|
|
- extract::{
|
|
|
|
- ws::Message,
|
|
|
|
- Extension, TypedHeader, WebSocketUpgrade,
|
|
|
|
- },
|
|
|
|
|
|
+ extract::{ws::Message, Extension, TypedHeader, WebSocketUpgrade},
|
|
http::StatusCode,
|
|
http::StatusCode,
|
|
response::IntoResponse,
|
|
response::IntoResponse,
|
|
routing::{get, get_service},
|
|
routing::{get, get_service},
|
|
AddExtensionLayer, Router,
|
|
AddExtensionLayer, Router,
|
|
};
|
|
};
|
|
-use notify::{watcher, Watcher, DebouncedEvent};
|
|
|
|
|
|
+use notify::{watcher, DebouncedEvent, Watcher};
|
|
use std::sync::{mpsc::channel, Arc, Mutex};
|
|
use std::sync::{mpsc::channel, Arc, Mutex};
|
|
use std::time::Duration;
|
|
use std::time::Duration;
|
|
use tower_http::services::ServeDir;
|
|
use tower_http::services::ServeDir;
|
|
|
|
|
|
-use crate::{CrateConfig, builder};
|
|
|
|
|
|
+use crate::{builder, CrateConfig};
|
|
|
|
|
|
struct WsRelodState {
|
|
struct WsRelodState {
|
|
update: bool,
|
|
update: bool,
|
|
}
|
|
}
|
|
|
|
|
|
-impl WsRelodState { fn change(&mut self) { self.update = !self.update; } }
|
|
|
|
|
|
+impl WsRelodState {
|
|
|
|
+ fn change(&mut self) {
|
|
|
|
+ self.update = !self.update;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
|
|
pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
|
|
-
|
|
|
|
log::info!("🚀 Starting development server...");
|
|
log::info!("🚀 Starting development server...");
|
|
-
|
|
|
|
|
|
+
|
|
let (tx, rx) = channel();
|
|
let (tx, rx) = channel();
|
|
|
|
|
|
|
|
+ // file watcher: check file change
|
|
let mut watcher = watcher(tx, Duration::from_secs(2)).unwrap();
|
|
let mut watcher = watcher(tx, Duration::from_secs(2)).unwrap();
|
|
- watcher.watch(config.crate_dir.join("src").clone(), notify::RecursiveMode::Recursive).unwrap();
|
|
|
|
|
|
+ watcher
|
|
|
|
+ .watch(
|
|
|
|
+ config.crate_dir.join("src").clone(),
|
|
|
|
+ notify::RecursiveMode::Recursive,
|
|
|
|
+ )
|
|
|
|
+ .unwrap();
|
|
|
|
|
|
let ws_reload_state = Arc::new(Mutex::new(WsRelodState { update: false }));
|
|
let ws_reload_state = Arc::new(Mutex::new(WsRelodState { update: false }));
|
|
|
|
|
|
@@ -38,37 +44,40 @@ pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
|
|
loop {
|
|
loop {
|
|
if let Ok(v) = rx.recv() {
|
|
if let Ok(v) = rx.recv() {
|
|
match v {
|
|
match v {
|
|
- DebouncedEvent::Create(_) | DebouncedEvent::Write(_) |
|
|
|
|
- DebouncedEvent::Remove(_) | DebouncedEvent::Rename(_, _) => {
|
|
|
|
|
|
+ DebouncedEvent::Create(_)
|
|
|
|
+ | DebouncedEvent::Write(_)
|
|
|
|
+ | DebouncedEvent::Remove(_)
|
|
|
|
+ | DebouncedEvent::Rename(_, _) => {
|
|
if let Ok(_) = builder::build(&watcher_conf) {
|
|
if let Ok(_) = builder::build(&watcher_conf) {
|
|
|
|
+ // change the websocket reload state to true;
|
|
|
|
+ // the page will auto-reload.
|
|
watcher_ws_state.lock().unwrap().change();
|
|
watcher_ws_state.lock().unwrap().change();
|
|
}
|
|
}
|
|
- },
|
|
|
|
|
|
+ }
|
|
_ => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ }
|
|
});
|
|
});
|
|
|
|
|
|
let app = Router::new()
|
|
let app = Router::new()
|
|
.route("/ws", get(ws_handler))
|
|
.route("/ws", get(ws_handler))
|
|
- .fallback(
|
|
|
|
- get_service(ServeDir::new(config.out_dir)).handle_error(
|
|
|
|
- |error: std::io::Error| async move {
|
|
|
|
- (
|
|
|
|
- StatusCode::INTERNAL_SERVER_ERROR,
|
|
|
|
- format!("Unhandled internal error: {}", error),
|
|
|
|
- )
|
|
|
|
- },
|
|
|
|
- ),
|
|
|
|
- )
|
|
|
|
|
|
+ .fallback(get_service(ServeDir::new(config.out_dir)).handle_error(
|
|
|
|
+ |error: std::io::Error| async move {
|
|
|
|
+ (
|
|
|
|
+ StatusCode::INTERNAL_SERVER_ERROR,
|
|
|
|
+ format!("Unhandled internal error: {}", error),
|
|
|
|
+ )
|
|
|
|
+ },
|
|
|
|
+ ))
|
|
.layer(AddExtensionLayer::new(ws_reload_state.clone()));
|
|
.layer(AddExtensionLayer::new(ws_reload_state.clone()));
|
|
|
|
|
|
|
|
+ // start serve dev-server at 0.0.0.0:8080
|
|
let port = "8080";
|
|
let port = "8080";
|
|
|
|
+ log::info!("📡 Dev-Server is started at: http://127.0.0.1:{}/", port);
|
|
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
|
|
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
|
|
.serve(app.into_make_service())
|
|
.serve(app.into_make_service())
|
|
.await?;
|
|
.await?;
|
|
-
|
|
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
@@ -80,7 +89,10 @@ async fn ws_handler(
|
|
ws.on_upgrade(|mut socket| async move {
|
|
ws.on_upgrade(|mut socket| async move {
|
|
loop {
|
|
loop {
|
|
if state.lock().unwrap().update {
|
|
if state.lock().unwrap().update {
|
|
- socket.send(Message::Text(String::from("reload"))).await.unwrap();
|
|
|
|
|
|
+ socket
|
|
|
|
+ .send(Message::Text(String::from("reload")))
|
|
|
|
+ .await
|
|
|
|
+ .unwrap();
|
|
state.lock().unwrap().change();
|
|
state.lock().unwrap().change();
|
|
}
|
|
}
|
|
}
|
|
}
|