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#[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 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 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 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 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 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
185impl<'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
289impl 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#[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 pub fn into_inner(self) -> BusName<'static> {
386 self.0
387 }
388
389 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";