1 | use core::{ |
2 | borrow::Borrow, |
3 | convert::TryFrom, |
4 | fmt::{self, Display, Formatter}, |
5 | ops::Deref, |
6 | }; |
7 | use std::{borrow::Cow, convert::TryInto, sync::Arc}; |
8 | |
9 | use crate::{Error, OwnedUniqueName, OwnedWellKnownName, Result, UniqueName, WellKnownName}; |
10 | use serde::{de, Deserialize, Serialize}; |
11 | use static_assertions::assert_impl_all; |
12 | use 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)] |
50 | pub enum BusName<'name> { |
51 | #[serde(borrow)] |
52 | Unique(UniqueName<'name>), |
53 | #[serde(borrow)] |
54 | WellKnown(WellKnownName<'name>), |
55 | } |
56 | |
57 | assert_impl_all!(BusName<'_>: Send, Sync, Unpin); |
58 | |
59 | impl<'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 | |
103 | impl Deref for BusName<'_> { |
104 | type Target = str; |
105 | |
106 | fn deref(&self) -> &Self::Target { |
107 | self.as_str() |
108 | } |
109 | } |
110 | |
111 | impl Borrow<str> for BusName<'_> { |
112 | fn borrow(&self) -> &str { |
113 | self.as_str() |
114 | } |
115 | } |
116 | |
117 | impl Display for BusName<'_> { |
118 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
119 | Display::fmt(&self.as_str(), f) |
120 | } |
121 | } |
122 | |
123 | impl PartialEq<str> for BusName<'_> { |
124 | fn eq(&self, other: &str) -> bool { |
125 | self.as_str() == other |
126 | } |
127 | } |
128 | |
129 | impl PartialEq<&str> for BusName<'_> { |
130 | fn eq(&self, other: &&str) -> bool { |
131 | self.as_str() == *other |
132 | } |
133 | } |
134 | |
135 | impl PartialEq<OwnedBusName> for BusName<'_> { |
136 | fn eq(&self, other: &OwnedBusName) -> bool { |
137 | *self == other.0 |
138 | } |
139 | } |
140 | |
141 | impl 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 | |
150 | impl 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 | |
159 | impl<'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. |
168 | impl<'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 | |
179 | impl Type for BusName<'_> { |
180 | fn signature() -> zvariant::Signature<'static> { |
181 | <&str>::signature() |
182 | } |
183 | } |
184 | |
185 | impl<'name> From<UniqueName<'name>> for BusName<'name> { |
186 | fn from(name: UniqueName<'name>) -> Self { |
187 | BusName::Unique(name) |
188 | } |
189 | } |
190 | |
191 | impl<'name> From<WellKnownName<'name>> for BusName<'name> { |
192 | fn from(name: WellKnownName<'name>) -> Self { |
193 | BusName::WellKnown(name) |
194 | } |
195 | } |
196 | |
197 | impl<'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 | |
215 | impl<'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 | |
223 | impl<'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 | |
231 | impl<'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 | |
239 | impl<'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. |
251 | impl 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 | |
259 | impl<'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 | |
267 | impl<'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 | |
276 | impl<'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 | |
285 | impl<'name> From<&BusName<'name>> for BusName<'name> { |
286 | fn from(name: &BusName<'name>) -> Self { |
287 | name.clone() |
288 | } |
289 | } |
290 | |
291 | impl 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 | |
301 | impl 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 | |
310 | impl From<OwnedUniqueName> for BusName<'static> { |
311 | fn from(name: OwnedUniqueName) -> Self { |
312 | BusName::Unique(name.into()) |
313 | } |
314 | } |
315 | |
316 | impl<'a> From<&'a OwnedUniqueName> for BusName<'a> { |
317 | fn from(name: &'a OwnedUniqueName) -> Self { |
318 | BusName::Unique(name.into()) |
319 | } |
320 | } |
321 | |
322 | impl From<OwnedWellKnownName> for BusName<'static> { |
323 | fn from(name: OwnedWellKnownName) -> Self { |
324 | BusName::WellKnown(name.into()) |
325 | } |
326 | } |
327 | |
328 | impl<'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)] |
336 | pub struct OwnedBusName(#[serde(borrow)] BusName<'static>); |
337 | |
338 | impl 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 | |
350 | impl Deref for OwnedBusName { |
351 | type Target = BusName<'static>; |
352 | |
353 | fn deref(&self) -> &Self::Target { |
354 | &self.0 |
355 | } |
356 | } |
357 | |
358 | impl Borrow<str> for OwnedBusName { |
359 | fn borrow(&self) -> &str { |
360 | self.0.as_str() |
361 | } |
362 | } |
363 | |
364 | impl Display for OwnedBusName { |
365 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
366 | BusName::from(self).fmt(f) |
367 | } |
368 | } |
369 | |
370 | impl From<OwnedBusName> for BusName<'static> { |
371 | fn from(name: OwnedBusName) -> Self { |
372 | name.into_inner() |
373 | } |
374 | } |
375 | |
376 | impl<'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 | |
385 | impl From<BusName<'_>> for OwnedBusName { |
386 | fn from(name: BusName<'_>) -> Self { |
387 | OwnedBusName(name.into_owned()) |
388 | } |
389 | } |
390 | |
391 | impl 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 | |
399 | impl 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 | |
407 | impl 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 | |
415 | impl 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 | |
423 | impl From<OwnedBusName> for Value<'static> { |
424 | fn from(name: OwnedBusName) -> Self { |
425 | name.0.into() |
426 | } |
427 | } |
428 | |
429 | impl 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 | |
437 | impl From<OwnedBusName> for OwnedValue { |
438 | fn from(name: OwnedBusName) -> Self { |
439 | name.0.into() |
440 | } |
441 | } |
442 | |
443 | impl 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 | |
452 | impl<'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 | |
463 | impl PartialEq<&str> for OwnedBusName { |
464 | fn eq(&self, other: &&str) -> bool { |
465 | self.as_str() == *other |
466 | } |
467 | } |
468 | |
469 | impl PartialEq<BusName<'_>> for OwnedBusName { |
470 | fn eq(&self, other: &BusName<'_>) -> bool { |
471 | self.0 == *other |
472 | } |
473 | } |
474 | |
475 | impl 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 | |