1use cfg_if::cfg_if;
2use std::io;
3
4#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
6#[cfg_attr(feature = "clap", derive(::clap::ValueEnum))]
7#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
8#[cfg_attr(feature = "clap", clap(rename_all = "lowercase"))]
9#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
10pub enum ServiceManagerKind {
11 Launchd,
13
14 OpenRc,
16
17 Rcd,
19
20 Sc,
22
23 Systemd,
25
26 WinSw,
28}
29
30impl ServiceManagerKind {
31 pub fn native() -> io::Result<ServiceManagerKind> {
33 cfg_if! {
34 if #[cfg(target_os = "macos")] {
35 Ok(ServiceManagerKind::Launchd)
36 } else if #[cfg(target_os = "windows")] {
37 use super::{ServiceManager, TypedServiceManager};
38
39 let manager = TypedServiceManager::target(ServiceManagerKind::WinSw);
42 if let Ok(true) = manager.available() {
43 return Ok(ServiceManagerKind::WinSw);
44 }
45
46 Ok(ServiceManagerKind::Sc)
47 } else if #[cfg(any(
48 target_os = "freebsd",
49 target_os = "dragonfly",
50 target_os = "openbsd",
51 target_os = "netbsd"
52 ))] {
53 Ok(ServiceManagerKind::Rcd)
54 } else if #[cfg(target_os = "linux")] {
55 use super::{ServiceManager, TypedServiceManager};
56
57 let manager = TypedServiceManager::target(ServiceManagerKind::Systemd);
58 if let Ok(true) = manager.available() {
59 return Ok(ServiceManagerKind::Systemd);
60 }
61
62 let manager = TypedServiceManager::target(ServiceManagerKind::OpenRc);
63 if let Ok(true) = manager.available() {
64 return Ok(ServiceManagerKind::OpenRc);
65 }
66
67 Err(io::Error::new(
68 io::ErrorKind::Unsupported,
69 "Only systemd and openrc are supported on Linux",
70 ))
71 } else {
72 Err(io::Error::new(
73 io::ErrorKind::Unsupported,
74 "Service manager are not supported on current Operating System!",
75 ))
76 }
77 }
78 }
79}