zbus_names/
well_known_name.rs

1use crate::{
2    utils::{impl_str_basic, impl_try_from},
3    Error, Result,
4};
5use serde::{de, Deserialize, Serialize};
6use static_assertions::assert_impl_all;
7use std::{
8    borrow::{Borrow, Cow},
9    fmt::{self, Debug, Display, Formatter},
10    ops::Deref,
11    sync::Arc,
12};
13use zvariant::{NoneValue, OwnedValue, Str, Type, Value};
14
15/// String that identifies a [well-known bus name][wbn].
16///
17/// # Examples
18///
19/// ```
20/// use zbus_names::WellKnownName;
21///
22/// // Valid well-known names.
23/// let name = WellKnownName::try_from("org.gnome.Service-for_you").unwrap();
24/// assert_eq!(name, "org.gnome.Service-for_you");
25/// let name = WellKnownName::try_from("a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap();
26/// assert_eq!(name, "a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name");
27///
28/// // Invalid well-known names
29/// WellKnownName::try_from("").unwrap_err();
30/// WellKnownName::try_from("double..dots").unwrap_err();
31/// WellKnownName::try_from(".").unwrap_err();
32/// WellKnownName::try_from(".start.with.dot").unwrap_err();
33/// WellKnownName::try_from("1st.element.starts.with.digit").unwrap_err();
34/// WellKnownName::try_from("the.2nd.element.starts.with.digit").unwrap_err();
35/// WellKnownName::try_from("no-dots").unwrap_err();
36/// ```
37///
38/// [wbn]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
39#[derive(
40    Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
41)]
42pub struct WellKnownName<'name>(pub(crate) Str<'name>);
43
44impl_str_basic!(WellKnownName<'_>);
45
46assert_impl_all!(WellKnownName<'_>: Send, Sync, Unpin);
47
48impl<'name> WellKnownName<'name> {
49    /// This is faster than `Clone::clone` when `self` contains owned data.
50    pub fn as_ref(&self) -> WellKnownName<'_> {
51        WellKnownName(self.0.as_ref())
52    }
53
54    /// The well-known-name as string.
55    pub fn as_str(&self) -> &str {
56        self.0.as_str()
57    }
58
59    /// Create a new `WellKnownName` from the given string.
60    ///
61    /// Since the passed string is not checked for correctness, prefer using the
62    /// `TryFrom<&str>` implementation.
63    pub fn from_str_unchecked(name: &'name str) -> Self {
64        Self(Str::from(name))
65    }
66
67    /// Same as `try_from`, except it takes a `&'static str`.
68    pub fn from_static_str(name: &'static str) -> Result<Self> {
69        validate(name)?;
70        Ok(Self(Str::from_static(name)))
71    }
72
73    /// Same as `from_str_unchecked`, except it takes a `&'static str`.
74    pub const fn from_static_str_unchecked(name: &'static str) -> Self {
75        Self(Str::from_static(name))
76    }
77
78    /// Same as `from_str_unchecked`, except it takes an owned `String`.
79    ///
80    /// Since the passed string is not checked for correctness, prefer using the
81    /// `TryFrom<String>` implementation.
82    pub fn from_string_unchecked(name: String) -> Self {
83        Self(Str::from(name))
84    }
85
86    /// Creates an owned clone of `self`.
87    pub fn to_owned(&self) -> WellKnownName<'static> {
88        WellKnownName(self.0.to_owned())
89    }
90
91    /// Creates an owned clone of `self`.
92    pub fn into_owned(self) -> WellKnownName<'static> {
93        WellKnownName(self.0.into_owned())
94    }
95}
96
97impl Deref for WellKnownName<'_> {
98    type Target = str;
99
100    fn deref(&self) -> &Self::Target {
101        self.as_str()
102    }
103}
104
105impl Borrow<str> for WellKnownName<'_> {
106    fn borrow(&self) -> &str {
107        self.as_str()
108    }
109}
110
111impl Display for WellKnownName<'_> {
112    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
113        Display::fmt(&self.as_str(), f)
114    }
115}
116
117impl PartialEq<str> for WellKnownName<'_> {
118    fn eq(&self, other: &str) -> bool {
119        self.as_str() == other
120    }
121}
122
123impl PartialEq<&str> for WellKnownName<'_> {
124    fn eq(&self, other: &&str) -> bool {
125        self.as_str() == *other
126    }
127}
128
129impl PartialEq<OwnedWellKnownName> for WellKnownName<'_> {
130    fn eq(&self, other: &OwnedWellKnownName) -> bool {
131        *self == other.0
132    }
133}
134
135impl<'de: 'name, 'name> Deserialize<'de> for WellKnownName<'name> {
136    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
137    where
138        D: serde::Deserializer<'de>,
139    {
140        let name = <Cow<'name, str>>::deserialize(deserializer)?;
141
142        Self::try_from(name).map_err(|e| de::Error::custom(e.to_string()))
143    }
144}
145
146fn validate(name: &str) -> Result<()> {
147    validate_bytes(name.as_bytes()).map_err(|_| {
148        Error::InvalidName(
149            "Invalid well-known name. \
150            See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus"
151        )
152    })
153}
154
155pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> {
156    use winnow::{
157        combinator::separated,
158        stream::AsChar,
159        token::{one_of, take_while},
160        Parser,
161    };
162    // Rules
163    //
164    // * Only ASCII alphanumeric, `_` or '-'.
165    // * Must not begin with a `.`.
166    // * Must contain at least one `.`.
167    // * Each element must:
168    //  * not begin with a digit.
169    //  * be 1 character (so name must be minimum 3 characters long).
170    // * <= 255 characters.
171    let first_element_char = one_of((AsChar::is_alpha, b'_', b'-'));
172    let subsequent_element_chars = take_while::<_, _, ()>(0.., (AsChar::is_alphanum, b'_', b'-'));
173    let element = (first_element_char, subsequent_element_chars);
174    let mut well_known_name = separated(2.., element, b'.');
175
176    well_known_name
177        .parse(bytes)
178        .map_err(|_| ())
179        .and_then(|_: ()| {
180            // Least likely scenario so we check this last.
181            if bytes.len() > 255 {
182                return Err(());
183            }
184
185            Ok(())
186        })
187}
188
189/// This never succeeds but is provided so it's easier to pass `Option::None` values for API
190/// requiring `Option<TryInto<impl BusName>>`, since type inference won't work here.
191impl TryFrom<()> for WellKnownName<'_> {
192    type Error = Error;
193
194    fn try_from(_value: ()) -> Result<Self> {
195        unreachable!("Conversion from `()` is not meant to actually work");
196    }
197}
198
199impl<'name> From<&WellKnownName<'name>> for WellKnownName<'name> {
200    fn from(name: &WellKnownName<'name>) -> Self {
201        name.clone()
202    }
203}
204
205impl<'name> From<WellKnownName<'name>> for Str<'name> {
206    fn from(value: WellKnownName<'name>) -> Self {
207        value.0
208    }
209}
210
211impl<'name> NoneValue for WellKnownName<'name> {
212    type NoneType = &'name str;
213
214    fn null_value() -> Self::NoneType {
215        <&str>::default()
216    }
217}
218
219/// Owned sibling of [`WellKnownName`].
220#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)]
221pub struct OwnedWellKnownName(#[serde(borrow)] WellKnownName<'static>);
222
223assert_impl_all!(OwnedWellKnownName: Send, Sync, Unpin);
224
225impl OwnedWellKnownName {
226    /// Convert to the inner `WellKnownName`, consuming `self`.
227    pub fn into_inner(self) -> WellKnownName<'static> {
228        self.0
229    }
230
231    /// Get a reference to the inner `WellKnownName`.
232    pub fn inner(&self) -> &WellKnownName<'static> {
233        &self.0
234    }
235}
236
237impl_str_basic!(OwnedWellKnownName);
238
239impl Deref for OwnedWellKnownName {
240    type Target = WellKnownName<'static>;
241
242    fn deref(&self) -> &Self::Target {
243        &self.0
244    }
245}
246
247impl Borrow<str> for OwnedWellKnownName {
248    fn borrow(&self) -> &str {
249        self.0.as_str()
250    }
251}
252
253impl AsRef<str> for OwnedWellKnownName {
254    fn as_ref(&self) -> &str {
255        self.0.as_str()
256    }
257}
258
259impl Debug for OwnedWellKnownName {
260    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
261        f.debug_tuple("OwnedWellKnownName")
262            .field(&self.as_str())
263            .finish()
264    }
265}
266
267impl Display for OwnedWellKnownName {
268    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
269        Display::fmt(&WellKnownName::from(self), f)
270    }
271}
272
273impl From<OwnedWellKnownName> for WellKnownName<'_> {
274    fn from(name: OwnedWellKnownName) -> Self {
275        name.into_inner()
276    }
277}
278
279impl<'unowned, 'owned: 'unowned> From<&'owned OwnedWellKnownName> for WellKnownName<'unowned> {
280    fn from(name: &'owned OwnedWellKnownName) -> Self {
281        WellKnownName::from_str_unchecked(name.as_str())
282    }
283}
284
285impl From<WellKnownName<'_>> for OwnedWellKnownName {
286    fn from(name: WellKnownName<'_>) -> Self {
287        OwnedWellKnownName(name.into_owned())
288    }
289}
290
291impl_try_from! {
292    ty: WellKnownName<'s>,
293    owned_ty: OwnedWellKnownName,
294    validate_fn: validate,
295    try_from: [&'s str, String, Arc<str>, Cow<'s, str>, Str<'s>],
296}
297
298impl From<OwnedWellKnownName> for Str<'_> {
299    fn from(value: OwnedWellKnownName) -> Self {
300        value.into_inner().0
301    }
302}
303
304impl<'de> Deserialize<'de> for OwnedWellKnownName {
305    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
306    where
307        D: de::Deserializer<'de>,
308    {
309        String::deserialize(deserializer)
310            .and_then(|n| WellKnownName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
311            .map(Self)
312    }
313}
314
315impl PartialEq<&str> for OwnedWellKnownName {
316    fn eq(&self, other: &&str) -> bool {
317        self.as_str() == *other
318    }
319}
320
321impl PartialEq<WellKnownName<'_>> for OwnedWellKnownName {
322    fn eq(&self, other: &WellKnownName<'_>) -> bool {
323        self.0 == *other
324    }
325}
326
327impl NoneValue for OwnedWellKnownName {
328    type NoneType = <WellKnownName<'static> as NoneValue>::NoneType;
329
330    fn null_value() -> Self::NoneType {
331        WellKnownName::null_value()
332    }
333}