tokio_dbus/connection/
builder.rs

1use crate::error::Result;
2use crate::sasl::{Auth, SaslRequest, SaslResponse};
3
4use super::{Connection, Transport};
5
6enum BusKind {
7    Session,
8    System,
9}
10
11enum AuthKind {
12    #[cfg_attr(feature = "libc", allow(unused))]
13    None,
14    #[cfg(feature = "libc")]
15    Uid,
16}
17
18impl AuthKind {
19    #[cfg(not(feature = "libc"))]
20    const DEFAULT: Self = Self::None;
21    #[cfg(feature = "libc")]
22    const DEFAULT: Self = Self::Uid;
23}
24
25/// Builder of a [`Connection`].
26pub struct ConnectionBuilder {
27    bus: BusKind,
28    auth: AuthKind,
29}
30
31impl ConnectionBuilder {
32    /// Construct a new [`ConnectionBuilder`] with the default configuration.
33    ///
34    /// # Examples
35    ///
36    /// ```
37    /// use tokio_dbus::ConnectionBuilder;
38    ///
39    /// let c = ConnectionBuilder::new();
40    /// ```
41    pub fn new() -> Self {
42        Self {
43            bus: BusKind::Session,
44            auth: AuthKind::DEFAULT,
45        }
46    }
47
48    /// Construct a connection connecting to the session bus (default).
49    ///
50    /// # Examples
51    ///
52    /// ```no_run
53    /// use tokio_dbus::ConnectionBuilder;
54    ///
55    /// # #[tokio::main] async fn main() -> tokio_dbus::Result<()> {
56    /// let c = ConnectionBuilder::new().session_bus().connect().await?;
57    /// # Ok(()) }
58    /// ```
59    pub fn session_bus(&mut self) -> &mut Self {
60        self.bus = BusKind::Session;
61        self
62    }
63
64    /// Construct a connection connecting to the system bus.
65    ///
66    /// # Examples
67    ///
68    /// ```no_run
69    /// use tokio_dbus::ConnectionBuilder;
70    ///
71    /// # #[tokio::main] async fn main() -> tokio_dbus::Result<()> {
72    /// let c = ConnectionBuilder::new().system_bus().connect().await?;
73    /// # Ok(()) }
74    /// ```
75    pub fn system_bus(&mut self) -> &mut Self {
76        self.bus = BusKind::System;
77        self
78    }
79
80    /// Construct and connect a [`Connection`] with the current configuration.
81    pub async fn connect(&self) -> Result<Connection> {
82        let transport = match self.bus {
83            BusKind::Session => Transport::session_bus()?,
84            BusKind::System => Transport::system_bus()?,
85        };
86
87        let mut auth_buf;
88
89        let auth = match self.auth {
90            AuthKind::None => None,
91            #[cfg(feature = "libc")]
92            AuthKind::Uid => {
93                auth_buf = [0; 32];
94                Some(Auth::external_from_uid(&mut auth_buf))
95            }
96        };
97
98        let mut c = Connection::new(transport)?;
99
100        if let Some(auth) = auth {
101            let sasl = c.sasl_request(&SaslRequest::Auth(auth)).await?;
102
103            match sasl {
104                SaslResponse::Ok(..) => {}
105            }
106        }
107
108        // Transition to message mode.
109        c.sasl_begin().await?;
110        c.hello()?;
111        Ok(c)
112    }
113}
114
115impl Default for ConnectionBuilder {
116    #[inline]
117    fn default() -> Self {
118        Self::new()
119    }
120}