// Copyright 2022 Daniel Arbuckle // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Run with `cargo run --example tide --no-default-features --features "asyncstd examples"` 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 fn index(_req: Request>>) -> tide::Result { let mut resp: tide::Response = r#"Hello World.
"#.into(); resp.set_content_type("text/html"); Ok(resp) } async fn shutdown(req: Request>>) -> 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() { // Non-async set up. We can do any server configuration that // doesn't need an async context here, parse the command line, // etc. 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); // Pick a random available port on the loopback interface. Not // actually required, but usually a good idea. let ear = TcpListener::bind("127.0.0.1:0").expect("bind port"); let addr = ear.local_addr().expect("retrieve port"); // Here we start up the webview and actually run the server. The // async block is the asynchronous entry point for the program // (like tokio::main or async_std::main), so any server set up // code that needs to run in an async context should be there, as // well as the code to actually run the server. When the async // block finishes executing, the program will close. drteeth::launch( "Tide Demo", addr, async move { app.listen(ear).await.unwrap(); } .race(async move { shutdown_rx.recv().await.unwrap(); }), ) .unwrap(); }