zbus_names/
property_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(
35 Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
36)]
37pub struct PropertyName<'name>(Str<'name>);
38
39assert_impl_all!(PropertyName<'_>: Send, Sync, Unpin);
40
41impl_str_basic!(PropertyName<'_>);
42
43impl<'name> PropertyName<'name> {
44 pub fn as_ref(&self) -> PropertyName<'_> {
46 PropertyName(self.0.as_ref())
47 }
48
49 pub fn as_str(&self) -> &str {
51 self.0.as_str()
52 }
53
54 pub fn from_str_unchecked(name: &'name str) -> Self {
59 Self(Str::from(name))
60 }
61
62 pub fn from_static_str(name: &'static str) -> Result<Self> {
64 ensure_correct_property_name(name)?;
65 Ok(Self(Str::from_static(name)))
66 }
67
68 pub const fn from_static_str_unchecked(name: &'static str) -> Self {
70 Self(Str::from_static(name))
71 }
72
73 pub fn from_string_unchecked(name: String) -> Self {
78 Self(Str::from(name))
79 }
80
81 pub fn to_owned(&self) -> PropertyName<'static> {
83 PropertyName(self.0.to_owned())
84 }
85
86 pub fn into_owned(self) -> PropertyName<'static> {
88 PropertyName(self.0.into_owned())
89 }
90}
91
92impl Deref for PropertyName<'_> {
93 type Target = str;
94
95 fn deref(&self) -> &Self::Target {
96 self.as_str()
97 }
98}
99
100impl Borrow<str> for PropertyName<'_> {
101 fn borrow(&self) -> &str {
102 self.as_str()
103 }
104}
105
106impl Display for PropertyName<'_> {
107 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
108 Display::fmt(&self.as_str(), f)
109 }
110}
111
112impl PartialEq<str> for PropertyName<'_> {
113 fn eq(&self, other: &str) -> bool {
114 self.as_str() == other
115 }
116}
117
118impl PartialEq<&str> for PropertyName<'_> {
119 fn eq(&self, other: &&str) -> bool {
120 self.as_str() == *other
121 }
122}
123
124impl PartialEq<OwnedPropertyName> for PropertyName<'_> {
125 fn eq(&self, other: &OwnedPropertyName) -> bool {
126 *self == other.0
127 }
128}
129
130impl<'de: 'name, 'name> Deserialize<'de> for PropertyName<'name> {
131 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
132 where
133 D: serde::Deserializer<'de>,
134 {
135 let name = <Cow<'name, str>>::deserialize(deserializer)?;
136
137 Self::try_from(name).map_err(|e| de::Error::custom(e.to_string()))
138 }
139}
140
141impl<'name> From<PropertyName<'name>> for Str<'name> {
142 fn from(value: PropertyName<'name>) -> Self {
143 value.0
144 }
145}
146
147impl_try_from! {
148 ty: PropertyName<'s>,
149 owned_ty: OwnedPropertyName,
150 validate_fn: ensure_correct_property_name,
151 try_from: [&'s str, String, Arc<str>, Cow<'s, str>, Str<'s>],
152}
153
154fn ensure_correct_property_name(name: &str) -> Result<()> {
155 if name.is_empty() {
162 return Err(Error::InvalidPropertyName(format!(
163 "`{}` is {} characters long, which is smaller than minimum allowed (1)",
164 name,
165 name.len(),
166 )));
167 } else if name.len() > 255 {
168 return Err(Error::InvalidPropertyName(format!(
169 "`{}` is {} characters long, which is longer than maximum allowed (255)",
170 name,
171 name.len(),
172 )));
173 }
174
175 Ok(())
176}
177
178impl TryFrom<()> for PropertyName<'_> {
181 type Error = Error;
182
183 fn try_from(_value: ()) -> Result<Self> {
184 unreachable!("Conversion from `()` is not meant to actually work");
185 }
186}
187
188impl<'name> From<&PropertyName<'name>> for PropertyName<'name> {
189 fn from(name: &PropertyName<'name>) -> Self {
190 name.clone()
191 }
192}
193
194impl<'name> NoneValue for PropertyName<'name> {
195 type NoneType = &'name str;
196
197 fn null_value() -> Self::NoneType {
198 <&str>::default()
199 }
200}
201
202#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)]
204pub struct OwnedPropertyName(#[serde(borrow)] PropertyName<'static>);
205
206assert_impl_all!(OwnedPropertyName: Send, Sync, Unpin);
207
208impl_str_basic!(OwnedPropertyName);
209
210impl OwnedPropertyName {
211 pub fn into_inner(self) -> PropertyName<'static> {
213 self.0
214 }
215
216 pub fn inner(&self) -> &PropertyName<'static> {
218 &self.0
219 }
220}
221
222impl Deref for OwnedPropertyName {
223 type Target = PropertyName<'static>;
224
225 fn deref(&self) -> &Self::Target {
226 &self.0
227 }
228}
229
230impl Borrow<str> for OwnedPropertyName {
231 fn borrow(&self) -> &str {
232 self.0.as_str()
233 }
234}
235
236impl From<OwnedPropertyName> for PropertyName<'_> {
237 fn from(o: OwnedPropertyName) -> Self {
238 o.into_inner()
239 }
240}
241
242impl<'unowned, 'owned: 'unowned> From<&'owned OwnedPropertyName> for PropertyName<'unowned> {
243 fn from(name: &'owned OwnedPropertyName) -> Self {
244 PropertyName::from_str_unchecked(name.as_str())
245 }
246}
247
248impl From<PropertyName<'_>> for OwnedPropertyName {
249 fn from(name: PropertyName<'_>) -> Self {
250 OwnedPropertyName(name.into_owned())
251 }
252}
253
254impl From<OwnedPropertyName> for Str<'_> {
255 fn from(value: OwnedPropertyName) -> Self {
256 value.into_inner().0
257 }
258}
259
260impl<'de> Deserialize<'de> for OwnedPropertyName {
261 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
262 where
263 D: de::Deserializer<'de>,
264 {
265 String::deserialize(deserializer)
266 .and_then(|n| PropertyName::try_from(n).map_err(|e| de::Error::custom(e.to_string())))
267 .map(Self)
268 }
269}
270
271impl PartialEq<&str> for OwnedPropertyName {
272 fn eq(&self, other: &&str) -> bool {
273 self.as_str() == *other
274 }
275}
276
277impl PartialEq<PropertyName<'_>> for OwnedPropertyName {
278 fn eq(&self, other: &PropertyName<'_>) -> bool {
279 self.0 == *other
280 }
281}
282
283impl Debug for OwnedPropertyName {
284 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
285 f.debug_tuple("OwnedPropertyName")
286 .field(&self.as_str())
287 .finish()
288 }
289}
290
291impl Display for OwnedPropertyName {
292 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
293 Display::fmt(&PropertyName::from(self), f)
294 }
295}
296
297impl NoneValue for OwnedPropertyName {
298 type NoneType = <PropertyName<'static> as NoneValue>::NoneType;
299
300 fn null_value() -> Self::NoneType {
301 PropertyName::null_value()
302 }
303}