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