zbus_names/
unique_name.rs1use crate::{
2 utils::{impl_str_basic, impl_try_from},
3 Error, Result,
4};
5use serde::{de, Deserialize, Serialize};
6use static_assertions::assert_impl_all;
7use std::{
8 borrow::{Borrow, Cow},
9 fmt::{self, Debug, Display, Formatter},
10 ops::Deref,
11 sync::Arc,
12};
13use zvariant::{NoneValue, OwnedValue, Str, Type, Value};
14
15#[derive(
39 Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
40)]
41pub struct UniqueName<'name>(pub(crate) Str<'name>);
42
43assert_impl_all!(UniqueName<'_>: Send, Sync, Unpin);
44
45impl_str_basic!(UniqueName<'_>);
46
47impl<'name> UniqueName<'name> {
48 pub fn as_ref(&self) -> UniqueName<'_> {
50 UniqueName(self.0.as_ref())
51 }
52
53 pub fn as_str(&self) -> &str {
55 self.0.as_str()
56 }
57
58 pub fn from_str_unchecked(name: &'name str) -> Self {
63 Self(Str::from(name))
64 }
65
66 pub fn from_static_str(name: &'static str) -> Result<Self> {
68 validate(name)?;
69 Ok(Self(Str::from_static(name)))
70 }
71
72 pub const fn from_static_str_unchecked(name: &'static str) -> Self {
74 Self(Str::from_static(name))
75 }
76
77 pub fn from_string_unchecked(name: String) -> Self {
82 Self(Str::from(name))
83 }
84
85 pub fn to_owned(&self) -> UniqueName<'static> {
87 UniqueName(self.0.to_owned())
88 }
89
90 pub fn into_owned(self) -> UniqueName<'static> {
92 UniqueName(self.0.into_owned())
93 }
94}
95
96impl Deref for UniqueName<'_> {
97 type Target = str;
98
99 fn deref(&self) -> &Self::Target {
100 self.as_str()
101 }
102}
103
104impl Borrow<str> for UniqueName<'_> {
105 fn borrow(&self) -> &str {
106 self.as_str()
107 }
108}
109
110impl Display for UniqueName<'_> {
111 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
112 Display::fmt(&self.as_str(), f)
113 }
114}
115
116impl PartialEq<str> for UniqueName<'_> {
117 fn eq(&self, other: &str) -> bool {
118 self.as_str() == other
119 }
120}
121
122impl PartialEq<&str> for UniqueName<'_> {
123 fn eq(&self, other: &&str) -> bool {
124 self.as_str() == *other
125 }
126}
127
128impl PartialEq<OwnedUniqueName> for UniqueName<'_> {
129 fn eq(&self, other: &OwnedUniqueName) -> bool {
130 *self == other.0
131 }
132}
133
134impl<'de: 'name, 'name> Deserialize<'de> for UniqueName<'name> {
135 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
136 where
137 D: serde::Deserializer<'de>,
138 {
139 let name = <Cow<'name, str>>::deserialize(deserializer)?;
140
141 Self::try_from(name).map_err(|e| de::Error::custom(e.to_string()))
142 }
143}
144
145fn validate(name: &str) -> Result<()> {
146 validate_bytes(name.as_bytes()).map_err(|_| {
147 Error::InvalidName(
148 "Invalid unique name. \
149 See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus"
150 )
151 })
152}
153
154pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> {
155 use winnow::{
156 combinator::{alt, separated},
157 stream::AsChar,
158 token::take_while,
159 Parser,
160 };
161 let element = take_while::<_, _, ()>(1.., (AsChar::is_alphanum, b'_', b'-'));
169 let peer_name = (b':', (separated(2.., element, b'.'))).map(|_: (_, ())| ());
170 let bus_name = b"org.freedesktop.DBus".map(|_| ());
171 let mut unique_name = alt((bus_name, peer_name));
172
173 unique_name.parse(bytes).map_err(|_| ()).and_then(|_: ()| {
174 if bytes.len() > 255 {
176 return Err(());
177 }
178
179 Ok(())
180 })
181}
182
183impl TryFrom<()> for UniqueName<'_> {
186 type Error = Error;
187
188 fn try_from(_value: ()) -> Result<Self> {
189 unreachable!("Conversion from `()` is not meant to actually work");
190 }
191}
192
193impl<'name> From<&UniqueName<'name>> for UniqueName<'name> {
194 fn from(name: &UniqueName<'name>) -> Self {
195 name.clone()
196 }
197}
198
199impl<'name> From<UniqueName<'name>> for Str<'name> {
200 fn from(value: UniqueName<'name>) -> Self {
201 value.0
202 }
203}
204
205impl<'name> NoneValue for UniqueName<'name> {
206 type NoneType = &'name str;
207
208 fn null_value() -> Self::NoneType {
209 <&str>::default()
210 }
211}
212
213#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)]
215pub struct OwnedUniqueName(#[serde(borrow)] UniqueName<'static>);
216
217assert_impl_all!(OwnedUniqueName: Send, Sync, Unpin);
218
219impl_str_basic!(OwnedUniqueName);
220
221impl OwnedUniqueName {
222 pub fn into_inner(self) -> UniqueName<'static> {
224 self.0
225 }
226
227 pub fn inner(&self) -> &UniqueName<'static> {
229 &self.0
230 }
231}
232
233impl Deref for OwnedUniqueName {
234 type Target = UniqueName<'static>;
235
236 fn deref(&self) -> &Self::Target {
237 &self.0
238 }
239}
240
241impl Borrow<str> for OwnedUniqueName {
242 fn borrow(&self) -> &str {
243 self.0.as_str()
244 }
245}
246
247impl From<OwnedUniqueName> for UniqueName<'_> {
248 fn from(o: OwnedUniqueName) -> Self {
249 o.into_inner()
250 }
251}
252
253impl<'unowned, 'owned: 'unowned> From<&'owned OwnedUniqueName> for UniqueName<'unowned> {
254 fn from(name: &'owned OwnedUniqueName) -> Self {
255 UniqueName::from_str_unchecked(name.as_str())
256 }
257}
258
259impl From<UniqueName<'_>> for OwnedUniqueName {
260 fn from(name: UniqueName<'_>) -> Self {
261 OwnedUniqueName(name.into_owned())
262 }
263}
264
265impl_try_from! {
266 ty: UniqueName<'s>,
267 owned_ty: OwnedUniqueName,
268 validate_fn: validate,
269 try_from: [&'s str, String, Arc<str>, Cow<'s, str>, Str<'s>],
270}
271
272impl From<OwnedUniqueName> for Str<'_> {
273 fn from(value: OwnedUniqueName) -> Self {
274 value.into_inner().0
275 }
276}
277
278impl<'de> Deserialize<'de> for OwnedUniqueName {
279 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
280 where
281 D: de::Deserializer<'de>,
282 {
283 String::deserialize(deserializer)
284 .and_then(|n| UniqueName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
285 .map(Self)
286 }
287}
288
289impl PartialEq<&str> for OwnedUniqueName {
290 fn eq(&self, other: &&str) -> bool {
291 self.as_str() == *other
292 }
293}
294
295impl PartialEq<UniqueName<'_>> for OwnedUniqueName {
296 fn eq(&self, other: &UniqueName<'_>) -> bool {
297 self.0 == *other
298 }
299}
300
301impl NoneValue for OwnedUniqueName {
302 type NoneType = <UniqueName<'static> as NoneValue>::NoneType;
303
304 fn null_value() -> Self::NoneType {
305 UniqueName::null_value()
306 }
307}
308
309impl Debug for OwnedUniqueName {
310 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
311 f.debug_tuple("OwnedUniqueName")
312 .field(&self.as_str())
313 .finish()
314 }
315}
316
317impl Display for OwnedUniqueName {
318 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
319 Display::fmt(&UniqueName::from(self), f)
320 }
321}