dbus_addr/transport/
autolaunch.rs

1use std::marker::PhantomData;
2#[cfg(target_os = "windows")]
3use std::{borrow::Cow, fmt};
4
5#[cfg(target_os = "windows")]
6use super::percent::decode_percents_str;
7use super::{DBusAddr, KeyValFmt, Result, TransportImpl};
8
9/// `autolaunch:` D-Bus transport.
10///
11/// <https://dbus.freedesktop.org/doc/dbus-specification.html#meta-transports-autolaunch>
12#[derive(Clone, Debug, PartialEq, Eq, Default)]
13pub struct Autolaunch<'a> {
14    #[cfg(target_os = "windows")]
15    scope: Option<AutolaunchScope<'a>>,
16    phantom: PhantomData<&'a ()>,
17}
18
19impl<'a> Autolaunch<'a> {
20    #[cfg(target_os = "windows")]
21    /// Scope of autolaunch (Windows only)
22    pub fn scope(&self) -> Option<&AutolaunchScope<'a>> {
23        self.scope.as_ref()
24    }
25
26    /// Convert into owned version, with 'static lifetime.
27    pub fn into_owned(self) -> Autolaunch<'static> {
28        Autolaunch {
29            #[cfg(target_os = "windows")]
30            scope: self.scope.map(|s| s.into_owned()),
31            phantom: PhantomData,
32        }
33    }
34}
35
36impl<'a> TransportImpl<'a> for Autolaunch<'a> {
37    fn for_address(s: &'a DBusAddr<'a>) -> Result<Self> {
38        #[allow(unused_mut)]
39        let mut res = Autolaunch::default();
40
41        for (k, v) in s.key_val_iter() {
42            match (k, v) {
43                #[cfg(target_os = "windows")]
44                ("scope", Some(v)) => {
45                    res.scope = Some(decode_percents_str(v)?.try_into()?);
46                }
47                _ => continue,
48            }
49        }
50
51        Ok(res)
52    }
53
54    fn fmt_key_val<'s: 'b, 'b>(&'s self, kv: KeyValFmt<'b>) -> KeyValFmt<'b> {
55        #[cfg(target_os = "windows")]
56        let kv = kv.add("scope", self.scope());
57        kv
58    }
59}
60
61/// Scope of autolaunch (Windows only)
62#[cfg(target_os = "windows")]
63#[derive(Clone, Debug, PartialEq, Eq)]
64#[non_exhaustive]
65pub enum AutolaunchScope<'a> {
66    /// Limit session bus to dbus installation path.
67    InstallPath,
68    /// Limit session bus to the recent user.
69    User,
70    /// other values - specify dedicated session bus like "release", "debug" or other.
71    Other(Cow<'a, str>),
72}
73
74#[cfg(target_os = "windows")]
75impl<'a> AutolaunchScope<'a> {
76    fn into_owned(self) -> AutolaunchScope<'static> {
77        match self {
78            AutolaunchScope::InstallPath => AutolaunchScope::InstallPath,
79            AutolaunchScope::User => AutolaunchScope::User,
80            AutolaunchScope::Other(other) => AutolaunchScope::Other(other.into_owned().into()),
81        }
82    }
83}
84
85#[cfg(target_os = "windows")]
86impl fmt::Display for AutolaunchScope<'_> {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        match self {
89            Self::InstallPath => write!(f, "*install-path"),
90            Self::User => write!(f, "*user"),
91            Self::Other(o) => write!(f, "{o}"),
92        }
93    }
94}
95
96#[cfg(target_os = "windows")]
97impl<'a> TryFrom<Cow<'a, str>> for AutolaunchScope<'a> {
98    type Error = super::Error;
99
100    fn try_from(s: Cow<'a, str>) -> Result<Self> {
101        match s.as_ref() {
102            "*install-path" => Ok(Self::InstallPath),
103            "*user" => Ok(Self::User),
104            _ => Ok(Self::Other(s)),
105        }
106    }
107}