support_kit/service/
service_name.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use serde::{Deserialize, Serialize};
use service_manager::ServiceLabel;
use std::{ffi::OsStr, fmt::Display, path::Path, str::FromStr};

use crate::InvalidServiceLabelError;

pub fn get_runtime_name() -> String {
    std::env::var("CARGO_PKG_NAME").unwrap_or_default()
}

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
pub struct ServiceName(String);

impl ServiceName {
    pub fn as_default_label(&self) -> Result<ServiceLabel, InvalidServiceLabelError> {
        let label_candidate = format!("local.{name}.service", name = self.0);
        Ok(label_candidate.parse()?)
    }
}

impl Default for ServiceName {
    fn default() -> Self {
        Self(get_runtime_name())
    }
}

impl Display for ServiceName {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl From<ServiceName> for String {
    fn from(service_name: ServiceName) -> Self {
        service_name.0
    }
}

impl FromStr for ServiceName {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Self(s.to_string()))
    }
}

impl From<&str> for ServiceName {
    fn from(s: &str) -> Self {
        Self(s.to_string())
    }
}

impl AsRef<str> for ServiceName {
    fn as_ref(&self) -> &str {
        &self.0
    }
}

impl AsRef<OsStr> for ServiceName {
    fn as_ref(&self) -> &OsStr {
        self.0.as_ref()
    }
}

impl AsRef<Path> for ServiceName {
    fn as_ref(&self) -> &Path {
        self.0.as_ref()
    }
}

#[test]
fn default_name() -> Result<(), Box<dyn std::error::Error>> {
    use figment::Jail;

    let config: ServiceName = serde_json::from_str(r#""support-kit""#)?;

    assert_eq!(config, ServiceName::default());
    assert_eq!(config, ServiceName::from("support-kit"));

    Jail::expect_with(|jail| {
        jail.set_env("CARGO_PKG_NAME", "consumer-package");

        let config: ServiceName =
            serde_json::from_str(r#""consumer-package""#).expect("failed to parse");

        assert_eq!(config, ServiceName::default());
        assert_eq!(config, ServiceName::from("consumer-package"));

        Ok(())
    });
    Ok(())
}

#[test]
fn custom_name() -> Result<(), Box<dyn std::error::Error>> {
    let config: ServiceName = serde_json::from_str(r#""custom-name""#)?;

    assert_eq!(config, ServiceName::from("custom-name"));

    Ok(())
}