dbus_addr/transport/
unixexec.rs1use std::{borrow::Cow, ffi::OsStr, fmt};
2
3use super::{
4 percent::{decode_percents_os_str, decode_percents_str, EncOsStr},
5 DBusAddr, Error, KeyValFmt, Result, TransportImpl,
6};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct Unixexec<'a> {
13 path: Cow<'a, OsStr>,
14 argv: Vec<(usize, Cow<'a, str>)>,
15}
16
17impl<'a> Unixexec<'a> {
18 pub fn path(&self) -> &OsStr {
24 self.path.as_ref()
25 }
26
27 pub fn argv(&self) -> &[(usize, Cow<'a, str>)] {
31 self.argv.as_ref()
32 }
33
34 pub fn into_owned(self) -> Unixexec<'static> {
36 let argv = self
37 .argv
38 .into_iter()
39 .map(|(index, cow)| (index, cow.into_owned().into()))
40 .collect();
41 Unixexec {
42 path: self.path.into_owned().into(),
43 argv,
44 }
45 }
46}
47
48impl<'a> TransportImpl<'a> for Unixexec<'a> {
49 fn for_address(s: &'a DBusAddr<'a>) -> Result<Self> {
50 let mut path = None;
51 let mut argv = Vec::new();
52
53 for (k, v) in s.key_val_iter() {
54 match (k, v) {
55 ("path", Some(v)) => {
56 path = Some(decode_percents_os_str(v)?);
57 }
58 (k, Some(v)) if k.starts_with("argv") => {
59 let n: usize = k[4..].parse().map_err(|_| Error::InvalidValue(k.into()))?;
60 let arg = decode_percents_str(v)?;
61 argv.push((n, arg));
62 }
63 _ => continue,
64 }
65 }
66
67 let Some(path) = path else {
68 return Err(Error::MissingKey("path".into()));
69 };
70
71 argv.sort_by_key(|(num, _)| *num);
72
73 Ok(Self { path, argv })
74 }
75
76 fn fmt_key_val<'s: 'b, 'b>(&'s self, mut kv: KeyValFmt<'b>) -> KeyValFmt<'b> {
77 kv = kv.add("path", Some(EncOsStr(self.path())));
78 for (n, arg) in self.argv() {
79 kv = kv.add(Argv(*n), Some(arg));
80 }
81
82 kv
83 }
84}
85
86#[derive(Debug, PartialEq, Eq)]
87struct Argv(usize);
88
89impl fmt::Display for Argv {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 let n = self.0;
92
93 write!(f, "argv{n}")
94 }
95}