ptth/src/main.rs

104 lines
2.0 KiB
Rust

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,
};
mod watcher;
use watcher::Watchers;
#[derive (Clone)]
enum Message {
Meow,
}
#[derive (Default)]
struct ServerState {
watchers: Arc <Mutex <Watchers <Message>>>,
}
fn status_reply <B: Into <Body>> (status: StatusCode, b: B)
-> Response <Body>
{
Response::builder ().status (status).body (b.into ()).unwrap ()
}
async fn handle_watch (state: Arc <ServerState>)
-> Response <Body>
{
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 <ServerState>)
-> Response <Body>
{
let mut watchers = state.watchers.lock ().await;
watchers.wake_all (Message::Meow);
status_reply (StatusCode::OK, "ok\n")
}
async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
-> Result <Response <Body>, 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 {
Ok (status_reply (StatusCode::OK, "Hi\n"))
}
}
#[tokio::main]
async fn main () -> Result <(), Box <dyn Error>> {
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 (())
}