mod base;
#[doc = include_str!("../README.md")]
mod readme_tests {}
#[cfg(windows)]
mod win_service;
pub use base::BaseService;
use std::sync::mpsc::channel;
#[cfg(windows)]
use win_service::start_service;
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub trait ServiceApp {
fn name(&self) -> &str;
fn start(&mut self) -> Result<()>;
fn stop(&mut self) -> Result<()>;
}
#[cfg(not(windows))]
fn start_service(mut app: Box<dyn ServiceApp + Send>) -> Result<()> {
run_interactive(&mut *app)
}
fn run_interactive(app: &mut (dyn ServiceApp + Send + 'static)) -> Result<()> {
app.start()?;
wait_for_shutdown()?;
app.stop()?;
Ok(())
}
pub fn run_service(mut app: impl ServiceApp + Send + 'static, service_mode: bool) -> Result<()> {
if service_mode {
start_service(Box::new(app))
} else {
run_interactive(&mut app)
}
}
fn wait_for_shutdown() -> Result<()> {
let (tx, rx) = channel();
ctrlc::set_handler(move || tx.send(()).expect("Could not send signal on channel."))?;
rx.recv()?;
Ok(())
}