printnanny_dbus/systemd1/
models.rs1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4use zbus_systemd::systemd1::UnitProxy;
5
6use crate::error::SystemdError;
7use printnanny_asyncapi_models;
8
9pub const PRINTNANNY_RECORDING_SERVICE_TEMPLATE: &str = "printnanny-recording-sync@";
10
11#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
14pub enum SystemdLoadState {
15 #[serde(rename = "loaded")]
16 Loaded,
17 #[serde(rename = "error")]
18 Error,
19 #[serde(rename = "masked")]
20 Masked,
21 #[serde(rename = "not-found")]
22 NotFound,
23}
24
25impl FromStr for SystemdLoadState {
26 type Err = SystemdError;
27 fn from_str(input: &str) -> Result<SystemdLoadState, Self::Err> {
28 match input {
29 "loaded" => Ok(SystemdLoadState::Loaded),
30 "error" => Ok(SystemdLoadState::Error),
31 "masked" => Ok(SystemdLoadState::Masked),
32 "not-found" => Ok(SystemdLoadState::NotFound),
33 _ => Err(SystemdError::InvalidUnitLoadState {
34 state: input.to_string(),
35 }),
36 }
37 }
38}
39
40#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
43pub enum SystemdActiveState {
44 #[serde(rename = "active")]
45 Active,
46 #[serde(rename = "activating")]
47 Activating,
48 #[serde(rename = "deactivating")]
49 Deactivating,
50 #[serde(rename = "failed")]
51 Failed,
52 #[serde(rename = "inactive")]
53 Inactive,
54 #[serde(rename = "reloading")]
55 Reloading,
56 #[serde(rename = "loaded")]
57 Loaded,
58}
59
60impl FromStr for SystemdActiveState {
61 type Err = SystemdError;
62 fn from_str(input: &str) -> Result<SystemdActiveState, Self::Err> {
63 match input {
64 "active" => Ok(SystemdActiveState::Active),
65 "activating" => Ok(SystemdActiveState::Activating),
66 "deactivating" => Ok(SystemdActiveState::Deactivating),
67 "failed" => Ok(SystemdActiveState::Failed),
68 "inactive" => Ok(SystemdActiveState::Inactive),
69 "reloading" => Ok(SystemdActiveState::Reloading),
70 "loaded" => Ok(SystemdActiveState::Loaded),
71 _ => Err(SystemdError::InvalidUnitActiveState {
72 state: input.to_string(),
73 }),
74 }
75 }
76}
77
78#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
81pub enum SystemdUnitFileState {
82 #[serde(rename = "enabled")]
83 Enabled,
84 #[serde(rename = "enabled-runtime")]
85 EnabledRuntime,
86 #[serde(rename = "linked")]
87 Linked,
88 #[serde(rename = "linked-runtime")]
89 LinkedRuntime,
90 #[serde(rename = "masked")]
91 Masked,
92 #[serde(rename = "masked-runtime")]
93 MaskedRuntime,
94 #[serde(rename = "static")]
95 Static,
96 #[serde(rename = "disabled")]
97 Disabled,
98 #[serde(rename = "invalid")]
99 Invalid,
100}
101
102impl FromStr for SystemdUnitFileState {
103 type Err = SystemdError;
104 fn from_str(input: &str) -> Result<SystemdUnitFileState, Self::Err> {
105 match input {
106 "enabled" => Ok(SystemdUnitFileState::Enabled),
107 "enabled-runtime" => Ok(SystemdUnitFileState::EnabledRuntime),
108 "linked" => Ok(SystemdUnitFileState::Linked),
109 "linked-runtime" => Ok(SystemdUnitFileState::LinkedRuntime),
110 "masked" => Ok(SystemdUnitFileState::Masked),
111 "masked-runtime" => Ok(SystemdUnitFileState::MaskedRuntime),
112 "static" => Ok(SystemdUnitFileState::Static),
113 "disabled" => Ok(SystemdUnitFileState::Disabled),
114 "invalid" => Ok(SystemdUnitFileState::Invalid),
115 _ => Err(SystemdError::InvalidUnitFileState {
116 state: input.to_string(),
117 }),
118 }
119 }
120}
121
122#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
125pub enum SystemdSubState {}
126
127#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
128pub struct SystemdUnit {
129 pub id: String,
132 pub fragment_path: String,
133 pub load_state: SystemdLoadState, pub load_error: (String, String), pub active_state: SystemdActiveState, pub unit_file_state: SystemdUnitFileState, }
138
139impl SystemdUnit {
140 pub async fn from_owned_object_path(
141 path: zbus::zvariant::OwnedObjectPath,
142 ) -> Result<SystemdUnit, SystemdError> {
143 let connection = zbus::Connection::system().await?;
144 let unit = UnitProxy::new(&connection, path.clone()).await?;
145
146 let unit_file_state = unit.unit_file_state().await?;
147 let load_path = unit.load_state().await?;
148 let active_state = unit.active_state().await?;
149
150 let load_state = SystemdLoadState::from_str(&load_path)?;
151 if load_state == SystemdLoadState::NotFound {
152 return Err(SystemdError::UnitNotFound {
153 unit: path.to_string(),
154 });
155 }
156
157 let result = SystemdUnit {
158 load_state,
159 id: unit.id().await?,
160 fragment_path: unit.fragment_path().await?,
161 active_state: SystemdActiveState::from_str(&active_state)?,
162 unit_file_state: SystemdUnitFileState::from_str(&unit_file_state)?,
163 load_error: unit.load_error().await?,
164 };
165
166 Ok(result)
167 }
168}
169
170impl From<SystemdUnit> for printnanny_asyncapi_models::SystemdUnit {
171 fn from(unit: SystemdUnit) -> printnanny_asyncapi_models::SystemdUnit {
172 let active_state = match unit.active_state {
173 SystemdActiveState::Active => {
174 printnanny_asyncapi_models::SystemdUnitActiveState::Active
175 }
176 SystemdActiveState::Loaded => {
177 printnanny_asyncapi_models::SystemdUnitActiveState::Loaded
178 }
179 SystemdActiveState::Activating => {
180 printnanny_asyncapi_models::SystemdUnitActiveState::Activating
181 }
182 SystemdActiveState::Inactive => {
183 printnanny_asyncapi_models::SystemdUnitActiveState::Inactive
184 }
185 SystemdActiveState::Reloading => {
186 printnanny_asyncapi_models::SystemdUnitActiveState::Reloading
187 }
188 SystemdActiveState::Deactivating => {
189 printnanny_asyncapi_models::SystemdUnitActiveState::Deactivating
190 }
191 SystemdActiveState::Failed => {
192 printnanny_asyncapi_models::SystemdUnitActiveState::Failed
193 }
194 };
195
196 let load_state = match unit.load_state {
197 SystemdLoadState::Masked => printnanny_asyncapi_models::SystemdUnitLoadState::Masked,
198 SystemdLoadState::Error => printnanny_asyncapi_models::SystemdUnitLoadState::Error,
199 SystemdLoadState::Loaded => printnanny_asyncapi_models::SystemdUnitLoadState::Loaded,
200 SystemdLoadState::NotFound => {
201 printnanny_asyncapi_models::SystemdUnitLoadState::NotMinusFound
202 }
203 };
204
205 let unit_file_state = match unit.unit_file_state {
206 SystemdUnitFileState::Enabled => {
207 printnanny_asyncapi_models::SystemdUnitFileState::Enabled
208 }
209 SystemdUnitFileState::EnabledRuntime => {
210 printnanny_asyncapi_models::SystemdUnitFileState::EnabledMinusRuntime
211 }
212 SystemdUnitFileState::Disabled => {
213 printnanny_asyncapi_models::SystemdUnitFileState::Disabled
214 }
215 SystemdUnitFileState::Linked => {
216 printnanny_asyncapi_models::SystemdUnitFileState::Linked
217 }
218 SystemdUnitFileState::LinkedRuntime => {
219 printnanny_asyncapi_models::SystemdUnitFileState::LinkedMinusRuntime
220 }
221 SystemdUnitFileState::Masked => {
222 printnanny_asyncapi_models::SystemdUnitFileState::Masked
223 }
224 SystemdUnitFileState::MaskedRuntime => {
225 printnanny_asyncapi_models::SystemdUnitFileState::MaskedMinusRuntime
226 }
227 SystemdUnitFileState::Static => {
228 printnanny_asyncapi_models::SystemdUnitFileState::Static
229 }
230 SystemdUnitFileState::Invalid => {
231 printnanny_asyncapi_models::SystemdUnitFileState::Invalid
232 }
233 };
234
235 printnanny_asyncapi_models::SystemdUnit {
236 id: unit.id,
237 fragment_path: unit.fragment_path,
238 active_state: Box::new(active_state),
239 load_state: Box::new(load_state),
240 unit_file_state: Box::new(unit_file_state),
241 }
242 }
243}