dbus_server_address_parser/decode/
launchd.rs

1use super::{
2    guid::decode_guid,
3    unescape::{unescape, UnescapeError},
4    GuidError,
5};
6use crate::{Guid, Launchd};
7use std::convert::TryFrom;
8use thiserror::Error;
9
10#[derive(Debug, Clone, Error)]
11pub enum LaunchdError {
12    #[error("Could not unescape: {0}")]
13    UnescapeError(#[from] UnescapeError),
14    #[error("GUID error: {0}")]
15    GuidError(#[from] GuidError),
16    #[error("Unknown key")]
17    UnknownKey,
18    #[error("Env is duplicate")]
19    EnvDuplicate,
20    #[error("Env is missing")]
21    EnvMissing,
22}
23
24impl Launchd {
25    fn decode_env(env_str: &str, env: &mut Option<String>) -> Result<(), LaunchdError> {
26        if env.is_none() {
27            let env_str = unescape(env_str)?;
28            *env = Some(env_str);
29            Ok(())
30        } else {
31            Err(LaunchdError::EnvDuplicate)
32        }
33    }
34
35    fn decode_key_value(
36        key_value: &str,
37        env: &mut Option<String>,
38        guid: &mut Option<Guid>,
39    ) -> Result<(), LaunchdError> {
40        if let Some(env_str) = key_value.strip_prefix("env=") {
41            Launchd::decode_env(env_str, env)
42        } else if let Some(guid_str) = key_value.strip_prefix("guid=") {
43            decode_guid(guid_str, guid)?;
44            Ok(())
45        } else {
46            Err(LaunchdError::UnknownKey)
47        }
48    }
49}
50
51impl TryFrom<&str> for Launchd {
52    type Error = LaunchdError;
53
54    fn try_from(server_address: &str) -> Result<Self, Self::Error> {
55        let mut env = None;
56        let mut guid = None;
57
58        for key_value in server_address.split(',') {
59            Launchd::decode_key_value(key_value, &mut env, &mut guid)?;
60        }
61
62        if let Some(env) = env {
63            Ok(Launchd { env, guid })
64        } else {
65            Err(LaunchdError::EnvMissing)
66        }
67    }
68}