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