zbus_names/
bus_name.rs

1use core::{
2    borrow::Borrow,
3    fmt::{self, Debug, Display, Formatter},
4    ops::Deref,
5};
6use std::{borrow::Cow, sync::Arc};
7
8use crate::{
9    unique_name, utils::impl_str_basic, well_known_name, Error, OwnedUniqueName,
10    OwnedWellKnownName, Result, UniqueName, WellKnownName,
11};
12use serde::{de, Deserialize, Serialize};
13use static_assertions::assert_impl_all;
14use zvariant::{NoneValue, OwnedValue, Str, Type, Value};
15
16/// String that identifies a [bus name].
17///
18/// # Examples
19///
20/// ```
21/// use zbus_names::BusName;
22///
23/// // Valid well-known names.
24/// let name = BusName::try_from("org.gnome.Service-for_you").unwrap();
25/// assert!(matches!(name, BusName::WellKnown(_)));
26/// assert_eq!(name, "org.gnome.Service-for_you");
27/// let name = BusName::try_from("a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap();
28/// assert!(matches!(name, BusName::WellKnown(_)));
29/// assert_eq!(name, "a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name");
30///
31/// // Valid unique names.
32/// let name = BusName::try_from(":org.gnome.Service-for_you").unwrap();
33/// assert!(matches!(name, BusName::Unique(_)));
34/// assert_eq!(name, ":org.gnome.Service-for_you");
35/// let name = BusName::try_from(":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap();
36/// assert!(matches!(name, BusName::Unique(_)));
37/// assert_eq!(name, ":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name");
38///
39/// // Invalid bus names
40/// BusName::try_from("").unwrap_err();
41/// BusName::try_from("double..dots").unwrap_err();
42/// BusName::try_from(".").unwrap_err();
43/// BusName::try_from(".start.with.dot").unwrap_err();
44/// BusName::try_from("1start.with.digit").unwrap_err();
45/// BusName::try_from("no-dots").unwrap_err();
46/// ```
47///
48/// [bus name]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
49#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)]
50#[serde(untagged)]
51pub enum BusName<'name> {
52    #[serde(borrow)]
53    Unique(UniqueName<'name>),
54    #[serde(borrow)]
55    WellKnown(WellKnownName<'name>),
56}
57
58assert_impl_all!(BusName<'_>: Send, Sync, Unpin);
59
60impl_str_basic!(BusName<'_>);
61
62impl BusName<'_> {
63    /// This is faster than `Clone::clone` when `self` contains owned data.
64    pub fn as_ref(&self) -> BusName<'_> {
65        match self {
66            BusName::Unique(name) => BusName::Unique(name.as_ref()),
67            BusName::WellKnown(name) => BusName::WellKnown(name.as_ref()),
68        }
69    }
70
71    /// The well-known-name as string.
72    pub fn as_str(&self) -> &str {
73        match self {
74            BusName::Unique(name) => name.as_str(),
75            BusName::WellKnown(name) => name.as_str(),
76        }
77    }
78
79    /// Creates an owned clone of `self`.
80    pub fn to_owned(&self) -> BusName<'static> {
81        match self {
82            BusName::Unique(name) => BusName::Unique(name.to_owned()),
83            BusName::WellKnown(name) => BusName::WellKnown(name.to_owned()),
84        }
85    }
86
87    /// Creates an owned clone of `self`.
88    pub fn into_owned(self) -> BusName<'static> {
89        match self {
90            BusName::Unique(name) => BusName::Unique(name.into_owned()),
91            BusName::WellKnown(name) => BusName::WellKnown(name.into_owned()),
92        }
93    }
94
95    /// Same as `try_from`, except it takes a `&'static str`.
96    pub fn from_static_str(name: &'static str) -> Result<Self> {
97        match Self::try_from(name)? {
98            BusName::Unique(_) => Ok(BusName::Unique(UniqueName::from_static_str_unchecked(name))),
99            BusName::WellKnown(_) => Ok(BusName::WellKnown(
100                WellKnownName::from_static_str_unchecked(name),
101            )),
102        }
103    }
104}
105
106impl Deref for BusName<'_> {
107    type Target = str;
108
109    fn deref(&self) -> &Self::Target {
110        self.as_str()
111    }
112}
113
114impl Borrow<str> for BusName<'_> {
115    fn borrow(&self) -> &str {
116        self.as_str()
117    }
118}
119
120impl Debug for BusName<'_> {
121    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
122        match self {
123            BusName::Unique(name) => f
124                .debug_tuple("BusName::Unique")
125                .field(&name.as_str())
126                .finish(),
127            BusName::WellKnown(name) => f
128                .debug_tuple("BusName::WellKnown")
129                .field(&name.as_str())
130                .finish(),
131        }
132    }
133}
134
135impl Display for BusName<'_> {
136    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
137        Display::fmt(&self.as_str(), f)
138    }
139}
140
141impl PartialEq<str> for BusName<'_> {
142    fn eq(&self, other: &str) -> bool {
143        self.as_str() == other
144    }
145}
146
147impl PartialEq<&str> for BusName<'_> {
148    fn eq(&self, other: &&str) -> bool {
149        self.as_str() == *other
150    }
151}
152
153impl PartialEq<OwnedBusName> for BusName<'_> {
154    fn eq(&self, other: &OwnedBusName) -> bool {
155        *self == other.0
156    }
157}
158
159impl PartialEq<UniqueName<'_>> for BusName<'_> {
160    fn eq(&self, other: &UniqueName<'_>) -> bool {
161        match self {
162            Self::Unique(name) => *name == *other,
163            Self::WellKnown(_) => false,
164        }
165    }
166}
167
168impl PartialEq<WellKnownName<'_>> for BusName<'_> {
169    fn eq(&self, other: &WellKnownName<'_>) -> bool {
170        match self {
171            Self::Unique(_) => false,
172            Self::WellKnown(name) => *name == *other,
173        }
174    }
175}
176
177impl<'name> NoneValue for BusName<'name> {
178    type NoneType = &'name str;
179
180    fn null_value() -> Self::NoneType {
181        <&str>::default()
182    }
183}
184
185// Manual deserialize implementation to get the desired error on invalid bus names.
186impl<'de: 'name, 'name> Deserialize<'de> for BusName<'name> {
187    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
188    where
189        D: serde::Deserializer<'de>,
190    {
191        let name = <Cow<'name, str>>::deserialize(deserializer)?;
192
193        Self::try_from(name).map_err(|e| de::Error::custom(e.to_string()))
194    }
195}
196
197impl Type for BusName<'_> {
198    const SIGNATURE: &'static zvariant::Signature = &zvariant::Signature::Str;
199}
200
201impl<'name> From<UniqueName<'name>> for BusName<'name> {
202    fn from(name: UniqueName<'name>) -> Self {
203        BusName::Unique(name)
204    }
205}
206
207impl<'name> From<WellKnownName<'name>> for BusName<'name> {
208    fn from(name: WellKnownName<'name>) -> Self {
209        BusName::WellKnown(name)
210    }
211}
212
213impl<'s> TryFrom<Str<'s>> for BusName<'s> {
214    type Error = Error;
215
216    fn try_from(value: Str<'s>) -> Result<Self> {
217        if unique_name::validate_bytes(value.as_bytes()).is_ok() {
218            Ok(BusName::Unique(UniqueName(value)))
219        } else if well_known_name::validate_bytes(value.as_bytes()).is_ok() {
220            Ok(BusName::WellKnown(WellKnownName(value)))
221        } else {
222            Err(Error::InvalidName(INVALID_BUS_NAME_ERROR))
223        }
224    }
225}
226
227impl<'s> TryFrom<BusName<'s>> for WellKnownName<'s> {
228    type Error = Error;
229
230    fn try_from(value: BusName<'s>) -> Result<Self> {
231        match value {
232            BusName::Unique(_) => Err(Error::InvalidNameConversion {
233                from: "UniqueName",
234                to: "WellKnownName",
235            }),
236            BusName::WellKnown(name) => Ok(name),
237        }
238    }
239}
240
241impl<'s> TryFrom<BusName<'s>> for UniqueName<'s> {
242    type Error = Error;
243
244    fn try_from(value: BusName<'s>) -> Result<Self> {
245        match value {
246            BusName::Unique(name) => Ok(name),
247            BusName::WellKnown(_) => Err(Error::InvalidNameConversion {
248                from: "WellKnownName",
249                to: "UniqueName",
250            }),
251        }
252    }
253}
254
255impl<'s> TryFrom<&'s str> for BusName<'s> {
256    type Error = Error;
257
258    fn try_from(value: &'s str) -> Result<Self> {
259        Str::from(value).try_into()
260    }
261}
262
263impl TryFrom<String> for BusName<'_> {
264    type Error = Error;
265
266    fn try_from(value: String) -> Result<Self> {
267        Str::from(value).try_into()
268    }
269}
270
271impl TryFrom<Arc<str>> for BusName<'_> {
272    type Error = Error;
273
274    fn try_from(value: Arc<str>) -> Result<Self> {
275        Str::from(value).try_into()
276    }
277}
278
279impl<'s> TryFrom<Value<'s>> for BusName<'s> {
280    type Error = Error;
281
282    fn try_from(value: Value<'s>) -> Result<Self> {
283        Str::try_from(value)
284            .map_err(Into::into)
285            .and_then(TryInto::try_into)
286    }
287}
288
289/// This never succeeds but is provided so it's easier to pass `Option::None` values for API
290/// requiring `Option<TryInto<impl BusName>>`, since type inference won't work here.
291impl TryFrom<()> for BusName<'_> {
292    type Error = Error;
293
294    fn try_from(_value: ()) -> Result<Self> {
295        unreachable!("Conversion from `()` is not meant to actually work.");
296    }
297}
298
299impl<'name> TryFrom<Cow<'name, str>> for BusName<'name> {
300    type Error = Error;
301
302    fn try_from(value: Cow<'name, str>) -> Result<Self> {
303        Str::from(value).try_into()
304    }
305}
306
307impl<'s> From<BusName<'s>> for Value<'s> {
308    fn from(name: BusName<'s>) -> Self {
309        match name {
310            BusName::Unique(name) => name.into(),
311            BusName::WellKnown(name) => name.into(),
312        }
313    }
314}
315
316impl<'name> From<BusName<'name>> for Str<'name> {
317    fn from(value: BusName<'name>) -> Self {
318        match value {
319            BusName::Unique(name) => name.into(),
320            BusName::WellKnown(name) => name.into(),
321        }
322    }
323}
324
325impl<'name> From<&BusName<'name>> for BusName<'name> {
326    fn from(name: &BusName<'name>) -> Self {
327        name.clone()
328    }
329}
330
331impl TryFrom<OwnedValue> for BusName<'_> {
332    type Error = Error;
333
334    fn try_from(value: OwnedValue) -> Result<Self> {
335        Str::try_from(value)
336            .map_err(Into::into)
337            .and_then(TryInto::try_into)
338    }
339}
340
341impl TryFrom<BusName<'static>> for OwnedValue {
342    type Error = Error;
343
344    fn try_from(name: BusName<'static>) -> Result<Self> {
345        match name {
346            BusName::Unique(name) => name.try_into(),
347            BusName::WellKnown(name) => name.try_into(),
348        }
349        .map_err(Into::into)
350    }
351}
352
353impl From<OwnedUniqueName> for BusName<'_> {
354    fn from(name: OwnedUniqueName) -> Self {
355        BusName::Unique(name.into())
356    }
357}
358
359impl<'a> From<&'a OwnedUniqueName> for BusName<'a> {
360    fn from(name: &'a OwnedUniqueName) -> Self {
361        BusName::Unique(name.into())
362    }
363}
364
365impl From<OwnedWellKnownName> for BusName<'_> {
366    fn from(name: OwnedWellKnownName) -> Self {
367        BusName::WellKnown(name.into())
368    }
369}
370
371impl<'a> From<&'a OwnedWellKnownName> for BusName<'a> {
372    fn from(name: &'a OwnedWellKnownName) -> Self {
373        BusName::WellKnown(name.into())
374    }
375}
376
377/// Owned sibling of [`BusName`].
378#[derive(Clone, Hash, PartialEq, Eq, Serialize, PartialOrd, Ord, Type)]
379pub struct OwnedBusName(#[serde(borrow)] BusName<'static>);
380
381impl_str_basic!(OwnedBusName);
382
383impl OwnedBusName {
384    /// Convert to the inner `BusName`, consuming `self`.
385    pub fn into_inner(self) -> BusName<'static> {
386        self.0
387    }
388
389    /// Get a reference to the inner `BusName`.
390    pub fn inner(&self) -> &BusName<'static> {
391        &self.0
392    }
393}
394
395impl Deref for OwnedBusName {
396    type Target = BusName<'static>;
397
398    fn deref(&self) -> &Self::Target {
399        &self.0
400    }
401}
402
403impl Borrow<str> for OwnedBusName {
404    fn borrow(&self) -> &str {
405        self.0.as_str()
406    }
407}
408
409impl Debug for OwnedBusName {
410    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
411        match &self.0 {
412            BusName::Unique(name) => f
413                .debug_tuple("OwnedBusName::Unique")
414                .field(&name.as_str())
415                .finish(),
416            BusName::WellKnown(name) => f
417                .debug_tuple("OwnedBusName::WellKnown")
418                .field(&name.as_str())
419                .finish(),
420        }
421    }
422}
423
424impl Display for OwnedBusName {
425    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
426        Display::fmt(&BusName::from(self), f)
427    }
428}
429
430impl From<OwnedBusName> for BusName<'_> {
431    fn from(name: OwnedBusName) -> Self {
432        name.into_inner()
433    }
434}
435
436impl<'unowned, 'owned: 'unowned> From<&'owned OwnedBusName> for BusName<'unowned> {
437    fn from(name: &'owned OwnedBusName) -> Self {
438        match &name.0 {
439            BusName::Unique(name) => BusName::Unique(UniqueName::from_str_unchecked(name)),
440            BusName::WellKnown(name) => BusName::WellKnown(WellKnownName::from_str_unchecked(name)),
441        }
442    }
443}
444
445impl From<BusName<'_>> for OwnedBusName {
446    fn from(name: BusName<'_>) -> Self {
447        OwnedBusName(name.into_owned())
448    }
449}
450
451impl TryFrom<&'_ str> for OwnedBusName {
452    type Error = Error;
453
454    fn try_from(value: &str) -> Result<Self> {
455        BusName::try_from(value).map(Self::from)
456    }
457}
458
459impl TryFrom<String> for OwnedBusName {
460    type Error = Error;
461
462    fn try_from(value: String) -> Result<Self> {
463        BusName::try_from(value).map(Self::from)
464    }
465}
466
467impl TryFrom<Cow<'_, str>> for OwnedBusName {
468    type Error = Error;
469
470    fn try_from(value: Cow<'_, str>) -> Result<Self> {
471        BusName::try_from(value).map(Self::from)
472    }
473}
474
475impl TryFrom<Value<'static>> for OwnedBusName {
476    type Error = Error;
477
478    fn try_from(value: Value<'static>) -> Result<Self> {
479        BusName::try_from(value).map(Self::from)
480    }
481}
482
483impl From<OwnedBusName> for Value<'_> {
484    fn from(name: OwnedBusName) -> Self {
485        name.0.into()
486    }
487}
488
489impl TryFrom<OwnedValue> for OwnedBusName {
490    type Error = Error;
491
492    fn try_from(value: OwnedValue) -> Result<Self> {
493        BusName::try_from(value).map(Self::from)
494    }
495}
496
497impl TryFrom<OwnedBusName> for OwnedValue {
498    type Error = Error;
499
500    fn try_from(name: OwnedBusName) -> Result<Self> {
501        name.0.try_into()
502    }
503}
504
505impl From<OwnedBusName> for Str<'_> {
506    fn from(value: OwnedBusName) -> Self {
507        match value.0 {
508            BusName::Unique(name) => name.into(),
509            BusName::WellKnown(name) => name.into(),
510        }
511    }
512}
513
514impl<'de> Deserialize<'de> for OwnedBusName {
515    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
516    where
517        D: de::Deserializer<'de>,
518    {
519        String::deserialize(deserializer)
520            .and_then(|n| BusName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
521            .map(Self)
522    }
523}
524
525impl PartialEq<&str> for OwnedBusName {
526    fn eq(&self, other: &&str) -> bool {
527        self.as_str() == *other
528    }
529}
530
531impl PartialEq<BusName<'_>> for OwnedBusName {
532    fn eq(&self, other: &BusName<'_>) -> bool {
533        self.0 == *other
534    }
535}
536
537impl NoneValue for OwnedBusName {
538    type NoneType = <BusName<'static> as NoneValue>::NoneType;
539
540    fn null_value() -> Self::NoneType {
541        BusName::null_value()
542    }
543}
544
545const INVALID_BUS_NAME_ERROR: &str = "Invalid bus name. \
546    See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus";