zbus_names/
well_known_name.rs
1use crate::{utils::impl_try_from, Error, Result};
2use serde::{de, Deserialize, Serialize};
3use static_assertions::assert_impl_all;
4use std::{
5 borrow::{Borrow, Cow},
6 convert::TryFrom,
7 fmt::{self, Display, Formatter},
8 ops::Deref,
9 sync::Arc,
10};
11use zvariant::{NoneValue, OwnedValue, Str, Type, Value};
12
13#[derive(
39 Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
40)]
41pub struct WellKnownName<'name>(Str<'name>);
42
43assert_impl_all!(WellKnownName<'_>: Send, Sync, Unpin);
44
45impl<'name> WellKnownName<'name> {
46 pub fn as_ref(&self) -> WellKnownName<'_> {
48 WellKnownName(self.0.as_ref())
49 }
50
51 pub fn as_str(&self) -> &str {
53 self.0.as_str()
54 }
55
56 pub fn from_str_unchecked(name: &'name str) -> Self {
61 Self(Str::from(name))
62 }
63
64 pub fn from_static_str(name: &'static str) -> Result<Self> {
66 ensure_correct_well_known_name(name)?;
67 Ok(Self(Str::from_static(name)))
68 }
69
70 pub const fn from_static_str_unchecked(name: &'static str) -> Self {
72 Self(Str::from_static(name))
73 }
74
75 pub fn from_string_unchecked(name: String) -> Self {
80 Self(Str::from(name))
81 }
82
83 pub fn to_owned(&self) -> WellKnownName<'static> {
85 WellKnownName(self.0.to_owned())
86 }
87
88 pub fn into_owned(self) -> WellKnownName<'static> {
90 WellKnownName(self.0.into_owned())
91 }
92}
93
94impl Deref for WellKnownName<'_> {
95 type Target = str;
96
97 fn deref(&self) -> &Self::Target {
98 self.as_str()
99 }
100}
101
102impl Borrow<str> for WellKnownName<'_> {
103 fn borrow(&self) -> &str {
104 self.as_str()
105 }
106}
107
108impl Display for WellKnownName<'_> {
109 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
110 Display::fmt(&self.as_str(), f)
111 }
112}
113
114impl<'a> PartialEq<str> for WellKnownName<'a> {
115 fn eq(&self, other: &str) -> bool {
116 self.as_str() == other
117 }
118}
119
120impl<'a> PartialEq<&str> for WellKnownName<'a> {
121 fn eq(&self, other: &&str) -> bool {
122 self.as_str() == *other
123 }
124}
125
126impl PartialEq<OwnedWellKnownName> for WellKnownName<'_> {
127 fn eq(&self, other: &OwnedWellKnownName) -> bool {
128 *self == other.0
129 }
130}
131
132impl<'de: 'name, 'name> Deserialize<'de> for WellKnownName<'name> {
133 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
134 where
135 D: serde::Deserializer<'de>,
136 {
137 let name = <Cow<'name, str>>::deserialize(deserializer)?;
138
139 Self::try_from(name).map_err(|e| de::Error::custom(e.to_string()))
140 }
141}
142
143fn ensure_correct_well_known_name(name: &str) -> Result<()> {
144 if name.is_empty() {
154 return Err(Error::InvalidWellKnownName(String::from(
155 "must contain at least 3 characters",
156 )));
157 } else if name.len() < 3 {
158 return Err(Error::InvalidWellKnownName(format!(
159 "`{}` is {} characters long, which is smaller than minimum allowed (3)",
160 name,
161 name.len(),
162 )));
163 } else if name.len() > 255 {
164 return Err(Error::InvalidWellKnownName(format!(
165 "`{}` is {} characters long, which is longer than maximum allowed (255)",
166 name,
167 name.len(),
168 )));
169 }
170
171 let mut prev = None;
172 let mut no_dot = true;
173 for c in name.chars() {
174 if c == '.' {
175 if prev.is_none() || prev == Some('.') {
176 return Err(Error::InvalidWellKnownName(String::from(
177 "must not contain a double `.`",
178 )));
179 }
180
181 if no_dot {
182 no_dot = false;
183 }
184 } else if c.is_ascii_digit() && (prev.is_none() || prev == Some('.')) {
185 return Err(Error::InvalidWellKnownName(String::from(
186 "each element must not start with a digit",
187 )));
188 } else if !c.is_ascii_alphanumeric() && c != '_' && c != '-' {
189 return Err(Error::InvalidWellKnownName(format!(
190 "`{c}` character not allowed"
191 )));
192 }
193
194 prev = Some(c);
195 }
196
197 if no_dot {
198 return Err(Error::InvalidWellKnownName(String::from(
199 "must contain at least 1 `.`",
200 )));
201 }
202
203 Ok(())
204}
205
206impl TryFrom<()> for WellKnownName<'_> {
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<&WellKnownName<'name>> for WellKnownName<'name> {
217 fn from(name: &WellKnownName<'name>) -> Self {
218 name.clone()
219 }
220}
221
222impl<'name> From<WellKnownName<'name>> for Str<'name> {
223 fn from(value: WellKnownName<'name>) -> Self {
224 value.0
225 }
226}
227
228impl<'name> NoneValue for WellKnownName<'name> {
229 type NoneType = &'name str;
230
231 fn null_value() -> Self::NoneType {
232 <&str>::default()
233 }
234}
235
236#[derive(
238 Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
239)]
240pub struct OwnedWellKnownName(#[serde(borrow)] WellKnownName<'static>);
241
242assert_impl_all!(OwnedWellKnownName: Send, Sync, Unpin);
243
244impl OwnedWellKnownName {
245 pub fn into_inner(self) -> WellKnownName<'static> {
247 self.0
248 }
249
250 pub fn inner(&self) -> &WellKnownName<'static> {
252 &self.0
253 }
254}
255
256impl Deref for OwnedWellKnownName {
257 type Target = WellKnownName<'static>;
258
259 fn deref(&self) -> &Self::Target {
260 &self.0
261 }
262}
263
264impl Borrow<str> for OwnedWellKnownName {
265 fn borrow(&self) -> &str {
266 self.0.as_str()
267 }
268}
269
270impl AsRef<str> for OwnedWellKnownName {
271 fn as_ref(&self) -> &str {
272 self.0.as_str()
273 }
274}
275
276impl Display for OwnedWellKnownName {
277 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
278 WellKnownName::from(self).fmt(f)
279 }
280}
281
282impl From<OwnedWellKnownName> for WellKnownName<'static> {
283 fn from(name: OwnedWellKnownName) -> Self {
284 name.into_inner()
285 }
286}
287
288impl<'unowned, 'owned: 'unowned> From<&'owned OwnedWellKnownName> for WellKnownName<'unowned> {
289 fn from(name: &'owned OwnedWellKnownName) -> Self {
290 WellKnownName::from_str_unchecked(name.as_str())
291 }
292}
293
294impl From<WellKnownName<'_>> for OwnedWellKnownName {
295 fn from(name: WellKnownName<'_>) -> Self {
296 OwnedWellKnownName(name.into_owned())
297 }
298}
299
300impl_try_from! {
301 ty: WellKnownName<'s>,
302 owned_ty: OwnedWellKnownName,
303 validate_fn: ensure_correct_well_known_name,
304 try_from: [&'s str, String, Arc<str>, Cow<'s, str>, Str<'s>],
305}
306
307impl From<OwnedWellKnownName> for Str<'static> {
308 fn from(value: OwnedWellKnownName) -> Self {
309 value.into_inner().0
310 }
311}
312
313impl<'de> Deserialize<'de> for OwnedWellKnownName {
314 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
315 where
316 D: de::Deserializer<'de>,
317 {
318 String::deserialize(deserializer)
319 .and_then(|n| WellKnownName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
320 .map(Self)
321 }
322}
323
324impl PartialEq<&str> for OwnedWellKnownName {
325 fn eq(&self, other: &&str) -> bool {
326 self.as_str() == *other
327 }
328}
329
330impl PartialEq<WellKnownName<'_>> for OwnedWellKnownName {
331 fn eq(&self, other: &WellKnownName<'_>) -> bool {
332 self.0 == *other
333 }
334}
335
336impl NoneValue for OwnedWellKnownName {
337 type NoneType = <WellKnownName<'static> as NoneValue>::NoneType;
338
339 fn null_value() -> Self::NoneType {
340 WellKnownName::null_value()
341 }
342}