use std::path::Path;
use std::borrow::Cow;
use chan::Receiver;
use chan_signal::Signal;
use logging::LogOptions;
pub enum Stopping {
Yes,
No
}
pub trait Config {
fn load<O: Options>(_: &O) -> Self;
}
pub trait Options : LogOptions {
fn load() -> Self;
fn config_path<'a>(&'a self) -> Cow<'a, Path>;
}
pub struct Context {
pub(crate) signal: Receiver<Signal>
}
impl Context {
pub fn poll_signals<A: Application>(&self, app: &mut A) {
let signal = &self.signal;
loop {
chan_select! {
default => { break; },
signal.recv() -> sig => {
debug!("Received signal: {:?}", sig);
sig.map(|s| app.received_signal(s));
},
}
}
}
}
pub trait Application: Sized {
type Err: Send + 'static;
type Config: Config;
type Options: Options;
fn new(_: Self::Options, _: Self::Config) -> Result<Self, Self::Err>;
fn run_once(&mut self, context: &Context) -> Result<Stopping, Self::Err>;
fn signals() -> &'static [Signal] {
static SIGNALS: &[Signal] = &[Signal::INT, Signal::TERM];
SIGNALS
}
fn received_signal(&mut self, _: Signal) {
die!("received_signal default action");
}
fn shutdown(self) -> Result<(), Self::Err> {
Ok(())
}
}