homebrew/model/
service.rs

1use serde::{Serialize, Deserialize};
2use std::str::FromStr;
3use std::fmt;
4
5// 定义状态枚举
6#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
7#[serde(rename_all = "lowercase")] // 使得枚举可以接受小写字符串
8pub enum ServiceStatus {
9    None,
10    Started,
11    Error,
12}
13
14// 实现从字符串转换为枚举
15impl FromStr for ServiceStatus {
16    type Err = ();
17
18    fn from_str(input: &str) -> Result<Self, Self::Err> {
19        match input {
20            "none" => Ok(ServiceStatus::None),
21            "started" => Ok(ServiceStatus::Started),
22            "error" => Ok(ServiceStatus::Error),
23            _ => Err(()),
24        }
25    }
26}
27
28// 实现 Display trait 以便打印
29impl fmt::Display for ServiceStatus {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            ServiceStatus::None => write!(f, "none"),
33            ServiceStatus::Started => write!(f, "started"),
34            ServiceStatus::Error => write!(f, "error"),
35        }
36    }
37}
38
39/// `Service` 的结构体
40#[derive(Debug, Serialize, Deserialize, Clone)]
41pub struct Service {
42    pub name: String,
43    pub status: ServiceStatus,
44    pub user: Option<String>,
45    pub file: String,
46    pub exit_code: Option<i8>,
47}
48
49impl Service {
50    /// 通过 `json` 字符串来新建结构体
51    ///
52    /// Examples
53    ///
54    /// ```
55    /// use homebrew;
56    ///
57    /// let json_str = r#"
58    /// {
59    ///     "name": "mongodb-community@7.0",
60    ///     "status": "none",
61    ///     "user": "wxnacy",
62    ///     "file": "/Users/wxnacy/Library/LaunchAgents/homebrew.mxcl.mongodb-community@7.0.plist",
63    ///     "exit_code": null
64    /// }
65    /// "#;
66    ///
67    /// let s = homebrew::Service::from(&json_str).unwrap();
68    ///
69    /// assert_eq!(s.name, "mongodb-community@7.0");
70    /// ```
71    pub fn from(json_str: &str) -> anyhow::Result<Self> {
72        let pkg: Self = serde_json::from_str(json_str)?;
73        Ok(pkg)
74    }
75}
76
77/// 具体服务详情结构体
78#[derive(Debug, Serialize, Deserialize, Clone)]
79pub struct ServiceInfo {
80    pub name: String,
81    pub service_name: String,
82    pub running: bool,
83    pub loaded: bool,
84    pub schedulable: bool,
85    pub pid: Option<u32>,
86    pub exit_code: Option<i32>,
87    pub user: Option<String>,
88    pub status: ServiceStatus, // 使用枚举代替字符串
89    pub file: String,
90    pub command: String,
91    pub working_dir: Option<String>,
92    pub root_dir: Option<String>,
93    pub log_path: Option<String>,
94    pub error_log_path: Option<String>,
95    pub interval: Option<String>,
96    pub cron: Option<String>,
97}
98
99impl ServiceInfo {
100    /// 通过 `json` 字符串来新建结构体
101    ///
102    /// Examples
103    ///
104    /// ```
105    /// use homebrew;
106    /// use homebrew::ServiceStatus;
107    ///
108    /// let json_str = r#"
109    /// {
110    ///     "name": "redis",
111    ///     "service_name": "homebrew.mxcl.redis",
112    ///     "running": false,
113    ///     "loaded": false,
114    ///     "schedulable": false,
115    ///     "pid": null,
116    ///     "exit_code": null,
117    ///     "user": null,
118    ///     "status": "none",
119    ///     "file": "/opt/homebrew/opt/redis/homebrew.mxcl.redis.plist",
120    ///     "command": "/opt/homebrew/opt/redis/bin/redis-server /opt/homebrew/etc/redis.conf",
121    ///     "working_dir": "/opt/homebrew/var",
122    ///     "root_dir": null,
123    ///     "log_path": "/opt/homebrew/var/log/redis.log",
124    ///     "error_log_path": "/opt/homebrew/var/log/redis.log",
125    ///     "interval": null,
126    ///     "cron": null
127    /// }
128    /// "#;
129    ///
130    /// let s = homebrew::ServiceInfo::from(&json_str).unwrap();
131    ///
132    /// assert_eq!(s.name, "redis");
133    /// assert_eq!(s.status, ServiceStatus::None);
134    /// ```
135    pub fn from(json_str: &str) -> anyhow::Result<Self> {
136        let pkg: Self = serde_json::from_str(json_str)?;
137        Ok(pkg)
138    }
139}