Skip to main content

tokio_dbus/object_path/
object_path_buf.rs

1use core::borrow::Borrow;
2use core::fmt;
3use core::hash;
4use core::ops::Deref;
5use core::str::FromStr;
6
7use alloc::borrow::ToOwned;
8use alloc::string::String;
9use alloc::vec::Vec;
10
11use super::{ObjectPath, ObjectPathError, validate};
12
13/// A validated owned object path.
14///
15/// The following rules define a [valid object path]. Implementations must not
16/// send or accept messages with invalid object paths.
17///
18/// [valid object path]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
19///
20/// * The path may be of any length.
21/// * The path must begin with an ASCII '/' (integer 47) character, and must
22///   consist of elements separated by slash characters.
23/// * Each element must only contain the ASCII characters `[A-Z][a-z][0-9]_`
24/// * No element may be the empty string.
25/// * Multiple '/' characters cannot occur in sequence.
26/// * A trailing '/' character is not allowed unless the path is the root path
27///   (a single '/' character).
28#[derive(Clone, PartialEq, Eq)]
29#[repr(transparent)]
30pub struct ObjectPathBuf(Vec<u8>);
31
32impl ObjectPathBuf {
33    /// Construct an owned object path from its raw underlying vector.
34    ///
35    /// # Safety
36    ///
37    /// The caller must ensure that the vector contains a valid object path.
38    #[inline]
39    pub(super) unsafe fn from_raw_vec(data: Vec<u8>) -> Self {
40        Self(data)
41    }
42
43    #[inline]
44    fn to_object_path(&self) -> &ObjectPath {
45        // SAFETY: This type ensures during construction that the object path it
46        // contains is valid.
47        unsafe { ObjectPath::new_unchecked(&self.0) }
48    }
49}
50
51/// Construct an owned object path from a vector, taking ownership of its
52/// allocation.
53///
54/// # Examples
55///
56/// ```
57/// use tokio_dbus::{ObjectPath, ObjectPathBuf};
58///
59/// let path = ObjectPathBuf::try_from(b"/org/freedesktop/DBus".to_vec())?;
60/// assert_eq!(&*path, ObjectPath::new("/org/freedesktop/DBus")?);
61///
62/// assert!(ObjectPathBuf::try_from(b"org/freedesktop/DBus".to_vec()).is_err());
63/// # Ok::<_, tokio_dbus::ObjectPathError>(())
64/// ```
65impl TryFrom<Vec<u8>> for ObjectPathBuf {
66    type Error = ObjectPathError;
67
68    #[inline]
69    fn try_from(path: Vec<u8>) -> Result<Self, Self::Error> {
70        if !validate(&path) {
71            return Err(ObjectPathError);
72        }
73
74        Ok(Self(path))
75    }
76}
77
78/// Construct an owned object path from a string, taking ownership of its
79/// allocation.
80///
81/// # Examples
82///
83/// ```
84/// use tokio_dbus::{ObjectPath, ObjectPathBuf};
85///
86/// let path = ObjectPathBuf::try_from(String::from("/org/freedesktop/DBus"))?;
87/// assert_eq!(&*path, ObjectPath::new("/org/freedesktop/DBus")?);
88/// # Ok::<_, tokio_dbus::ObjectPathError>(())
89/// ```
90impl TryFrom<String> for ObjectPathBuf {
91    type Error = ObjectPathError;
92
93    #[inline]
94    fn try_from(path: String) -> Result<Self, Self::Error> {
95        Self::try_from(path.into_bytes())
96    }
97}
98
99/// Construct an owned object path by copying a string.
100///
101/// # Examples
102///
103/// ```
104/// use tokio_dbus::{ObjectPath, ObjectPathBuf};
105///
106/// let path: ObjectPathBuf = "/org/freedesktop/DBus".parse()?;
107/// assert_eq!(&*path, ObjectPath::new("/org/freedesktop/DBus")?);
108/// # Ok::<_, tokio_dbus::ObjectPathError>(())
109/// ```
110impl FromStr for ObjectPathBuf {
111    type Err = ObjectPathError;
112
113    #[inline]
114    fn from_str(path: &str) -> Result<Self, Self::Err> {
115        Ok(ObjectPath::new(path)?.to_owned())
116    }
117}
118
119impl hash::Hash for ObjectPathBuf {
120    #[inline]
121    fn hash<H>(&self, state: &mut H)
122    where
123        H: hash::Hasher,
124    {
125        hash::Hash::hash(&**self, state);
126    }
127}
128
129impl fmt::Display for ObjectPathBuf {
130    #[inline]
131    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132        fmt::Display::fmt(&**self, f)
133    }
134}
135
136impl fmt::Debug for ObjectPathBuf {
137    #[inline]
138    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139        fmt::Debug::fmt(&**self, f)
140    }
141}
142
143impl Deref for ObjectPathBuf {
144    type Target = ObjectPath;
145
146    #[inline]
147    fn deref(&self) -> &Self::Target {
148        self.to_object_path()
149    }
150}
151
152impl Borrow<ObjectPath> for ObjectPathBuf {
153    #[inline]
154    fn borrow(&self) -> &ObjectPath {
155        self
156    }
157}
158
159impl AsRef<ObjectPath> for ObjectPathBuf {
160    #[inline]
161    fn as_ref(&self) -> &ObjectPath {
162        self
163    }
164}