zbus/blocking/connection/
builder.rs

1#[cfg(not(feature = "tokio"))]
2use std::net::TcpStream;
3#[cfg(all(unix, not(feature = "tokio")))]
4use std::os::unix::net::UnixStream;
5#[cfg(feature = "tokio")]
6use tokio::net::TcpStream;
7#[cfg(all(unix, feature = "tokio"))]
8use tokio::net::UnixStream;
9#[cfg(all(windows, not(feature = "tokio")))]
10use uds_windows::UnixStream;
11
12use zvariant::ObjectPath;
13
14#[cfg(feature = "p2p")]
15use crate::Guid;
16use crate::{
17    address::Address, blocking::Connection, conn::AuthMechanism, connection::socket::BoxedSplit,
18    names::WellKnownName, object_server::Interface, utils::block_on, Error, Result,
19};
20
21/// A builder for [`zbus::blocking::Connection`].
22#[derive(Debug)]
23#[must_use]
24pub struct Builder<'a>(crate::connection::Builder<'a>);
25
26impl<'a> Builder<'a> {
27    /// Create a builder for the session/user message bus connection.
28    pub fn session() -> Result<Self> {
29        crate::connection::Builder::session().map(Self)
30    }
31
32    /// Create a builder for the system-wide message bus connection.
33    pub fn system() -> Result<Self> {
34        crate::connection::Builder::system().map(Self)
35    }
36
37    /// Create a builder for a connection that will use the given [D-Bus bus address].
38    ///
39    /// [D-Bus bus address]: https://dbus.freedesktop.org/doc/dbus-specification.html#addresses
40    pub fn address<A>(address: A) -> Result<Self>
41    where
42        A: TryInto<Address>,
43        A::Error: Into<Error>,
44    {
45        crate::connection::Builder::address(address).map(Self)
46    }
47
48    /// Create a builder for a connection that will use the given unix stream.
49    ///
50    /// If the default `async-io` feature is disabled, this method will expect a
51    /// [`tokio::net::UnixStream`](https://docs.rs/tokio/latest/tokio/net/struct.UnixStream.html)
52    /// argument.
53    ///
54    /// Since tokio currently [does not support Unix domain sockets][tuds] on Windows, this method
55    /// is not available when the `tokio` feature is enabled and building for Windows target.
56    ///
57    /// [tuds]: https://github.com/tokio-rs/tokio/issues/2201
58    #[cfg(any(unix, not(feature = "tokio")))]
59    pub fn unix_stream(stream: UnixStream) -> Self {
60        Self(crate::connection::Builder::unix_stream(stream))
61    }
62
63    /// Create a builder for a connection that will use the given TCP stream.
64    ///
65    /// If the default `async-io` feature is disabled, this method will expect a
66    /// [`tokio::net::TcpStream`](https://docs.rs/tokio/latest/tokio/net/struct.TcpStream.html)
67    /// argument.
68    pub fn tcp_stream(stream: TcpStream) -> Self {
69        Self(crate::connection::Builder::tcp_stream(stream))
70    }
71
72    /// Create a builder for a connection that will use the given pre-authenticated socket.
73    ///
74    /// This is similar to [`Builder::socket`], except that the socket is either already
75    /// authenticated or does not require authentication.
76    pub fn authenticated_socket<S, G>(socket: S, guid: G) -> Result<Self>
77    where
78        S: Into<BoxedSplit>,
79        G: TryInto<crate::Guid<'a>>,
80        G::Error: Into<Error>,
81    {
82        crate::connection::Builder::authenticated_socket(socket, guid).map(Self)
83    }
84
85    /// Create a builder for a connection that will use the given socket.
86    pub fn socket<S: Into<BoxedSplit>>(socket: S) -> Self {
87        Self(crate::connection::Builder::socket(socket))
88    }
89
90    /// Specify the mechanism to use during authentication.
91    pub fn auth_mechanism(self, auth_mechanism: AuthMechanism) -> Self {
92        Self(self.0.auth_mechanism(auth_mechanism))
93    }
94
95    /// The to-be-created connection will be a peer-to-peer connection.
96    ///
97    /// This method is only available when the `p2p` feature is enabled.
98    #[cfg(feature = "p2p")]
99    pub fn p2p(self) -> Self {
100        Self(self.0.p2p())
101    }
102
103    /// The to-be-created connection will be a server using the given GUID.
104    ///
105    /// The to-be-created connection will wait for incoming client authentication handshake and
106    /// negotiation messages, for peer-to-peer communications after successful creation.
107    ///
108    /// This method is only available when the `p2p` feature is enabled.
109    ///
110    /// **NOTE:** This method is redundant when using [`Builder::authenticated_socket`] since the
111    /// latter already sets the GUID for the connection and zbus doesn't differentiate between a
112    /// server and a client connection, except for authentication.
113    #[cfg(feature = "p2p")]
114    pub fn server<G>(self, guid: G) -> Result<Self>
115    where
116        G: TryInto<Guid<'a>>,
117        G::Error: Into<Error>,
118    {
119        self.0.server(guid).map(Self)
120    }
121
122    /// Set the capacity of the main (unfiltered) queue.
123    ///
124    /// Since typically you'd want to set this at instantiation time, you can set it through the
125    /// builder.
126    ///
127    /// # Example
128    ///
129    /// ```
130    /// # use std::error::Error;
131    /// # use zbus::blocking::connection;
132    /// #
133    /// let conn = connection::Builder::session()?
134    ///     .max_queued(30)
135    ///     .build()?;
136    /// assert_eq!(conn.max_queued(), 30);
137    ///
138    /// // Do something useful with `conn`..
139    /// # Ok::<_, Box<dyn Error + Send + Sync>>(())
140    /// ```
141    pub fn max_queued(self, max: usize) -> Self {
142        Self(self.0.max_queued(max))
143    }
144
145    /// Register a D-Bus [`Interface`] to be served at a given path.
146    ///
147    /// This is similar to [`zbus::blocking::ObjectServer::at`], except that it allows you to have
148    /// your interfaces available immediately after the connection is established. Typically, this
149    /// is exactly what you'd want. Also in contrast to [`zbus::blocking::ObjectServer::at`], this
150    /// method will replace any previously added interface with the same name at the same path.
151    pub fn serve_at<P, I>(self, path: P, iface: I) -> Result<Self>
152    where
153        I: Interface,
154        P: TryInto<ObjectPath<'a>>,
155        P::Error: Into<Error>,
156    {
157        self.0.serve_at(path, iface).map(Self)
158    }
159
160    /// Register a well-known name for this connection on the bus.
161    ///
162    /// This is similar to [`zbus::blocking::Connection::request_name`], except the name is
163    /// requested as part of the connection setup ([`Builder::build`]), immediately after
164    /// interfaces registered (through [`Builder::serve_at`]) are advertised. Typically
165    /// this is exactly what you want.
166    pub fn name<W>(self, well_known_name: W) -> Result<Self>
167    where
168        W: TryInto<WellKnownName<'a>>,
169        W::Error: Into<Error>,
170    {
171        self.0.name(well_known_name).map(Self)
172    }
173
174    /// Whether the [`zbus::fdo::RequestNameFlags::AllowReplacement`] flag will be set when
175    /// requesting names.
176    pub fn allow_name_replacements(self, allow_replacement: bool) -> Self {
177        Self(self.0.allow_name_replacements(allow_replacement))
178    }
179
180    /// Whether the [`zbus::fdo::RequestNameFlags::ReplaceExisting`] flag will be set when
181    /// requesting names.
182    pub fn replace_existing_names(self, replace_existing: bool) -> Self {
183        Self(self.0.replace_existing_names(replace_existing))
184    }
185
186    /// Set the unique name of the connection.
187    ///
188    /// This method is only available when the `bus-impl` feature is enabled.
189    ///
190    /// # Panics
191    ///
192    /// This method panics if the to-be-created connection is not a peer-to-peer connection.
193    /// It will always panic if the connection is to a message bus as it's the bus that assigns
194    /// peers their unique names. This is mainly provided for bus implementations. All other users
195    /// should not need to use this method.
196    #[cfg(feature = "bus-impl")]
197    pub fn unique_name<U>(self, unique_name: U) -> Result<Self>
198    where
199        U: TryInto<crate::names::UniqueName<'a>>,
200        U::Error: Into<Error>,
201    {
202        self.0.unique_name(unique_name).map(Self)
203    }
204
205    /// Build the connection, consuming the builder.
206    ///
207    /// # Errors
208    ///
209    /// Until server-side bus connection is supported, attempting to build such a connection will
210    /// result in a [`Error::Unsupported`] error.
211    pub fn build(self) -> Result<Connection> {
212        block_on(self.0.build()).map(Into::into)
213    }
214}