aldrin_core/
ids.rs

1use crate::error::{DeserializeError, SerializeError};
2use crate::value_deserializer::{Deserialize, Deserializer};
3use crate::value_serializer::{Serialize, Serializer};
4use std::fmt;
5use std::str::FromStr;
6use uuid::{Error as UuidError, Uuid};
7
8/// Id of an object.
9///
10/// [`ObjectId`s][Self] consist of two parts:
11/// - An [`ObjectUuid`], identifying the object on the bus
12/// - An [`ObjectCookie`], a random UUID chosen by the broker
13///
14/// It is important to point out, that when an object is destroyed and later created again with the
15/// same [`ObjectUuid`], then the [`ObjectCookie`] and consequently the [`ObjectId`] will be
16/// different.
17#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
18#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
19pub struct ObjectId {
20    /// UUID of the object.
21    pub uuid: ObjectUuid,
22
23    /// Cookie of the object.
24    pub cookie: ObjectCookie,
25}
26
27impl ObjectId {
28    /// Nil `ObjectId` (all zeros).
29    pub const NIL: Self = Self::new(ObjectUuid::NIL, ObjectCookie::NIL);
30
31    /// Creates a new [`ObjectId`] from an [`ObjectUuid`] and [`ObjectCookie`].
32    pub const fn new(uuid: ObjectUuid, cookie: ObjectCookie) -> Self {
33        ObjectId { uuid, cookie }
34    }
35
36    /// Checks if the id is nil (all zeros).
37    pub const fn is_nil(&self) -> bool {
38        self.uuid.is_nil() && self.cookie.is_nil()
39    }
40}
41
42impl Serialize for ObjectId {
43    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
44        serializer.serialize_object_id(*self);
45        Ok(())
46    }
47}
48
49impl Deserialize for ObjectId {
50    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
51        deserializer.deserialize_object_id()
52    }
53}
54
55/// UUID of an object.
56///
57/// [`ObjectUuid`s](Self) are chosen by the user when creating an object and must be unique among
58/// all objects on the bus.
59#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
60#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
61#[repr(transparent)]
62pub struct ObjectUuid(pub Uuid);
63
64impl ObjectUuid {
65    /// Nil `ObjectUuid` (all zeros).
66    pub const NIL: Self = Self(Uuid::nil());
67
68    /// Creates an [`ObjectUuid`] with a random v4 UUID.
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// # use aldrin_core::ObjectUuid;
74    /// let object_uuid = ObjectUuid::new_v4();
75    /// ```
76    #[cfg(feature = "new-v4-ids")]
77    pub fn new_v4() -> Self {
78        Self(Uuid::new_v4())
79    }
80
81    /// Checks if the id is nil (all zeros).
82    pub const fn is_nil(&self) -> bool {
83        self.0.is_nil()
84    }
85}
86
87impl Serialize for ObjectUuid {
88    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
89        serializer.serialize_uuid(self.0);
90        Ok(())
91    }
92}
93
94impl Deserialize for ObjectUuid {
95    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
96        deserializer.deserialize_uuid().map(Self)
97    }
98}
99
100impl From<Uuid> for ObjectUuid {
101    fn from(uuid: Uuid) -> Self {
102        ObjectUuid(uuid)
103    }
104}
105
106impl From<ObjectUuid> for Uuid {
107    fn from(uuid: ObjectUuid) -> Self {
108        uuid.0
109    }
110}
111
112impl fmt::Display for ObjectUuid {
113    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114        self.0.fmt(f)
115    }
116}
117
118impl FromStr for ObjectUuid {
119    type Err = UuidError;
120
121    fn from_str(s: &str) -> Result<Self, UuidError> {
122        s.parse().map(Self)
123    }
124}
125
126/// Cookie of an object.
127///
128/// [`ObjectCookie`s](Self) are chosen by the broker when creating an object. They ensure that
129/// objects, created and destroyed over time with the same [`ObjectUuid`], can still be
130/// distinguished.
131#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
132#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
133#[repr(transparent)]
134pub struct ObjectCookie(pub Uuid);
135
136impl ObjectCookie {
137    /// Nil `ObjectCookie` (all zeros).
138    pub const NIL: Self = Self(Uuid::nil());
139
140    /// Creates an [`ObjectCookie`] with a random v4 UUID.
141    ///
142    /// # Examples
143    ///
144    /// ```
145    /// # use aldrin_core::ObjectCookie;
146    /// let object_cookie = ObjectCookie::new_v4();
147    /// ```
148    #[cfg(feature = "new-v4-ids")]
149    pub fn new_v4() -> Self {
150        Self(Uuid::new_v4())
151    }
152
153    /// Checks if the id is nil (all zeros).
154    pub const fn is_nil(&self) -> bool {
155        self.0.is_nil()
156    }
157}
158
159impl Serialize for ObjectCookie {
160    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
161        serializer.serialize_uuid(self.0);
162        Ok(())
163    }
164}
165
166impl Deserialize for ObjectCookie {
167    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
168        deserializer.deserialize_uuid().map(Self)
169    }
170}
171
172impl From<Uuid> for ObjectCookie {
173    fn from(cookie: Uuid) -> Self {
174        ObjectCookie(cookie)
175    }
176}
177
178impl From<ObjectCookie> for Uuid {
179    fn from(cookie: ObjectCookie) -> Self {
180        cookie.0
181    }
182}
183
184impl fmt::Display for ObjectCookie {
185    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
186        self.0.fmt(f)
187    }
188}
189
190/// Id of a service.
191///
192/// A [`ServiceId`] consists of three parts:
193/// - An [`ObjectId`], identifying the associated object on the bus
194/// - A [`ServiceUuid`], identifying the service of the object
195/// - A [`ServiceCookie`], a random UUID chosen by the broker
196///
197/// It is important to point out, that when a service is destroyed and later created again with the
198/// same [`ServiceUuid`], then the [`ServiceCookie`] and consequently the [`ServiceId`] will be
199/// different.
200#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
201#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
202pub struct ServiceId {
203    /// Id of the associated object.
204    pub object_id: ObjectId,
205
206    /// UUID of the service.
207    pub uuid: ServiceUuid,
208
209    /// Cookie of the service.
210    pub cookie: ServiceCookie,
211}
212
213impl ServiceId {
214    /// Nil `ServiceId` (all zeros).
215    pub const NIL: Self = Self::new(ObjectId::NIL, ServiceUuid::NIL, ServiceCookie::NIL);
216
217    /// Creates a new [`ServiceId`] from an [`ObjectId`], a [`ServiceUuid`] and a [`ServiceCookie`].
218    pub const fn new(object_id: ObjectId, uuid: ServiceUuid, cookie: ServiceCookie) -> Self {
219        ServiceId {
220            object_id,
221            uuid,
222            cookie,
223        }
224    }
225
226    /// Checks if the id is nil (all zeros).
227    pub const fn is_nil(&self) -> bool {
228        self.object_id.is_nil() && self.uuid.is_nil() && self.cookie.is_nil()
229    }
230}
231
232impl Serialize for ServiceId {
233    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
234        serializer.serialize_service_id(*self);
235        Ok(())
236    }
237}
238
239impl Deserialize for ServiceId {
240    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
241        deserializer.deserialize_service_id()
242    }
243}
244
245/// UUID of a service.
246///
247/// [`ServiceUuid`s](Self) are chosen by the user when creating a service and must be unique among
248/// all services of an object.
249#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
250#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
251#[repr(transparent)]
252pub struct ServiceUuid(pub Uuid);
253
254impl ServiceUuid {
255    /// Nil `ServiceUuid` (all zeros).
256    pub const NIL: Self = Self(Uuid::nil());
257
258    /// Creates a [`ServiceUuid`] with a random v4 UUID.
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// # use aldrin_core::ServiceUuid;
264    /// let service_uuid = ServiceUuid::new_v4();
265    /// ```
266    #[cfg(feature = "new-v4-ids")]
267    pub fn new_v4() -> Self {
268        Self(Uuid::new_v4())
269    }
270
271    /// Checks if the id is nil (all zeros).
272    pub const fn is_nil(&self) -> bool {
273        self.0.is_nil()
274    }
275}
276
277impl Serialize for ServiceUuid {
278    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
279        serializer.serialize_uuid(self.0);
280        Ok(())
281    }
282}
283
284impl Deserialize for ServiceUuid {
285    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
286        deserializer.deserialize_uuid().map(Self)
287    }
288}
289
290impl From<Uuid> for ServiceUuid {
291    fn from(uuid: Uuid) -> Self {
292        ServiceUuid(uuid)
293    }
294}
295
296impl From<ServiceUuid> for Uuid {
297    fn from(uuid: ServiceUuid) -> Self {
298        uuid.0
299    }
300}
301
302impl fmt::Display for ServiceUuid {
303    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304        self.0.fmt(f)
305    }
306}
307
308impl FromStr for ServiceUuid {
309    type Err = UuidError;
310
311    fn from_str(s: &str) -> Result<Self, UuidError> {
312        s.parse().map(Self)
313    }
314}
315
316/// Cookie of a service.
317///
318/// [`ServiceCookie`s](Self) are chosen by the broker when creating a service. They ensure that
319/// services, created and destroyed over time with the same [`ServiceUuid`] and on the same object,
320/// can still be distinguished.
321#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
322#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
323#[repr(transparent)]
324pub struct ServiceCookie(pub Uuid);
325
326impl ServiceCookie {
327    /// Nil `ServiceCookie` (all zeros).
328    pub const NIL: Self = Self(Uuid::nil());
329
330    /// Creates a [`ServiceCookie`] with a random v4 UUID.
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// # use aldrin_core::ServiceCookie;
336    /// let service_cookie = ServiceCookie::new_v4();
337    /// ```
338    #[cfg(feature = "new-v4-ids")]
339    pub fn new_v4() -> Self {
340        Self(Uuid::new_v4())
341    }
342
343    /// Checks if the id is nil (all zeros).
344    pub const fn is_nil(&self) -> bool {
345        self.0.is_nil()
346    }
347}
348
349impl Serialize for ServiceCookie {
350    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
351        serializer.serialize_uuid(self.0);
352        Ok(())
353    }
354}
355
356impl Deserialize for ServiceCookie {
357    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
358        deserializer.deserialize_uuid().map(Self)
359    }
360}
361
362impl From<Uuid> for ServiceCookie {
363    fn from(cookie: Uuid) -> Self {
364        ServiceCookie(cookie)
365    }
366}
367
368impl From<ServiceCookie> for Uuid {
369    fn from(cookie: ServiceCookie) -> Self {
370        cookie.0
371    }
372}
373
374impl fmt::Display for ServiceCookie {
375    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
376        self.0.fmt(f)
377    }
378}
379
380/// Cookie of a channel.
381///
382/// [`ChannelCookie`s](Self) are chosen by the broker when creating a channel.
383#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
384#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
385#[repr(transparent)]
386pub struct ChannelCookie(pub Uuid);
387
388impl ChannelCookie {
389    /// Nil `ChannelCookie` (all zeros).
390    pub const NIL: Self = Self(Uuid::nil());
391
392    /// Creates a [`ChannelCookie`] with a random v4 UUID.
393    ///
394    /// # Examples
395    ///
396    /// ```
397    /// # use aldrin_core::ChannelCookie;
398    /// let channel_cookie = ChannelCookie::new_v4();
399    /// ```
400    #[cfg(feature = "new-v4-ids")]
401    pub fn new_v4() -> Self {
402        Self(Uuid::new_v4())
403    }
404
405    /// Checks if the id is nil (all zeros).
406    pub const fn is_nil(&self) -> bool {
407        self.0.is_nil()
408    }
409}
410
411impl Serialize for ChannelCookie {
412    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
413        serializer.serialize_uuid(self.0);
414        Ok(())
415    }
416}
417
418impl Deserialize for ChannelCookie {
419    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
420        deserializer.deserialize_uuid().map(Self)
421    }
422}
423
424impl From<Uuid> for ChannelCookie {
425    fn from(cookie: Uuid) -> Self {
426        ChannelCookie(cookie)
427    }
428}
429
430impl From<ChannelCookie> for Uuid {
431    fn from(cookie: ChannelCookie) -> Self {
432        cookie.0
433    }
434}
435
436impl fmt::Display for ChannelCookie {
437    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
438        self.0.fmt(f)
439    }
440}
441
442/// Cookie of a bus listener.
443///
444/// [`BusListenerCookie`s](Self) are chosen by the broker when creating a bus listener.
445#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
446#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
447#[repr(transparent)]
448pub struct BusListenerCookie(pub Uuid);
449
450impl BusListenerCookie {
451    /// Nil `BusListenerCookie` (all zeros).
452    pub const NIL: Self = Self(Uuid::nil());
453
454    /// Creates a [`BusListenerCookie`] with a random v4 UUID.
455    ///
456    /// # Examples
457    ///
458    /// ```
459    /// # use aldrin_core::BusListenerCookie;
460    /// let bus_listener_cookie = BusListenerCookie::new_v4();
461    /// ```
462    #[cfg(feature = "new-v4-ids")]
463    pub fn new_v4() -> Self {
464        Self(Uuid::new_v4())
465    }
466
467    /// Checks if the id is nil (all zeros).
468    pub const fn is_nil(&self) -> bool {
469        self.0.is_nil()
470    }
471}
472
473impl From<Uuid> for BusListenerCookie {
474    fn from(cookie: Uuid) -> Self {
475        Self(cookie)
476    }
477}
478
479impl From<BusListenerCookie> for Uuid {
480    fn from(cookie: BusListenerCookie) -> Self {
481        cookie.0
482    }
483}
484
485impl fmt::Display for BusListenerCookie {
486    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
487        self.0.fmt(f)
488    }
489}