bluez_async/
service.rs

1use dbus::Path;
2use serde::{Deserialize, Serialize};
3use std::fmt::{self, Display, Formatter};
4use uuid::Uuid;
5
6use crate::DeviceId;
7
8/// Opaque identifier for a GATT service on a Bluetooth device.
9#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
10pub struct ServiceId {
11    #[serde(with = "crate::serde_path")]
12    pub(crate) object_path: Path<'static>,
13}
14
15impl ServiceId {
16    pub(crate) fn new(object_path: &str) -> Self {
17        Self {
18            object_path: object_path.to_owned().into(),
19        }
20    }
21
22    /// Get the ID of the device on which this service was advertised.
23    pub fn device(&self) -> DeviceId {
24        let index = self
25            .object_path
26            .rfind('/')
27            .expect("ServiceId object_path must contain a slash.");
28        DeviceId::new(&self.object_path[0..index])
29    }
30}
31
32impl From<ServiceId> for Path<'static> {
33    fn from(id: ServiceId) -> Self {
34        id.object_path
35    }
36}
37
38impl Display for ServiceId {
39    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
40        write!(
41            f,
42            "{}",
43            self.object_path
44                .to_string()
45                .strip_prefix("/org/bluez/")
46                .ok_or(fmt::Error)?
47        )
48    }
49}
50
51/// Information about a GATT service on a Bluetooth device.
52#[derive(Clone, Debug, Eq, PartialEq)]
53pub struct ServiceInfo {
54    /// An opaque identifier for the service on the device, including a reference to which adapter
55    /// it was discovered on.
56    pub id: ServiceId,
57    /// The 128-bit UUID of the service.
58    pub uuid: Uuid,
59    /// Whether this GATT service is a primary service.
60    pub primary: bool,
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn service_device() {
69        let device_id = DeviceId::new("/org/bluez/hci0/dev_11_22_33_44_55_66");
70        let service_id = ServiceId::new("/org/bluez/hci0/dev_11_22_33_44_55_66/service0022");
71        assert_eq!(service_id.device(), device_id);
72    }
73
74    #[test]
75    fn to_string() {
76        let service_id = ServiceId::new("/org/bluez/hci0/dev_11_22_33_44_55_66/service0022");
77        assert_eq!(
78            service_id.to_string(),
79            "hci0/dev_11_22_33_44_55_66/service0022"
80        );
81    }
82}