support_kit/service/
service_name.rs

1use serde::{Deserialize, Serialize};
2use service_manager::ServiceLabel;
3use std::{ffi::OsStr, fmt::Display, path::Path, str::FromStr};
4
5use crate::InvalidServiceLabelError;
6
7pub fn get_runtime_name() -> String {
8    std::env::var("CARGO_PKG_NAME").unwrap_or_default()
9}
10
11#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
12pub struct ServiceName(String);
13
14impl ServiceName {
15    pub fn as_default_label(&self) -> Result<ServiceLabel, InvalidServiceLabelError> {
16        let label_candidate = format!("local.{name}.service", name = self.0);
17        Ok(label_candidate.parse()?)
18    }
19}
20
21impl Default for ServiceName {
22    fn default() -> Self {
23        Self(get_runtime_name())
24    }
25}
26
27impl Display for ServiceName {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        write!(f, "{}", self.0)
30    }
31}
32
33impl From<ServiceName> for String {
34    fn from(service_name: ServiceName) -> Self {
35        service_name.0
36    }
37}
38
39impl FromStr for ServiceName {
40    type Err = String;
41
42    fn from_str(s: &str) -> Result<Self, Self::Err> {
43        Ok(Self(s.to_string()))
44    }
45}
46
47impl From<&str> for ServiceName {
48    fn from(s: &str) -> Self {
49        Self(s.to_string())
50    }
51}
52
53impl AsRef<str> for ServiceName {
54    fn as_ref(&self) -> &str {
55        &self.0
56    }
57}
58
59impl AsRef<OsStr> for ServiceName {
60    fn as_ref(&self) -> &OsStr {
61        self.0.as_ref()
62    }
63}
64
65impl AsRef<Path> for ServiceName {
66    fn as_ref(&self) -> &Path {
67        self.0.as_ref()
68    }
69}
70
71#[test]
72fn default_name() -> Result<(), Box<dyn std::error::Error>> {
73    use figment::Jail;
74
75    let config: ServiceName = serde_json::from_str(r#""support-kit""#)?;
76
77    assert_eq!(config, ServiceName::default());
78    assert_eq!(config, ServiceName::from("support-kit"));
79
80    Jail::expect_with(|jail| {
81        jail.set_env("CARGO_PKG_NAME", "consumer-package");
82
83        let config: ServiceName =
84            serde_json::from_str(r#""consumer-package""#).expect("failed to parse");
85
86        assert_eq!(config, ServiceName::default());
87        assert_eq!(config, ServiceName::from("consumer-package"));
88
89        Ok(())
90    });
91    Ok(())
92}
93
94#[test]
95fn custom_name() -> Result<(), Box<dyn std::error::Error>> {
96    let config: ServiceName = serde_json::from_str(r#""custom-name""#)?;
97
98    assert_eq!(config, ServiceName::from("custom-name"));
99
100    Ok(())
101}