zbus_names/
well_known_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 WellKnownName<'name>(Str<'name>);
43
44impl_str_basic!(WellKnownName<'_>);
45
46assert_impl_all!(WellKnownName<'_>: Send, Sync, Unpin);
47
48impl<'name> WellKnownName<'name> {
49 pub fn as_ref(&self) -> WellKnownName<'_> {
51 WellKnownName(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 ensure_correct_well_known_name(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) -> WellKnownName<'static> {
88 WellKnownName(self.0.to_owned())
89 }
90
91 pub fn into_owned(self) -> WellKnownName<'static> {
93 WellKnownName(self.0.into_owned())
94 }
95}
96
97impl Deref for WellKnownName<'_> {
98 type Target = str;
99
100 fn deref(&self) -> &Self::Target {
101 self.as_str()
102 }
103}
104
105impl Borrow<str> for WellKnownName<'_> {
106 fn borrow(&self) -> &str {
107 self.as_str()
108 }
109}
110
111impl Display for WellKnownName<'_> {
112 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
113 Display::fmt(&self.as_str(), f)
114 }
115}
116
117impl<'a> PartialEq<str> for WellKnownName<'a> {
118 fn eq(&self, other: &str) -> bool {
119 self.as_str() == other
120 }
121}
122
123impl<'a> PartialEq<&str> for WellKnownName<'a> {
124 fn eq(&self, other: &&str) -> bool {
125 self.as_str() == *other
126 }
127}
128
129impl PartialEq<OwnedWellKnownName> for WellKnownName<'_> {
130 fn eq(&self, other: &OwnedWellKnownName) -> bool {
131 *self == other.0
132 }
133}
134
135impl<'de: 'name, 'name> Deserialize<'de> for WellKnownName<'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
146fn ensure_correct_well_known_name(name: &str) -> Result<()> {
147 if name.is_empty() {
157 return Err(Error::InvalidWellKnownName(String::from(
158 "must contain at least 3 characters",
159 )));
160 } else if name.len() < 3 {
161 return Err(Error::InvalidWellKnownName(format!(
162 "`{}` is {} characters long, which is smaller than minimum allowed (3)",
163 name,
164 name.len(),
165 )));
166 } else if name.len() > 255 {
167 return Err(Error::InvalidWellKnownName(format!(
168 "`{}` is {} characters long, which is longer than maximum allowed (255)",
169 name,
170 name.len(),
171 )));
172 }
173
174 let mut prev = None;
175 let mut no_dot = true;
176 for c in name.chars() {
177 if c == '.' {
178 if prev.is_none() || prev == Some('.') {
179 return Err(Error::InvalidWellKnownName(String::from(
180 "must not contain a double `.`",
181 )));
182 }
183
184 if no_dot {
185 no_dot = false;
186 }
187 } else if c.is_ascii_digit() && (prev.is_none() || prev == Some('.')) {
188 return Err(Error::InvalidWellKnownName(String::from(
189 "each element must not start with a digit",
190 )));
191 } else if !c.is_ascii_alphanumeric() && c != '_' && c != '-' {
192 return Err(Error::InvalidWellKnownName(format!(
193 "`{c}` character not allowed"
194 )));
195 }
196
197 prev = Some(c);
198 }
199
200 if no_dot {
201 return Err(Error::InvalidWellKnownName(String::from(
202 "must contain at least 1 `.`",
203 )));
204 }
205
206 Ok(())
207}
208
209impl TryFrom<()> for WellKnownName<'_> {
212 type Error = Error;
213
214 fn try_from(_value: ()) -> Result<Self> {
215 unreachable!("Conversion from `()` is not meant to actually work");
216 }
217}
218
219impl<'name> From<&WellKnownName<'name>> for WellKnownName<'name> {
220 fn from(name: &WellKnownName<'name>) -> Self {
221 name.clone()
222 }
223}
224
225impl<'name> From<WellKnownName<'name>> for Str<'name> {
226 fn from(value: WellKnownName<'name>) -> Self {
227 value.0
228 }
229}
230
231impl<'name> NoneValue for WellKnownName<'name> {
232 type NoneType = &'name str;
233
234 fn null_value() -> Self::NoneType {
235 <&str>::default()
236 }
237}
238
239#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)]
241pub struct OwnedWellKnownName(#[serde(borrow)] WellKnownName<'static>);
242
243assert_impl_all!(OwnedWellKnownName: Send, Sync, Unpin);
244
245impl OwnedWellKnownName {
246 pub fn into_inner(self) -> WellKnownName<'static> {
248 self.0
249 }
250
251 pub fn inner(&self) -> &WellKnownName<'static> {
253 &self.0
254 }
255}
256
257impl_str_basic!(OwnedWellKnownName);
258
259impl Deref for OwnedWellKnownName {
260 type Target = WellKnownName<'static>;
261
262 fn deref(&self) -> &Self::Target {
263 &self.0
264 }
265}
266
267impl Borrow<str> for OwnedWellKnownName {
268 fn borrow(&self) -> &str {
269 self.0.as_str()
270 }
271}
272
273impl AsRef<str> for OwnedWellKnownName {
274 fn as_ref(&self) -> &str {
275 self.0.as_str()
276 }
277}
278
279impl Debug for OwnedWellKnownName {
280 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
281 f.debug_tuple("OwnedWellKnownName")
282 .field(&self.as_str())
283 .finish()
284 }
285}
286
287impl Display for OwnedWellKnownName {
288 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
289 Display::fmt(&WellKnownName::from(self), f)
290 }
291}
292
293impl From<OwnedWellKnownName> for WellKnownName<'_> {
294 fn from(name: OwnedWellKnownName) -> Self {
295 name.into_inner()
296 }
297}
298
299impl<'unowned, 'owned: 'unowned> From<&'owned OwnedWellKnownName> for WellKnownName<'unowned> {
300 fn from(name: &'owned OwnedWellKnownName) -> Self {
301 WellKnownName::from_str_unchecked(name.as_str())
302 }
303}
304
305impl From<WellKnownName<'_>> for OwnedWellKnownName {
306 fn from(name: WellKnownName<'_>) -> Self {
307 OwnedWellKnownName(name.into_owned())
308 }
309}
310
311impl_try_from! {
312 ty: WellKnownName<'s>,
313 owned_ty: OwnedWellKnownName,
314 validate_fn: ensure_correct_well_known_name,
315 try_from: [&'s str, String, Arc<str>, Cow<'s, str>, Str<'s>],
316}
317
318impl From<OwnedWellKnownName> for Str<'_> {
319 fn from(value: OwnedWellKnownName) -> Self {
320 value.into_inner().0
321 }
322}
323
324impl<'de> Deserialize<'de> for OwnedWellKnownName {
325 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
326 where
327 D: de::Deserializer<'de>,
328 {
329 String::deserialize(deserializer)
330 .and_then(|n| WellKnownName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
331 .map(Self)
332 }
333}
334
335impl PartialEq<&str> for OwnedWellKnownName {
336 fn eq(&self, other: &&str) -> bool {
337 self.as_str() == *other
338 }
339}
340
341impl PartialEq<WellKnownName<'_>> for OwnedWellKnownName {
342 fn eq(&self, other: &WellKnownName<'_>) -> bool {
343 self.0 == *other
344 }
345}
346
347impl NoneValue for OwnedWellKnownName {
348 type NoneType = <WellKnownName<'static> as NoneValue>::NoneType;
349
350 fn null_value() -> Self::NoneType {
351 WellKnownName::null_value()
352 }
353}