use std::{ collections::*, error::Error, }; use std::convert::{Infallible}; use std::io::Write; use std::net::SocketAddr; use std::path::Path; use std::str::FromStr; use std::sync::{ Arc }; use std::time::{Duration, Instant}; use futures::channel::oneshot; use hyper::{Body, Request, Response, Server, StatusCode}; use hyper::service::{make_service_fn, service_fn}; use tokio::{ sync::Mutex, time::delay_for, }; use ptth::watcher::Watchers; #[derive (Clone)] enum Message { Meow, } #[derive (Default)] struct ServerState { watchers: Arc >>, } fn status_reply > (status: StatusCode, b: B) -> Response { Response::builder ().status (status).body (b.into ()).unwrap () } async fn handle_watch (state: Arc ) -> Response { match Watchers::long_poll (state.watchers.clone ()).await { None => status_reply (StatusCode::OK, "no\n"), Some (_) => status_reply (StatusCode::OK, "actually, yes\n"), } } async fn handle_wake (state: Arc ) -> Response { let mut watchers = state.watchers.lock ().await; watchers.wake_all (Message::Meow); status_reply (StatusCode::OK, "ok\n") } async fn handle_udp_send () -> Response { use tokio::net::UdpSocket; let mut sock = UdpSocket::bind (SocketAddr::from (([0,0,0,0], 0))).await.unwrap (); sock.send_to (b"handle_udp_send\n", SocketAddr::from (([127,0,0,1], 9000u16))).await.unwrap (); status_reply (StatusCode::OK, "ok\n") } async fn handle_all (req: Request , state: Arc ) -> Result , Infallible> { let uri = req.uri (); println! ("{}", uri); if uri == "/watch" { Ok (handle_watch (state).await) } else if uri == "/wake" { Ok (handle_wake (state).await) } else if uri == "/udp_send" { Ok (handle_udp_send ().await) } else { Ok (status_reply (StatusCode::OK, "Hi\n")) } } #[tokio::main] async fn main () -> Result <(), Box > { let addr = SocketAddr::from(([0, 0, 0, 0], 4000)); let state = Arc::new (ServerState::default ()); let make_svc = make_service_fn (|_conn| { let state = state.clone (); async { Ok::<_, Infallible> (service_fn (move |req| { let state = state.clone (); handle_all (req, state) })) } }); let server = Server::bind (&addr).serve (make_svc); server.await?; Ok (()) }