zbus_names/
interface_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(
42 Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
43)]
44pub struct InterfaceName<'name>(Str<'name>);
45
46impl_str_basic!(InterfaceName<'_>);
47
48assert_impl_all!(InterfaceName<'_>: Send, Sync, Unpin);
49
50impl<'name> InterfaceName<'name> {
51 pub fn as_ref(&self) -> InterfaceName<'_> {
53 InterfaceName(self.0.as_ref())
54 }
55
56 pub fn as_str(&self) -> &str {
58 self.0.as_str()
59 }
60
61 pub fn from_str_unchecked(name: &'name str) -> Self {
66 Self(Str::from(name))
67 }
68
69 pub fn from_static_str(name: &'static str) -> Result<Self> {
71 validate(name)?;
72 Ok(Self(Str::from_static(name)))
73 }
74
75 pub const fn from_static_str_unchecked(name: &'static str) -> Self {
77 Self(Str::from_static(name))
78 }
79
80 pub fn from_string_unchecked(name: String) -> Self {
85 Self(Str::from(name))
86 }
87
88 pub fn to_owned(&self) -> InterfaceName<'static> {
90 InterfaceName(self.0.to_owned())
91 }
92
93 pub fn into_owned(self) -> InterfaceName<'static> {
95 InterfaceName(self.0.into_owned())
96 }
97}
98
99impl Deref for InterfaceName<'_> {
100 type Target = str;
101
102 fn deref(&self) -> &Self::Target {
103 self.as_str()
104 }
105}
106
107impl Borrow<str> for InterfaceName<'_> {
108 fn borrow(&self) -> &str {
109 self.as_str()
110 }
111}
112
113impl Display for InterfaceName<'_> {
114 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
115 Display::fmt(&self.as_str(), f)
116 }
117}
118
119impl PartialEq<str> for InterfaceName<'_> {
120 fn eq(&self, other: &str) -> bool {
121 self.as_str() == other
122 }
123}
124
125impl PartialEq<&str> for InterfaceName<'_> {
126 fn eq(&self, other: &&str) -> bool {
127 self.as_str() == *other
128 }
129}
130
131impl PartialEq<OwnedInterfaceName> for InterfaceName<'_> {
132 fn eq(&self, other: &OwnedInterfaceName) -> bool {
133 *self == other.0
134 }
135}
136
137impl<'de: 'name, 'name> Deserialize<'de> for InterfaceName<'name> {
138 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
139 where
140 D: serde::Deserializer<'de>,
141 {
142 let name = <Cow<'name, str>>::deserialize(deserializer)?;
143
144 Self::try_from(name).map_err(|e| de::Error::custom(e.to_string()))
145 }
146}
147
148impl_try_from! {
149 ty:InterfaceName<'s>,
150 owned_ty: OwnedInterfaceName,
151 validate_fn: validate,
152 try_from: [&'s str, String, Arc<str>, Cow<'s, str>, Str<'s>],
153}
154
155impl<'name> From<InterfaceName<'name>> for Str<'name> {
156 fn from(value: InterfaceName<'name>) -> Self {
157 value.0
158 }
159}
160
161fn validate(name: &str) -> Result<()> {
162 validate_bytes(name.as_bytes()).map_err(|_| {
163 Error::InvalidName(
164 "Invalid interface name. See \
165 https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface"
166 )
167 })
168}
169
170pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> {
171 use winnow::{
172 combinator::separated,
173 stream::AsChar,
174 token::{one_of, take_while},
175 Parser,
176 };
177 let first_element_char = one_of((AsChar::is_alpha, b'_'));
189 let subsequent_element_chars = take_while::<_, _, ()>(0.., (AsChar::is_alphanum, b'_'));
190 let element = (first_element_char, subsequent_element_chars);
191 let mut interface_name = separated(2.., element, b'.');
192
193 interface_name
194 .parse(bytes)
195 .map_err(|_| ())
196 .and_then(|_: ()| {
197 if bytes.len() > 255 {
199 return Err(());
200 }
201
202 Ok(())
203 })
204}
205
206impl TryFrom<()> for InterfaceName<'_> {
209 type Error = Error;
210
211 fn try_from(_value: ()) -> Result<Self> {
212 unreachable!("Conversion from `()` is not meant to actually work");
213 }
214}
215
216impl<'name> From<&InterfaceName<'name>> for InterfaceName<'name> {
217 fn from(name: &InterfaceName<'name>) -> Self {
218 name.clone()
219 }
220}
221
222impl<'name> NoneValue for InterfaceName<'name> {
223 type NoneType = &'name str;
224
225 fn null_value() -> Self::NoneType {
226 <&str>::default()
227 }
228}
229
230#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)]
232pub struct OwnedInterfaceName(#[serde(borrow)] InterfaceName<'static>);
233
234assert_impl_all!(OwnedInterfaceName: Send, Sync, Unpin);
235
236impl_str_basic!(OwnedInterfaceName);
237
238impl OwnedInterfaceName {
239 pub fn into_inner(self) -> InterfaceName<'static> {
241 self.0
242 }
243
244 pub fn inner(&self) -> &InterfaceName<'static> {
246 &self.0
247 }
248}
249
250impl Deref for OwnedInterfaceName {
251 type Target = InterfaceName<'static>;
252
253 fn deref(&self) -> &Self::Target {
254 &self.0
255 }
256}
257
258impl Borrow<str> for OwnedInterfaceName {
259 fn borrow(&self) -> &str {
260 self.0.as_str()
261 }
262}
263
264impl From<OwnedInterfaceName> for InterfaceName<'_> {
265 fn from(o: OwnedInterfaceName) -> Self {
266 o.into_inner()
267 }
268}
269
270impl<'unowned, 'owned: 'unowned> From<&'owned OwnedInterfaceName> for InterfaceName<'unowned> {
271 fn from(name: &'owned OwnedInterfaceName) -> Self {
272 InterfaceName::from_str_unchecked(name.as_str())
273 }
274}
275
276impl From<InterfaceName<'_>> for OwnedInterfaceName {
277 fn from(name: InterfaceName<'_>) -> Self {
278 OwnedInterfaceName(name.into_owned())
279 }
280}
281
282impl From<OwnedInterfaceName> for Str<'_> {
283 fn from(value: OwnedInterfaceName) -> Self {
284 value.into_inner().0
285 }
286}
287
288impl<'de> Deserialize<'de> for OwnedInterfaceName {
289 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
290 where
291 D: de::Deserializer<'de>,
292 {
293 String::deserialize(deserializer)
294 .and_then(|n| InterfaceName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
295 .map(Self)
296 }
297}
298
299impl PartialEq<&str> for OwnedInterfaceName {
300 fn eq(&self, other: &&str) -> bool {
301 self.as_str() == *other
302 }
303}
304
305impl PartialEq<InterfaceName<'_>> for OwnedInterfaceName {
306 fn eq(&self, other: &InterfaceName<'_>) -> bool {
307 self.0 == *other
308 }
309}
310
311impl Debug for OwnedInterfaceName {
312 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
313 f.debug_tuple("OwnedInterfaceName")
314 .field(&self.as_str())
315 .finish()
316 }
317}
318
319impl Display for OwnedInterfaceName {
320 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
321 Display::fmt(&InterfaceName::from(self), f)
322 }
323}
324
325impl NoneValue for OwnedInterfaceName {
326 type NoneType = <InterfaceName<'static> as NoneValue>::NoneType;
327
328 fn null_value() -> Self::NoneType {
329 InterfaceName::null_value()
330 }
331}