|
1 | 1 | # Builders Module |
2 | 2 |
|
3 | | -The `builders` module provides low-level APIs for constructing NetworkManager connection settings. Most users should use the high-level `NetworkManager` API instead — these builders are for advanced use cases where you need fine-grained control over the settings dictionary before calling NetworkManager D-Bus methods directly. |
| 3 | +The `builders` module provides low-level APIs for constructing NetworkManager connection settings. Most users should use the high-level `NetworkManager` API instead — these builders are for advanced use cases where you need fine-grained control over the settings dictionary. |
4 | 4 |
|
5 | | -To submit builder output, use [`NetworkManager::dbus_connection()`](./network-manager.md#advanced-d-bus-access) together with [`nmrs::raw`](./raw.md) (`zbus` / `zvariant` re-exports). See [Submitting Builder Output](#submitting-builder-output) below. |
| 5 | +To submit builder output, use [`NetworkManager::add_connection`](./network-manager.md#saving-profiles-without-activating) or [`NetworkManager::add_and_activate_connection`](./network-manager.md#activating-builder-output). See [Submitting Builder Output](#submitting-builder-output) below. |
6 | 6 |
|
7 | 7 | ## ConnectionBuilder |
8 | 8 |
|
@@ -153,64 +153,60 @@ For standard connections, the `NetworkManager` API handles everything automatica |
153 | 153 | ## Submitting Builder Output |
154 | 154 |
|
155 | 155 | Builders produce a NetworkManager settings dictionary |
156 | | -(`HashMap<&str, HashMap<&str, zvariant::Value>>`). To activate that profile you |
157 | | -need the same system D-Bus connection nmrs already manages, plus compatible |
158 | | -`zbus` / `zvariant` types from [`nmrs::raw`](./raw.md). |
| 156 | +(`HashMap<&str, HashMap<&str, zvariant::Value>>`). Pass that map to |
| 157 | +[`NetworkManager::add_connection`](./network-manager.md#saving-profiles-without-activating) |
| 158 | +to save a profile, or |
| 159 | +[`NetworkManager::add_and_activate_connection`](./network-manager.md#activating-builder-output) |
| 160 | +to create and bring it up immediately. |
159 | 161 |
|
160 | 162 | ### Wi-Fi hotspot (AP mode) |
161 | 163 |
|
162 | | -This is the workflow for cases such as [#260](https://github.com/freedesktop-rs/nmrs/issues/260) where the high-level `connect()` API does not expose every builder knob (for example `WifiMode::Ap`): |
| 164 | +This closes the workflow requested in [#260](https://github.com/freedesktop-rs/nmrs/issues/260) — use `WifiMode::Ap` with the high-level API: |
163 | 165 |
|
164 | 166 | ```rust |
165 | 167 | use nmrs::builders::{WifiConnectionBuilder, WifiMode}; |
166 | | -use nmrs::raw::{zbus, zvariant}; |
167 | | -use nmrs::{NetworkManager, Result}; |
168 | | - |
169 | | -#[zbus::proxy( |
170 | | - interface = "org.freedesktop.NetworkManager", |
171 | | - default_service = "org.freedesktop.NetworkManager", |
172 | | - default_path = "/org/freedesktop/NetworkManager" |
173 | | -)] |
174 | | -trait Nm { |
175 | | - fn add_and_activate_connection( |
176 | | - &self, |
177 | | - connection: std::collections::HashMap< |
178 | | - &str, |
179 | | - std::collections::HashMap<&str, zvariant::Value<'_>>, |
180 | | - >, |
181 | | - device: zvariant::OwnedObjectPath, |
182 | | - specific_object: zvariant::OwnedObjectPath, |
183 | | - ) -> zbus::Result<(zvariant::OwnedObjectPath, zvariant::OwnedObjectPath)>; |
184 | | -} |
| 168 | +use nmrs::NetworkManager; |
185 | 169 |
|
186 | | -async fn start_hotspot(nm: &NetworkManager, interface: &str) -> Result<()> { |
| 170 | +async fn start_hotspot(nm: &NetworkManager, interface: &str) -> nmrs::Result<()> { |
187 | 171 | let settings = WifiConnectionBuilder::new("Hotspot") |
188 | 172 | .wpa_psk("password") |
189 | 173 | .mode(WifiMode::Ap) |
190 | 174 | .ipv4_shared() |
191 | 175 | .ipv6_ignore() |
192 | 176 | .build(); |
193 | 177 |
|
194 | | - let device = nm.get_device_by_interface(interface).await?; |
195 | | - let proxy = NmProxy::new(nm.dbus_connection()).await?; |
196 | | - proxy |
197 | | - .add_and_activate_connection(settings, device, "/".into()) |
198 | | - .await?; |
199 | | - |
| 178 | + nm.add_and_activate_connection(settings, Some(interface), None).await?; |
200 | 179 | Ok(()) |
201 | 180 | } |
202 | 181 | ``` |
203 | 182 |
|
204 | | -Notes: |
205 | | - |
206 | | -- Use `"/"` as `specific_object` for AP mode and other cases where there is no target access point. |
207 | | -- For client (infrastructure) mode, resolve an access-point object path first (nmrs does this internally in `connect()`). |
208 | | -- Map D-Bus errors to `ConnectionError::Dbus` (or handle them in your own error type). |
209 | | -- nmrs does not yet provide a high-level wrapper for `AddConnection` / `AddAndActivateConnection`; `dbus_connection()` is the supported escape hatch. |
| 183 | +`specific_object` defaults to `"/"`, which is correct for AP mode. |
210 | 184 |
|
211 | 185 | ### Saving without activating |
212 | 186 |
|
213 | | -To persist a profile without bringing it up immediately, define a proxy method for `AddConnection` instead and pass the same `settings` map. nmrs uses that D-Bus call internally when saving VPN profiles. |
| 187 | +To persist a profile without bringing it up immediately — the workflow from [#463](https://github.com/freedesktop-rs/nmrs/issues/463): |
| 188 | + |
| 189 | +```rust |
| 190 | +use nmrs::builders::build_wifi_connection; |
| 191 | +use nmrs::{ConnectionOptions, NetworkManager, WifiSecurity}; |
| 192 | + |
| 193 | +let nm = NetworkManager::new().await?; |
| 194 | +let settings = build_wifi_connection( |
| 195 | + "GuestWiFi", |
| 196 | + &WifiSecurity::WpaPsk { psk: "password".into() }, |
| 197 | + &ConnectionOptions::new(true), |
| 198 | +); |
| 199 | +let profile = nm.add_connection(settings).await?; |
| 200 | +``` |
| 201 | + |
| 202 | +Activate the saved profile later with `activate_connection` via D-Bus, or use the existing high-level `connect()` APIs when the profile matches a visible network. |
| 203 | + |
| 204 | +### Advanced: direct D-Bus access |
| 205 | + |
| 206 | +If you need an NetworkManager D-Bus method that nmrs does not wrap yet, combine |
| 207 | +[`dbus_connection()`](./network-manager.md#advanced-d-bus-access) with |
| 208 | +[`nmrs::raw`](./raw.md) and define your own `#[zbus::proxy]` trait on top of |
| 209 | +the builder output. |
214 | 210 |
|
215 | 211 | ## OpenVpnBuilder |
216 | 212 |
|
@@ -254,6 +250,6 @@ See [docs.rs/nmrs](https://docs.rs/nmrs) for complete builder documentation. |
254 | 250 |
|
255 | 251 | ## See Also |
256 | 252 |
|
257 | | -- [Raw Module](./raw.md) – `zbus` / `zvariant` re-exports for advanced D-Bus work |
258 | | -- [NetworkManager API](./network-manager.md#advanced-d-bus-access) – `dbus_connection()` |
| 253 | +- [NetworkManager API](./network-manager.md#activating-builder-output) – `add_connection()` / `add_and_activate_connection()` |
| 254 | +- [Raw Module](./raw.md) – `zbus` / `zvariant` re-exports for unwrapped D-Bus calls |
259 | 255 | - [D-Bus Architecture](../advanced/dbus.md) – how settings reach NetworkManager |
0 commit comments