1use dbus::Path;
2use serde::{Deserialize, Serialize};
3use std::fmt::{self, Display, Formatter};
4use uuid::Uuid;
5
6use crate::DeviceId;
7
8#[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 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#[derive(Clone, Debug, Eq, PartialEq)]
53pub struct ServiceInfo {
54 pub id: ServiceId,
57 pub uuid: Uuid,
59 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}