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}