venues 0.3.2

Privacy friendly online meeting service
Documentation
mod acme;
mod reps;
mod session;
mod talk;

use async_std::{channel::unbounded, stream::StreamExt};
use futures::{select, stream::FuturesUnordered, FutureExt};
use log::*;

#[async_std::main]
async fn main() {
    env_logger::init();

    let bind = std::env::var("LISTEN_ON").unwrap_or("localhost:0".to_owned());
    let domains = std::env::var("DOMAIN")
        .unwrap_or_else(|_| {
            bind.rsplit_once(":")
                .map(|(host, _port)| host.to_owned())
                .unwrap_or(bind.clone())
        })
        .split(",")
        .map(|s| s.to_owned())
        .collect::<Vec<_>>();
    let contact = std::env::var("CONTACT").ok();
    let prod = std::env::var("ENV") == Ok("production".to_owned());
    let mut works = FuturesUnordered::new();

    info!("Binding {bind} for domains {domains:?}, ACME contact {contact:?}, prod: {prod}");

    loop {
        let (todo_tx, todo_rx) = unbounded();
        let (rep_tx, rep_rx) = unbounded();
        let (ban_tx, ban_rx) = unbounded();
        let (cert_tx, cert_rx) = unbounded();

        let mut reps = Box::pin(reps::reps(rep_rx, ban_tx)).fuse();
        let mut talk = Box::pin(talk::talk(
            bind.clone(),
            todo_tx,
            rep_tx,
            ban_rx,
            talk::new_certs(domains.clone(), cert_rx),
        ))
        .fuse();
        let mut acme = Box::pin(acme::acme(
            prod,
            &bind,
            &domains,
            contact.as_ref(),
            cert_tx.clone(),
            None // TODO: webserver
        ))
        .fuse();

        loop {
            select! {
                _ = acme => {}
                res = talk =>  res.expect("processing"),
                todo = todo_rx.recv().fuse() => if let Ok(fut) = todo { works.push(fut) },
                _ = reps => break,
                _ = (&mut works).for_each(|_|{}).fuse() => {

                }
            }
        }
    }
}