zero-trust-rps 0.1.1

Online Multiplayer Rock Paper Scissors
Documentation
use std::{ffi::c_int, future::Future};

use futures::StreamExt as _;
use signal_hook::consts::signal::SIGHUP;
use signal_hook_tokio::Signals;
use tokio::task::JoinError;

const SIGNALS: &[c_int] = &[
    SIGHUP,
    // TODO: SIGINT, SIGQUIT, SIGTERM
];

async fn handle_signals(mut signals: Signals, handler: impl SignalHandler) {
    while let Some(signal) = signals.next().await {
        match signal {
            SIGHUP => handler.reload_config().await,
            // TODO: SIGTERM | SIGINT | SIGQUIT => handler.shutdown().await,
            _ => unreachable!(),
        }
    }
}

pub trait SignalHandler {
    // TODO: fn shutdown(&self) -> impl Future<Output = ()> + Send;
    fn reload_config(&self) -> impl Future<Output = ()> + Send;
}

pub fn run_and_configure_signals(
    handler: impl SignalHandler + Send + 'static,
) -> Result<impl Future<Output = Result<(), JoinError>>, std::io::Error> {
    let signals = Signals::new(SIGNALS)?;

    let handle = signals.handle();

    let signals_task = tokio::spawn(handle_signals(signals, handler));

    Ok(async move {
        handle.close();
        signals_task.await
    })
}