use std::{collections::HashMap, process::Command};
use super::{Transport, Unix, UnixSocket};
use crate::{
Result,
runtime::{Runtime, process},
};
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct Launchd {
pub(super) env: String,
}
impl Launchd {
pub fn new(env: &str) -> Self {
Self {
env: env.to_string(),
}
}
pub fn env(&self) -> &str {
&self.env
}
pub(super) async fn bus_address(&self, runtime: &Runtime) -> Result<Transport> {
let mut command = Command::new("launchctl");
command.args(["getenv", self.env()]);
let printed = process::stdout(runtime, command)
.await
.map_err(|e| crate::Error::Address(format!("The launchctl command failed: {e}")))?;
let addr = String::from_utf8(printed).map_err(|e| {
crate::Error::Address(format!("Unable to parse launchctl output as UTF-8: {e}"))
})?;
Ok(Transport::Unix(Unix::new(UnixSocket::File(
addr.trim().into(),
))))
}
pub(super) fn from_options(opts: HashMap<&str, &str>) -> Result<Self> {
opts.get("env")
.ok_or_else(|| crate::Error::Address("missing env key".into()))
.map(|env| Self {
env: env.to_string(),
})
}
}
impl std::fmt::Display for Launchd {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "launchd:env={}", self.env)
}
}