use super::{
LaunchdServiceManager, OpenRcServiceManager, RcdServiceManager, ScServiceManager,
ServiceInstallCtx, ServiceLevel, ServiceManager, ServiceManagerKind, ServiceStartCtx,
ServiceStopCtx, ServiceUninstallCtx, SystemdServiceManager, WinSwServiceManager,
};
use std::io;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TypedServiceManager {
Launchd(LaunchdServiceManager),
OpenRc(OpenRcServiceManager),
Rcd(RcdServiceManager),
Sc(ScServiceManager),
Systemd(SystemdServiceManager),
WinSw(WinSwServiceManager),
}
macro_rules! using {
($self:ident, $this:ident -> $expr:expr) => {{
match $self {
TypedServiceManager::Launchd($this) => $expr,
TypedServiceManager::OpenRc($this) => $expr,
TypedServiceManager::Rcd($this) => $expr,
TypedServiceManager::Sc($this) => $expr,
TypedServiceManager::Systemd($this) => $expr,
TypedServiceManager::WinSw($this) => $expr,
}
}};
}
impl ServiceManager for TypedServiceManager {
fn available(&self) -> io::Result<bool> {
using!(self, x -> x.available())
}
fn install(&self, ctx: ServiceInstallCtx) -> io::Result<()> {
using!(self, x -> x.install(ctx))
}
fn uninstall(&self, ctx: ServiceUninstallCtx) -> io::Result<()> {
using!(self, x -> x.uninstall(ctx))
}
fn start(&self, ctx: ServiceStartCtx) -> io::Result<()> {
using!(self, x -> x.start(ctx))
}
fn stop(&self, ctx: ServiceStopCtx) -> io::Result<()> {
using!(self, x -> x.stop(ctx))
}
fn level(&self) -> ServiceLevel {
using!(self, x -> x.level())
}
fn set_level(&mut self, level: ServiceLevel) -> io::Result<()> {
using!(self, x -> x.set_level(level))
}
}
impl TypedServiceManager {
pub fn target_or_native(kind: impl Into<Option<ServiceManagerKind>>) -> io::Result<Self> {
match kind.into() {
Some(kind) => Ok(Self::target(kind)),
None => Self::native(),
}
}
pub fn target(kind: ServiceManagerKind) -> Self {
match kind {
ServiceManagerKind::Launchd => Self::Launchd(LaunchdServiceManager::default()),
ServiceManagerKind::OpenRc => Self::OpenRc(OpenRcServiceManager::default()),
ServiceManagerKind::Rcd => Self::Rcd(RcdServiceManager::default()),
ServiceManagerKind::Sc => Self::Sc(ScServiceManager::default()),
ServiceManagerKind::Systemd => Self::Systemd(SystemdServiceManager::default()),
ServiceManagerKind::WinSw => Self::WinSw(WinSwServiceManager::default()),
}
}
pub fn native() -> io::Result<Self> {
Ok(Self::target(ServiceManagerKind::native()?))
}
pub fn into_box(self) -> Box<dyn ServiceManager> {
using!(self, x -> Box::new(x))
}
pub fn is_launchd(&self) -> bool {
matches!(self, Self::Launchd(_))
}
pub fn is_openrc(&self) -> bool {
matches!(self, Self::OpenRc(_))
}
pub fn is_rc_d(&self) -> bool {
matches!(self, Self::Rcd(_))
}
pub fn is_sc(&self) -> bool {
matches!(self, Self::Sc(_))
}
pub fn is_systemd(&self) -> bool {
matches!(self, Self::Systemd(_))
}
pub fn is_winsw(&self) -> bool {
matches!(self, Self::WinSw(_))
}
}
impl From<super::LaunchdServiceManager> for TypedServiceManager {
fn from(manager: super::LaunchdServiceManager) -> Self {
Self::Launchd(manager)
}
}
impl From<super::OpenRcServiceManager> for TypedServiceManager {
fn from(manager: super::OpenRcServiceManager) -> Self {
Self::OpenRc(manager)
}
}
impl From<super::RcdServiceManager> for TypedServiceManager {
fn from(manager: super::RcdServiceManager) -> Self {
Self::Rcd(manager)
}
}
impl From<super::ScServiceManager> for TypedServiceManager {
fn from(manager: super::ScServiceManager) -> Self {
Self::Sc(manager)
}
}
impl From<super::SystemdServiceManager> for TypedServiceManager {
fn from(manager: super::SystemdServiceManager) -> Self {
Self::Systemd(manager)
}
}
impl From<super::WinSwServiceManager> for TypedServiceManager {
fn from(manager: super::WinSwServiceManager) -> Self {
Self::WinSw(manager)
}
}