1use super::{
2 LaunchdServiceManager, OpenRcServiceManager, RcdServiceManager, ScServiceManager,
3 ServiceInstallCtx, ServiceLevel, ServiceManager, ServiceManagerKind, ServiceStartCtx,
4 ServiceStopCtx, ServiceUninstallCtx, SystemdServiceManager, WinSwServiceManager,
5};
6use std::io;
7
8#[derive(Clone, Debug, PartialEq, Eq)]
10pub enum TypedServiceManager {
11 Launchd(LaunchdServiceManager),
12 OpenRc(OpenRcServiceManager),
13 Rcd(RcdServiceManager),
14 Sc(ScServiceManager),
15 Systemd(SystemdServiceManager),
16 WinSw(WinSwServiceManager),
17}
18
19macro_rules! using {
20 ($self:ident, $this:ident -> $expr:expr) => {{
21 match $self {
22 TypedServiceManager::Launchd($this) => $expr,
23 TypedServiceManager::OpenRc($this) => $expr,
24 TypedServiceManager::Rcd($this) => $expr,
25 TypedServiceManager::Sc($this) => $expr,
26 TypedServiceManager::Systemd($this) => $expr,
27 TypedServiceManager::WinSw($this) => $expr,
28 }
29 }};
30}
31
32impl ServiceManager for TypedServiceManager {
33 fn available(&self) -> io::Result<bool> {
34 using!(self, x -> x.available())
35 }
36
37 fn install(&self, ctx: ServiceInstallCtx) -> io::Result<()> {
38 using!(self, x -> x.install(ctx))
39 }
40
41 fn uninstall(&self, ctx: ServiceUninstallCtx) -> io::Result<()> {
42 using!(self, x -> x.uninstall(ctx))
43 }
44
45 fn start(&self, ctx: ServiceStartCtx) -> io::Result<()> {
46 using!(self, x -> x.start(ctx))
47 }
48
49 fn stop(&self, ctx: ServiceStopCtx) -> io::Result<()> {
50 using!(self, x -> x.stop(ctx))
51 }
52
53 fn level(&self) -> ServiceLevel {
54 using!(self, x -> x.level())
55 }
56
57 fn set_level(&mut self, level: ServiceLevel) -> io::Result<()> {
58 using!(self, x -> x.set_level(level))
59 }
60
61 fn status(&self, ctx: crate::ServiceStatusCtx) -> io::Result<crate::ServiceStatus> {
62 using!(self, x -> x.status(ctx))
63 }
64}
65
66impl TypedServiceManager {
67 pub fn target_or_native(kind: impl Into<Option<ServiceManagerKind>>) -> io::Result<Self> {
70 match kind.into() {
71 Some(kind) => Ok(Self::target(kind)),
72 None => Self::native(),
73 }
74 }
75
76 pub fn target(kind: ServiceManagerKind) -> Self {
79 match kind {
80 ServiceManagerKind::Launchd => Self::Launchd(LaunchdServiceManager::default()),
81 ServiceManagerKind::OpenRc => Self::OpenRc(OpenRcServiceManager::default()),
82 ServiceManagerKind::Rcd => Self::Rcd(RcdServiceManager::default()),
83 ServiceManagerKind::Sc => Self::Sc(ScServiceManager::default()),
84 ServiceManagerKind::Systemd => Self::Systemd(SystemdServiceManager::default()),
85 ServiceManagerKind::WinSw => Self::WinSw(WinSwServiceManager::default()),
86 }
87 }
88
89 pub fn native() -> io::Result<Self> {
96 Ok(Self::target(ServiceManagerKind::native()?))
97 }
98
99 pub fn into_box(self) -> Box<dyn ServiceManager> {
101 using!(self, x -> Box::new(x))
102 }
103
104 pub fn is_launchd(&self) -> bool {
106 matches!(self, Self::Launchd(_))
107 }
108
109 pub fn is_openrc(&self) -> bool {
111 matches!(self, Self::OpenRc(_))
112 }
113
114 pub fn is_rc_d(&self) -> bool {
116 matches!(self, Self::Rcd(_))
117 }
118
119 pub fn is_sc(&self) -> bool {
121 matches!(self, Self::Sc(_))
122 }
123
124 pub fn is_systemd(&self) -> bool {
126 matches!(self, Self::Systemd(_))
127 }
128
129 pub fn is_winsw(&self) -> bool {
131 matches!(self, Self::WinSw(_))
132 }
133}
134
135impl From<super::LaunchdServiceManager> for TypedServiceManager {
136 fn from(manager: super::LaunchdServiceManager) -> Self {
137 Self::Launchd(manager)
138 }
139}
140
141impl From<super::OpenRcServiceManager> for TypedServiceManager {
142 fn from(manager: super::OpenRcServiceManager) -> Self {
143 Self::OpenRc(manager)
144 }
145}
146
147impl From<super::RcdServiceManager> for TypedServiceManager {
148 fn from(manager: super::RcdServiceManager) -> Self {
149 Self::Rcd(manager)
150 }
151}
152
153impl From<super::ScServiceManager> for TypedServiceManager {
154 fn from(manager: super::ScServiceManager) -> Self {
155 Self::Sc(manager)
156 }
157}
158
159impl From<super::SystemdServiceManager> for TypedServiceManager {
160 fn from(manager: super::SystemdServiceManager) -> Self {
161 Self::Systemd(manager)
162 }
163}
164
165impl From<super::WinSwServiceManager> for TypedServiceManager {
166 fn from(manager: super::WinSwServiceManager) -> Self {
167 Self::WinSw(manager)
168 }
169}