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
use super::{ guid::decode_guid, unescape::{unescape, UnescapeError}, GuidError, }; use crate::{Guid, Launchd}; use std::convert::TryFrom; use thiserror::Error; #[derive(Debug, Clone, Error)] pub enum LaunchdError { #[error("Could not unescape: {0}")] UnescapeError(#[from] UnescapeError), #[error("GUID error: {0}")] GuidError(#[from] GuidError), #[error("Unknown key")] UnknownKey, #[error("Env is duplicate")] EnvDuplicate, #[error("Env is missing")] EnvMissing, } impl Launchd { fn decode_env(env_str: &str, env: &mut Option<String>) -> Result<(), LaunchdError> { if env.is_none() { let env_str = unescape(env_str)?; *env = Some(env_str); Ok(()) } else { Err(LaunchdError::EnvDuplicate) } } fn decode_key_value( key_value: &str, env: &mut Option<String>, guid: &mut Option<Guid>, ) -> Result<(), LaunchdError> { if let Some(env_str) = key_value.strip_prefix("env=") { Launchd::decode_env(env_str, env) } else if let Some(guid_str) = key_value.strip_prefix("guid=") { decode_guid(guid_str, guid)?; Ok(()) } else { Err(LaunchdError::UnknownKey) } } } impl TryFrom<&str> for Launchd { type Error = LaunchdError; fn try_from(server_address: &str) -> Result<Self, Self::Error> { let mut env = None; let mut guid = None; for key_value in server_address.split(',') { Launchd::decode_key_value(key_value, &mut env, &mut guid)?; } if let Some(env) = env { Ok(Launchd { env, guid }) } else { Err(LaunchdError::EnvMissing) } } }