use std::net::TcpListener;
use std::sync::{Arc, Mutex};
use async_std::prelude::FutureExt;
use tide::prelude::*;
use tide::Request;
struct State {
shutdown: Option<async_std::channel::Sender<()>>,
}
async fn index(_req: Request<Arc<Mutex<State>>>) -> tide::Result {
let mut resp: tide::Response = r#"Hello World. <form method="post" action="/shutdown"><input type="submit" value="Shut Down"></form>"#.into();
resp.set_content_type("text/html");
Ok(resp)
}
async fn shutdown(req: Request<Arc<Mutex<State>>>) -> tide::Result {
if let Some(shutdown) = req.state().lock().unwrap().shutdown.take() {
let _ = shutdown.try_send(());
Ok("Shutting down".into())
} else {
Ok("Shutdown already initiated".into())
}
}
fn main() {
let (shutdown_tx, shutdown_rx) = async_std::channel::bounded::<()>(1);
let state = Arc::new(Mutex::new(State {
shutdown: Some(shutdown_tx),
}));
let mut app = tide::with_state(state);
app.at("/").get(index);
app.at("/shutdown").post(shutdown);
let ear = TcpListener::bind("127.0.0.1:0").expect("bind port");
let addr = ear.local_addr().expect("retrieve port");
drteeth::launch(
"Tide Demo",
addr,
async move {
app.listen(ear).await.unwrap();
}
.race(async move {
shutdown_rx.recv().await.unwrap();
}),
)
.unwrap();
}