diff --git a/networkmanager/src/device.rs b/networkmanager/src/device.rs index 63ff06f..cc50f5b 100644 --- a/networkmanager/src/device.rs +++ b/networkmanager/src/device.rs @@ -10,7 +10,10 @@ use crate::{ interface::{ config::{ip4::Ipv4ConfigProxy, ip6::Ipv6ConfigProxy}, connection::ActiveConnectionProxy, - device::DeviceProxy, + device::{ + bluetooth::BluetoothDeviceProxy, wired::WiredDeviceProxy, + wireless::WirelessDeviceProxy, DeviceProxy, + }, enums::{DeviceCapabilities, DeviceState, DeviceType}, }, }; @@ -53,6 +56,33 @@ impl<'a> Device<'a> { self.0.device_type().await.map(DeviceType::from) } + pub async fn downcast_to_device(&'a self) -> Result> { + match self.device_type().await? { + DeviceType::Bluetooth => Ok(SpecificDevice::Bluetooth( + BluetoothDeviceProxy::builder(self.0.connection()) + .path(self.0.path())? + .build() + .await? + .into(), + )), + DeviceType::Ethernet => Ok(SpecificDevice::Wired( + WiredDeviceProxy::builder(self.0.connection()) + .path(self.0.path())? + .build() + .await? + .into(), + )), + DeviceType::Wifi => Ok(SpecificDevice::Wireless( + WirelessDeviceProxy::builder(self.0.connection()) + .path(self.0.path())? + .build() + .await? + .into(), + )), + _ => unimplemented!(), + } + } + pub async fn ip4_address(&self) -> Result { self.0.ip4_address().await.map(Ipv4Addr::from) } @@ -91,3 +121,32 @@ impl<'a> From> for Device<'a> { Device(device) } } + +pub enum SpecificDevice<'a> { + Bluetooth(bluetooth::BluetoothDevice<'a>), + Wired(wired::WiredDevice<'a>), + Wireless(wireless::WirelessDevice<'a>), +} + +impl<'a> SpecificDevice<'a> { + pub fn into_bluetooth(self) -> Option> { + match self { + SpecificDevice::Bluetooth(device) => Some(device), + _ => None, + } + } + + pub fn into_wired(self) -> Option> { + match self { + SpecificDevice::Wired(device) => Some(device), + _ => None, + } + } + + pub fn into_wireless(self) -> Option> { + match self { + SpecificDevice::Wireless(device) => Some(device), + _ => None, + } + } +} diff --git a/networkmanager/src/device/bluetooth.rs b/networkmanager/src/device/bluetooth.rs index efee043..9fde723 100644 --- a/networkmanager/src/device/bluetooth.rs +++ b/networkmanager/src/device/bluetooth.rs @@ -1,10 +1,22 @@ // SPDX-License-Identifier: MPL-2.0 -use crate::interface::device::bluetooth::BluetoothDeviceProxy; +use super::Device; +use crate::interface::device::{bluetooth::BluetoothDeviceProxy, DeviceProxy}; use std::ops::Deref; +use zbus::Result; pub struct BluetoothDevice<'a>(BluetoothDeviceProxy<'a>); +impl<'a> BluetoothDevice<'a> { + pub async fn upcast(&'a self) -> Result> { + DeviceProxy::builder(self.0.connection()) + .path(self.0.path())? + .build() + .await + .map(Device::from) + } +} + impl<'a> Deref for BluetoothDevice<'a> { type Target = BluetoothDeviceProxy<'a>; diff --git a/networkmanager/src/device/wired.rs b/networkmanager/src/device/wired.rs index 283ec28..bc0087b 100644 --- a/networkmanager/src/device/wired.rs +++ b/networkmanager/src/device/wired.rs @@ -1,10 +1,22 @@ // SPDX-License-Identifier: MPL-2.0 -use crate::interface::device::wired::WiredDeviceProxy; +use super::Device; +use crate::interface::device::{wired::WiredDeviceProxy, DeviceProxy}; use std::ops::Deref; +use zbus::Result; pub struct WiredDevice<'a>(WiredDeviceProxy<'a>); +impl<'a> WiredDevice<'a> { + pub async fn upcast(&'a self) -> Result> { + DeviceProxy::builder(self.0.connection()) + .path(self.0.path())? + .build() + .await + .map(Device::from) + } +} + impl<'a> Deref for WiredDevice<'a> { type Target = WiredDeviceProxy<'a>; diff --git a/networkmanager/src/device/wireless.rs b/networkmanager/src/device/wireless.rs index d33f20e..a8a270d 100644 --- a/networkmanager/src/device/wireless.rs +++ b/networkmanager/src/device/wireless.rs @@ -1,11 +1,25 @@ // SPDX-License-Identifier: MPL-2.0 -use crate::interface::{device::wireless::WirelessDeviceProxy, enums::WifiCapabilities}; +use super::Device; +use crate::interface::{ + device::{wireless::WirelessDeviceProxy, DeviceProxy}, + enums::WifiCapabilities, +}; use std::ops::Deref; use zbus::Result; pub struct WirelessDevice<'a>(WirelessDeviceProxy<'a>); +impl<'a> WirelessDevice<'a> { + pub async fn upcast(&'a self) -> Result> { + DeviceProxy::builder(self.0.connection()) + .path(self.0.path())? + .build() + .await + .map(Device::from) + } +} + impl<'a> WirelessDevice<'a> { pub async fn wireless_capabilities(&self) -> Result { self.0 diff --git a/networkmanager/src/interface/device.rs b/networkmanager/src/interface/device.rs index e4731d9..5164b19 100644 --- a/networkmanager/src/interface/device.rs +++ b/networkmanager/src/interface/device.rs @@ -182,7 +182,7 @@ pub trait Device { /// Path property #[dbus_proxy(property)] - fn path(&self) -> zbus::Result; + fn path_(&self) -> zbus::Result; /// PhysicalPortId property #[dbus_proxy(property)] diff --git a/networkmanager/src/interface/enums.rs b/networkmanager/src/interface/enums.rs index d57243b..f3c47ab 100644 --- a/networkmanager/src/interface/enums.rs +++ b/networkmanager/src/interface/enums.rs @@ -51,6 +51,7 @@ pub enum DeviceType { Ethernet, Wifi, Bluetooth, + Generic, Other, Unknown, } @@ -61,7 +62,8 @@ impl From for DeviceType { 1 => DeviceType::Ethernet, 2 => DeviceType::Wifi, 5 => DeviceType::Bluetooth, - 3..=4 | 6..=32 => DeviceType::Other, + 14 => DeviceType::Generic, + 3..=32 => DeviceType::Other, _ => DeviceType::Unknown, } } diff --git a/networkmanager/src/interface/mod.rs b/networkmanager/src/interface/mod.rs index b45485f..d5b2c10 100644 --- a/networkmanager/src/interface/mod.rs +++ b/networkmanager/src/interface/mod.rs @@ -19,6 +19,7 @@ //! * [`zbus::fdo::PeerProxy`] //! //! …consequently `zbus-xmlgen` did not generate code for the above interfaces. +#![allow(clippy::type_complexity)] pub mod access_point; pub mod config;