1use core::{
2 borrow::Borrow,
3 convert::TryFrom,
4 fmt::{self, Display, Formatter},
5 ops::Deref,
6};
7use std::{borrow::Cow, convert::TryInto, sync::Arc};
8
9use crate::{Error, OwnedUniqueName, OwnedWellKnownName, Result, UniqueName, WellKnownName};
10use serde::{de, Deserialize, Serialize};
11use static_assertions::assert_impl_all;
12use zvariant::{NoneValue, OwnedValue, Str, Type, Value};
13
14/// String that identifies a [bus name].
15///
16/// # Examples
17///
18/// ```
19/// use core::convert::TryFrom;
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, Debug, 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
57assert_impl_all!(BusName<'_>: Send, Sync, Unpin);
58
59impl<'name> BusName<'name> {
60 /// A borrowed clone (never allocates, unlike clone).
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 Display for BusName<'_> {
118 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
119 Display::fmt(&self.as_str(), f)
120 }
121}
122
123impl PartialEq<str> for BusName<'_> {
124 fn eq(&self, other: &str) -> bool {
125 self.as_str() == other
126 }
127}
128
129impl PartialEq<&str> for BusName<'_> {
130 fn eq(&self, other: &&str) -> bool {
131 self.as_str() == *other
132 }
133}
134
135impl PartialEq<OwnedBusName> for BusName<'_> {
136 fn eq(&self, other: &OwnedBusName) -> bool {
137 *self == other.0
138 }
139}
140
141impl PartialEq<UniqueName<'_>> for BusName<'_> {
142 fn eq(&self, other: &UniqueName<'_>) -> bool {
143 match self {
144 Self::Unique(name: &UniqueName<'_>) => *name == *other,
145 Self::WellKnown(_) => false,
146 }
147 }
148}
149
150impl PartialEq<WellKnownName<'_>> for BusName<'_> {
151 fn eq(&self, other: &WellKnownName<'_>) -> bool {
152 match self {
153 Self::Unique(_) => false,
154 Self::WellKnown(name: &WellKnownName<'_>) => *name == *other,
155 }
156 }
157}
158
159impl<'name> NoneValue for BusName<'name> {
160 type NoneType = &'name str;
161
162 fn null_value() -> Self::NoneType {
163 <&str>::default()
164 }
165}
166
167// Manual deserialize implementation to get the desired error on invalid bus names.
168impl<'de: 'name, 'name> Deserialize<'de> for BusName<'name> {
169 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
170 where
171 D: serde::Deserializer<'de>,
172 {
173 let name: Cow<'_, str> = <Cow<'name, str>>::deserialize(deserializer)?;
174
175 Self::try_from(name).map_err(|e: Error| de::Error::custom(msg:e.to_string()))
176 }
177}
178
179impl Type for BusName<'_> {
180 fn signature() -> zvariant::Signature<'static> {
181 <&str>::signature()
182 }
183}
184
185impl<'name> From<UniqueName<'name>> for BusName<'name> {
186 fn from(name: UniqueName<'name>) -> Self {
187 BusName::Unique(name)
188 }
189}
190
191impl<'name> From<WellKnownName<'name>> for BusName<'name> {
192 fn from(name: WellKnownName<'name>) -> Self {
193 BusName::WellKnown(name)
194 }
195}
196
197impl<'s> TryFrom<Str<'s>> for BusName<'s> {
198 type Error = Error;
199
200 fn try_from(value: Str<'s>) -> Result<Self> {
201 match UniqueName::try_from(value.clone()) {
202 Err(Error::InvalidUniqueName(unique_err: String)) => match WellKnownName::try_from(value) {
203 Err(Error::InvalidWellKnownName(well_known_err: String)) => {
204 Err(Error::InvalidBusName(unique_err, well_known_err))
205 }
206 Err(e: Error) => Err(e),
207 Ok(name: WellKnownName<'_>) => Ok(BusName::WellKnown(name)),
208 },
209 Err(e: Error) => Err(e),
210 Ok(name: UniqueName<'_>) => Ok(BusName::Unique(name)),
211 }
212 }
213}
214
215impl<'s> TryFrom<&'s str> for BusName<'s> {
216 type Error = Error;
217
218 fn try_from(value: &'s str) -> Result<Self> {
219 Str::from(value).try_into()
220 }
221}
222
223impl<'s> TryFrom<String> for BusName<'s> {
224 type Error = Error;
225
226 fn try_from(value: String) -> Result<Self> {
227 Str::from(value).try_into()
228 }
229}
230
231impl<'s> TryFrom<Arc<str>> for BusName<'s> {
232 type Error = Error;
233
234 fn try_from(value: Arc<str>) -> Result<Self> {
235 Str::from(value).try_into()
236 }
237}
238
239impl<'s> TryFrom<Value<'s>> for BusName<'s> {
240 type Error = Error;
241
242 fn try_from(value: Value<'s>) -> Result<Self> {
243 Str::try_from(value)
244 .map_err(Into::into)
245 .and_then(op:TryInto::try_into)
246 }
247}
248
249/// This never succeeds but is provided so it's easier to pass `Option::None` values for API
250/// requiring `Option<TryInto<impl BusName>>`, since type inference won't work here.
251impl TryFrom<()> for BusName<'_> {
252 type Error = Error;
253
254 fn try_from(_value: ()) -> Result<Self> {
255 unreachable!("Conversion from `()` is not meant to actually work.");
256 }
257}
258
259impl<'name> TryFrom<Cow<'name, str>> for BusName<'name> {
260 type Error = Error;
261
262 fn try_from(value: Cow<'name, str>) -> Result<Self> {
263 Str::from(value).try_into()
264 }
265}
266
267impl<'s> From<BusName<'s>> for Value<'s> {
268 fn from(name: BusName<'s>) -> Self {
269 match name {
270 BusName::Unique(name: UniqueName<'_>) => name.into(),
271 BusName::WellKnown(name: WellKnownName<'_>) => name.into(),
272 }
273 }
274}
275
276impl<'name> From<BusName<'name>> for Str<'name> {
277 fn from(value: BusName<'name>) -> Self {
278 match value {
279 BusName::Unique(name: UniqueName<'_>) => name.into(),
280 BusName::WellKnown(name: WellKnownName<'_>) => name.into(),
281 }
282 }
283}
284
285impl<'name> From<&BusName<'name>> for BusName<'name> {
286 fn from(name: &BusName<'name>) -> Self {
287 name.clone()
288 }
289}
290
291impl TryFrom<OwnedValue> for BusName<'static> {
292 type Error = Error;
293
294 fn try_from(value: OwnedValue) -> Result<Self> {
295 Str::try_from(value)
296 .map_err(Into::into)
297 .and_then(op:TryInto::try_into)
298 }
299}
300
301impl From<BusName<'static>> for OwnedValue {
302 fn from(name: BusName<'static>) -> Self {
303 match name {
304 BusName::Unique(name: UniqueName<'_>) => name.into(),
305 BusName::WellKnown(name: WellKnownName<'_>) => name.into(),
306 }
307 }
308}
309
310impl From<OwnedUniqueName> for BusName<'static> {
311 fn from(name: OwnedUniqueName) -> Self {
312 BusName::Unique(name.into())
313 }
314}
315
316impl<'a> From<&'a OwnedUniqueName> for BusName<'a> {
317 fn from(name: &'a OwnedUniqueName) -> Self {
318 BusName::Unique(name.into())
319 }
320}
321
322impl From<OwnedWellKnownName> for BusName<'static> {
323 fn from(name: OwnedWellKnownName) -> Self {
324 BusName::WellKnown(name.into())
325 }
326}
327
328impl<'a> From<&'a OwnedWellKnownName> for BusName<'a> {
329 fn from(name: &'a OwnedWellKnownName) -> Self {
330 BusName::WellKnown(name.into())
331 }
332}
333
334/// Owned sibling of [`BusName`].
335#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, PartialOrd, Ord, Type)]
336pub struct OwnedBusName(#[serde(borrow)] BusName<'static>);
337
338impl OwnedBusName {
339 /// Convert to the inner `BusName`, consuming `self`.
340 pub fn into_inner(self) -> BusName<'static> {
341 self.0
342 }
343
344 /// Get a reference to the inner `BusName`.
345 pub fn inner(&self) -> &BusName<'static> {
346 &self.0
347 }
348}
349
350impl Deref for OwnedBusName {
351 type Target = BusName<'static>;
352
353 fn deref(&self) -> &Self::Target {
354 &self.0
355 }
356}
357
358impl Borrow<str> for OwnedBusName {
359 fn borrow(&self) -> &str {
360 self.0.as_str()
361 }
362}
363
364impl Display for OwnedBusName {
365 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
366 BusName::from(self).fmt(f)
367 }
368}
369
370impl From<OwnedBusName> for BusName<'static> {
371 fn from(name: OwnedBusName) -> Self {
372 name.into_inner()
373 }
374}
375
376impl<'unowned, 'owned: 'unowned> From<&'owned OwnedBusName> for BusName<'unowned> {
377 fn from(name: &'owned OwnedBusName) -> Self {
378 match &name.0 {
379 BusName::Unique(name: &UniqueName<'_>) => BusName::Unique(UniqueName::from_str_unchecked(name)),
380 BusName::WellKnown(name: &WellKnownName<'_>) => BusName::WellKnown(WellKnownName::from_str_unchecked(name)),
381 }
382 }
383}
384
385impl From<BusName<'_>> for OwnedBusName {
386 fn from(name: BusName<'_>) -> Self {
387 OwnedBusName(name.into_owned())
388 }
389}
390
391impl TryFrom<&'_ str> for OwnedBusName {
392 type Error = Error;
393
394 fn try_from(value: &str) -> Result<Self> {
395 BusName::try_from(value).map(Self::from)
396 }
397}
398
399impl TryFrom<String> for OwnedBusName {
400 type Error = Error;
401
402 fn try_from(value: String) -> Result<Self> {
403 BusName::try_from(value).map(Self::from)
404 }
405}
406
407impl TryFrom<Cow<'_, str>> for OwnedBusName {
408 type Error = Error;
409
410 fn try_from(value: Cow<'_, str>) -> Result<Self> {
411 BusName::try_from(value).map(Self::from)
412 }
413}
414
415impl TryFrom<Value<'static>> for OwnedBusName {
416 type Error = Error;
417
418 fn try_from(value: Value<'static>) -> Result<Self> {
419 BusName::try_from(value).map(Self::from)
420 }
421}
422
423impl From<OwnedBusName> for Value<'static> {
424 fn from(name: OwnedBusName) -> Self {
425 name.0.into()
426 }
427}
428
429impl TryFrom<OwnedValue> for OwnedBusName {
430 type Error = Error;
431
432 fn try_from(value: OwnedValue) -> Result<Self> {
433 BusName::try_from(value).map(Self::from)
434 }
435}
436
437impl From<OwnedBusName> for OwnedValue {
438 fn from(name: OwnedBusName) -> Self {
439 name.0.into()
440 }
441}
442
443impl From<OwnedBusName> for Str<'static> {
444 fn from(value: OwnedBusName) -> Self {
445 match value.0 {
446 BusName::Unique(name: UniqueName<'_>) => name.into(),
447 BusName::WellKnown(name: WellKnownName<'_>) => name.into(),
448 }
449 }
450}
451
452impl<'de> Deserialize<'de> for OwnedBusName {
453 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
454 where
455 D: de::Deserializer<'de>,
456 {
457 String::deserialize(deserializer)
458 .and_then(|n| BusName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
459 .map(Self)
460 }
461}
462
463impl PartialEq<&str> for OwnedBusName {
464 fn eq(&self, other: &&str) -> bool {
465 self.as_str() == *other
466 }
467}
468
469impl PartialEq<BusName<'_>> for OwnedBusName {
470 fn eq(&self, other: &BusName<'_>) -> bool {
471 self.0 == *other
472 }
473}
474
475impl NoneValue for OwnedBusName {
476 type NoneType = <BusName<'static> as NoneValue>::NoneType;
477
478 fn null_value() -> Self::NoneType {
479 BusName::null_value()
480 }
481}
482