rustdds/structure/
guid.rs

1use std::{fmt, hash::Hash, ops::RangeBounds};
2
3use speedy::{Context, Readable, Reader, Writable, Writer};
4use serde::{Deserialize, Serialize};
5use cdr_encoding_size::*;
6use mio_06::Token;
7use log::warn;
8use static_assertions as sa;
9
10use crate::dds::key::Key;
11
12/// DDS/RTPS Participant GuidPrefix
13#[derive(
14  Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Serialize, Deserialize, CdrEncodingSize,
15)]
16pub struct GuidPrefix {
17  pub(crate) bytes: [u8; 12],
18}
19
20impl GuidPrefix {
21  pub const UNKNOWN: Self = Self { bytes: [0x00; 12] };
22
23  pub fn new(prefix: &[u8]) -> Self {
24    let mut bytes: [u8; 12] = [0; 12];
25    for (ix, data) in prefix.iter().enumerate() {
26      if ix >= 12 {
27        break;
28      }
29      bytes[ix] = *data;
30    }
31    Self { bytes }
32  }
33
34  pub fn random_for_this_participant() -> Self {
35    let mut bytes: [u8; 12] = rand::random(); // start with random data
36
37    // The prefix is arbitrary, but let's place our vendor id at the head
38    // for easy recognition. It seems some other RTPS implementations are doing the
39    // same.
40    let my_vendor_id_bytes = crate::messages::vendor_id::VendorId::THIS_IMPLEMENTATION.as_bytes();
41    bytes[0] = my_vendor_id_bytes[0];
42    bytes[1] = my_vendor_id_bytes[1];
43
44    // TODO:
45    // We could add some other identifying stuff here also, like one of
46    // our IP addresses (but which one?)
47
48    Self { bytes }
49  }
50
51  pub fn range(&self) -> impl RangeBounds<GUID> {
52    GUID::new(*self, EntityId::MIN)..=GUID::new(*self, EntityId::MAX)
53  }
54}
55
56impl AsRef<[u8]> for GuidPrefix {
57  fn as_ref(&self) -> &[u8] {
58    &self.bytes
59  }
60}
61
62impl fmt::Debug for GuidPrefix {
63  // This is so common that we skip all the introductions and just print the data.
64  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65    for b in self.bytes.iter() {
66      write!(f, "{:02x}", b)?;
67    }
68    Ok(())
69  }
70}
71
72impl Default for GuidPrefix {
73  fn default() -> Self {
74    Self::UNKNOWN
75  }
76}
77
78impl<'a, C: Context> Readable<'a, C> for GuidPrefix {
79  #[inline]
80  fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
81    let mut guid_prefix = Self::default();
82    for i in 0..guid_prefix.bytes.len() {
83      guid_prefix.bytes[i] = reader.read_u8()?;
84    }
85    Ok(guid_prefix)
86  }
87
88  #[inline]
89  fn minimum_bytes_needed() -> usize {
90    std::mem::size_of::<Self>()
91  }
92}
93
94impl<C: Context> Writable<C> for GuidPrefix {
95  #[inline]
96  fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
97    for elem in &self.bytes {
98      writer.write_u8(*elem)?;
99    }
100    Ok(())
101  }
102}
103
104#[derive(
105  Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Serialize, Deserialize, CdrEncodingSize,
106)]
107pub struct EntityKind(u8);
108
109impl EntityKind {
110  // constants from RTPS spec Table 9.1
111  pub const UNKNOWN_USER_DEFINED: Self = Self(0x00);
112  // pub const PARTICIPANT_USER_DEFINED : Self = Self(0x01);
113  // User-defined participants do not exist by definition.
114  pub const WRITER_WITH_KEY_USER_DEFINED: Self = Self(0x02);
115  pub const WRITER_NO_KEY_USER_DEFINED: Self = Self(0x03);
116  pub const READER_NO_KEY_USER_DEFINED: Self = Self(0x04);
117  pub const READER_WITH_KEY_USER_DEFINED: Self = Self(0x07);
118  pub const WRITER_GROUP_USER_DEFINED: Self = Self(0x08);
119  pub const READER_GROUP_USER_DEFINED: Self = Self(0x09);
120
121  pub const UNKNOWN_BUILT_IN: Self = Self(0xC0);
122  pub const PARTICIPANT_BUILT_IN: Self = Self(0xC1);
123  pub const WRITER_WITH_KEY_BUILT_IN: Self = Self(0xC2);
124  pub const WRITER_NO_KEY_BUILT_IN: Self = Self(0xC3);
125  pub const READER_NO_KEY_BUILT_IN: Self = Self(0xC4);
126  pub const READER_WITH_KEY_BUILT_IN: Self = Self(0xC7);
127  pub const WRITER_GROUP_BUILT_IN: Self = Self(0xC8);
128  pub const READER_GROUP_BUILT_IN: Self = Self(0xC9);
129
130  pub const MIN: Self = Self(0x00);
131  pub const MAX: Self = Self(0xFF);
132
133  // We will encode polling tokens as EntityId, containing an EntityKind
134  // The upper nibble of EntityKind will distinguish between different
135  // poll tokens:
136  // 0 = user-defined entity
137  // 1
138  // 2 = user-defined alt token (timers etc)
139  // 3
140  // 4 = fixed poll tokens (not entity-specific)
141  pub const POLL_TOKEN_BASE: usize = 0x40;
142  // 5 = fixed poll tokens continued
143  // 6 = fixed poll tokens continued
144  // 7 = fixed poll tokens continued
145  // 8 = fixed poll tokens continued
146  // 9
147  // A
148  // B
149  // C = built-in entity
150  // D
151  // E = built-in alt token
152  // F
153
154  pub fn is_reader(&self) -> bool {
155    let e = self.0 & 0x0F;
156    e == 0x04 || e == 0x07 || e == 0x09
157  }
158
159  pub fn is_writer(&self) -> bool {
160    let e = self.0 & 0x0F;
161    e == 0x02 || e == 0x03 || e == 0x08
162  }
163
164  pub fn is_built_in(&self) -> bool {
165    (self.0 & 0xF0) == 0xC0
166  }
167
168  pub fn is_user_defined(&self) -> bool {
169    (self.0 & 0xF0) == 0x00
170  }
171}
172
173impl From<u8> for EntityKind {
174  fn from(b: u8) -> Self {
175    Self(b)
176  }
177}
178
179impl From<EntityKind> for u8 {
180  fn from(ek: EntityKind) -> Self {
181    ek.0
182  }
183}
184impl fmt::Debug for EntityKind {
185  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186    match *self {
187      Self::UNKNOWN_USER_DEFINED => f.write_str("EntityKind::UNKNOWN_USER_DEFINED"),
188      Self::WRITER_WITH_KEY_USER_DEFINED => f.write_str("EntityKind::WRITER_WITH_KEY_USER_DEFINED"),
189      Self::WRITER_NO_KEY_USER_DEFINED => f.write_str("EntityKind::WRITER_NO_KEY_USER_DEFINED"),
190      Self::READER_NO_KEY_USER_DEFINED => f.write_str("EntityKind::READER_NO_KEY_USER_DEFINED"),
191      Self::READER_WITH_KEY_USER_DEFINED => f.write_str("EntityKind::READER_WITH_KEY_USER_DEFINED"),
192      Self::WRITER_GROUP_USER_DEFINED => f.write_str("EntityKind::WRITER_GROUP_USER_DEFINED"),
193      Self::READER_GROUP_USER_DEFINED => f.write_str("EntityKind::READER_GROUP_USER_DEFINED"),
194
195      Self::UNKNOWN_BUILT_IN => f.write_str("EntityKind::UNKNOWN_BUILT_IN"),
196      Self::PARTICIPANT_BUILT_IN => f.write_str("EntityKind::PARTICIPANT_BUILT_IN"),
197      Self::WRITER_WITH_KEY_BUILT_IN => f.write_str("EntityKind::WRITER_WITH_KEY_BUILT_IN"),
198      Self::WRITER_NO_KEY_BUILT_IN => f.write_str("EntityKind::WRITER_NO_KEY_BUILT_IN"),
199      Self::READER_NO_KEY_BUILT_IN => f.write_str("EntityKind::READER_NO_KEY_BUILT_IN"),
200      Self::READER_WITH_KEY_BUILT_IN => f.write_str("EntityKind::READER_WITH_KEY_BUILT_IN"),
201      Self::WRITER_GROUP_BUILT_IN => f.write_str("EntityKind::WRITER_GROUP_BUILT_IN"),
202      Self::READER_GROUP_BUILT_IN => f.write_str("EntityKind::READER_GROUP_BUILT_IN"),
203      _ => f.write_fmt(format_args!("EntityKind({:x?})", self.0)),
204    }
205  }
206}
207
208/// RTPS EntityId
209/// See RTPS spec section 8.2.4 , 8.3.5.1 and 9.3.1.2
210#[derive(
211  Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Serialize, Deserialize, CdrEncodingSize,
212)]
213pub struct EntityId {
214  pub entity_key: [u8; 3],
215  pub entity_kind: EntityKind,
216}
217
218// We are going to pack 32 bits of payload into an usize, or ultimately
219// into a mio::Token, so we need it to be large enough.
220sa::const_assert!(std::mem::size_of::<usize>() >= std::mem::size_of::<u32>());
221
222#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Ord, Eq)]
223pub enum TokenDecode {
224  Entity(EntityId),
225  AltEntity(EntityId),
226  FixedToken(Token),
227}
228
229impl EntityId {
230  pub const UNKNOWN: Self = Self {
231    entity_key: [0x00; 3],
232    entity_kind: EntityKind::UNKNOWN_USER_DEFINED,
233  };
234  pub const PARTICIPANT: Self = Self {
235    entity_key: [0x00, 0x00, 0x01],
236    entity_kind: EntityKind::PARTICIPANT_BUILT_IN,
237  };
238  pub const SEDP_BUILTIN_TOPIC_WRITER: Self = Self {
239    entity_key: [0x00, 0x00, 0x02],
240    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
241  };
242  pub const SEDP_BUILTIN_TOPIC_READER: Self = Self {
243    entity_key: [0x00, 0x00, 0x02],
244    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
245  };
246  pub const SEDP_BUILTIN_PUBLICATIONS_WRITER: Self = Self {
247    entity_key: [0x00, 0x00, 0x03],
248    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
249  };
250  pub const SEDP_BUILTIN_PUBLICATIONS_READER: Self = Self {
251    entity_key: [0x00, 0x00, 0x03],
252    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
253  };
254  pub const SEDP_BUILTIN_SUBSCRIPTIONS_WRITER: Self = Self {
255    entity_key: [0x00, 0x00, 0x04],
256    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
257  };
258  pub const SEDP_BUILTIN_SUBSCRIPTIONS_READER: Self = Self {
259    entity_key: [0x00, 0x00, 0x04],
260    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
261  };
262  pub const SPDP_BUILTIN_PARTICIPANT_WRITER: Self = Self {
263    entity_key: [0x00, 0x01, 0x00],
264    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
265  };
266  pub const SPDP_BUILTIN_PARTICIPANT_READER: Self = Self {
267    entity_key: [0x00, 0x01, 0x00],
268    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
269  };
270  pub const P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER: Self = Self {
271    entity_key: [0x00, 0x02, 0x00],
272    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
273  };
274  pub const P2P_BUILTIN_PARTICIPANT_MESSAGE_READER: Self = Self {
275    entity_key: [0x00, 0x02, 0x00],
276    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
277  };
278
279  // DDS SEcurity spec v1.1
280  // Section "7.3.7 Mapping to UDP/IP PSM"
281  // Table 9 – EntityId values for secure builtin data writers and data readers
282  //
283  pub const SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER: Self = Self {
284    entity_key: [0xff, 0x00, 0x03],
285    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN, // 0xc2
286  };
287  pub const SEDP_BUILTIN_PUBLICATIONS_SECURE_READER: Self = Self {
288    entity_key: [0xff, 0x00, 0x03],
289    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
290  };
291  pub const SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER: Self = Self {
292    entity_key: [0xff, 0x00, 0x04],
293    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
294  };
295  pub const SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER: Self = Self {
296    entity_key: [0xff, 0x00, 0x04],
297    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
298  };
299  pub const P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER: Self = Self {
300    entity_key: [0xff, 0x02, 0x00],
301    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
302  };
303  pub const P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER: Self = Self {
304    entity_key: [0xff, 0x02, 0x00],
305    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
306  };
307  pub const P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER: Self = Self {
308    entity_key: [0x00, 0x02, 0x01],
309    entity_kind: EntityKind::WRITER_NO_KEY_BUILT_IN, //0xc3
310  };
311  pub const P2P_BUILTIN_PARTICIPANT_STATELESS_READER: Self = Self {
312    entity_key: [0x00, 0x02, 0x01],
313    entity_kind: EntityKind::READER_NO_KEY_BUILT_IN, // 0xc4
314  };
315  pub const P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER: Self = Self {
316    entity_key: [0xff, 0x02, 0x02],
317    entity_kind: EntityKind::WRITER_NO_KEY_BUILT_IN,
318  };
319  pub const P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER: Self = Self {
320    entity_key: [0xff, 0x02, 0x02],
321    entity_kind: EntityKind::READER_NO_KEY_BUILT_IN,
322  };
323  pub const SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER: Self = Self {
324    entity_key: [0xff, 0x01, 0x01],
325    entity_kind: EntityKind::WRITER_WITH_KEY_BUILT_IN,
326  };
327  pub const SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER: Self = Self {
328    entity_key: [0xff, 0x01, 0x01],
329    entity_kind: EntityKind::READER_WITH_KEY_BUILT_IN,
330  };
331
332  pub const MIN: Self = Self {
333    entity_key: [0x00; 3],
334    entity_kind: EntityKind::MIN,
335  };
336  pub const MAX: Self = Self {
337    entity_key: [0xFF, 0xFF, 0xFF],
338    entity_kind: EntityKind::MAX,
339  };
340
341  pub fn new(entity_key: [u8; 3], entity_kind: EntityKind) -> Self {
342    Self {
343      entity_key,
344      entity_kind,
345    }
346  }
347
348  #[cfg(test)]
349  pub(crate) fn create_custom_entity_id(entity_key: [u8; 3], entity_kind: EntityKind) -> Self {
350    Self::new(entity_key, entity_kind)
351  }
352
353  fn as_usize(self) -> usize {
354    // usize is generated like this because there needs to be
355    // a way to tell entity kind from the result
356    let u1 = u32::from(self.entity_key[0]);
357    let u2 = u32::from(self.entity_key[1]);
358    let u3 = u32::from(self.entity_key[2]);
359    let u4 = u32::from(self.entity_kind.0);
360
361    // This is essentially big-endian encoding
362    // The type coercion will always succeed, because we have
363    // above a static assert that usize is at least 32-bit
364    ((u1 << 24) | (u2 << 16) | (u3 << 8) | u4) as usize
365  }
366
367  /// Use this only with usize generated with EntityID::as_usize function.!!!
368  fn from_usize(number: usize) -> Self {
369    let u4 = (number & 0xFF) as u8;
370    let u3 = ((number >> 8) & 0xFF) as u8;
371    let u2 = ((number >> 16) & 0xFF) as u8;
372    let u1 = ((number >> 24) & 0xFF) as u8;
373
374    let result = Self {
375      entity_key: [u1, u2, u3],
376      entity_kind: EntityKind::from(u4),
377    };
378
379    // check sanity, as the result should be
380    let kind_kind = u4 & (0xC0 | 0x10);
381    if kind_kind == 0xC0 || kind_kind == 0x00 {
382      // this is ok, all normal
383    } else {
384      warn!("EntityId::from_usize tried to decode 0x{:x?}", number);
385    }
386
387    result
388  }
389
390  pub fn as_token(self) -> Token {
391    let u = self.as_usize();
392    assert_eq!(u & !0x20, u); // check bit 5 is zero
393    Token(u)
394  }
395
396  pub fn as_alt_token(self) -> Token {
397    Token(self.as_usize() | 0x20) // set bit 5
398  }
399
400  pub fn from_token(t: Token) -> TokenDecode {
401    match (t.0 & 0xF0) as u8 {
402      0x00 | 0xC0 => TokenDecode::Entity(Self::from_usize(t.0)),
403      0x20 | 0xE0 => TokenDecode::AltEntity(Self::from_usize(t.0 & !0x20)),
404      0x40 | 0x50 | 0x60 | 0x70 | 0x80 => TokenDecode::FixedToken(t),
405      _other => {
406        warn!("EntityId::from_token tried to decode 0x{:x?}", t.0);
407        TokenDecode::FixedToken(t)
408      }
409    }
410  }
411
412  pub fn kind(self) -> EntityKind {
413    self.entity_kind
414  }
415
416  pub fn set_kind(&mut self, entity_kind: EntityKind) {
417    self.entity_kind = entity_kind;
418  }
419
420  pub fn to_slice(self) -> [u8; 4] {
421    let mut slice = [0; 4];
422    slice[0] = self.entity_key[0];
423    slice[1] = self.entity_key[1];
424    slice[2] = self.entity_key[2];
425    slice[3] = self.entity_kind.0;
426
427    slice
428  }
429
430  pub fn from_slice(bytes: [u8; 4]) -> Self {
431    Self {
432      entity_key: [bytes[0], bytes[1], bytes[2]],
433      entity_kind: EntityKind::from(bytes[3]),
434    }
435  }
436}
437
438impl Default for EntityId {
439  fn default() -> Self {
440    Self::UNKNOWN
441  }
442}
443
444impl fmt::Debug for EntityId {
445  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
446    match *self {
447      Self::UNKNOWN => f.write_str("EntityId::UNKNOWN"),
448      Self::PARTICIPANT => f.write_str("EntityId::PARTICIPANT"),
449      Self::SEDP_BUILTIN_TOPIC_WRITER => f.write_str("EntityId::SEDP_BUILTIN_TOPIC_WRITER"),
450      Self::SEDP_BUILTIN_TOPIC_READER => f.write_str("EntityId::SEDP_BUILTIN_TOPIC_READER"),
451      Self::SEDP_BUILTIN_PUBLICATIONS_WRITER => {
452        f.write_str("EntityId::SEDP_BUILTIN_PUBLICATIONS_WRITER")
453      }
454      Self::SEDP_BUILTIN_PUBLICATIONS_READER => {
455        f.write_str("EntityId::SEDP_BUILTIN_PUBLICATIONS_READER")
456      }
457      Self::SEDP_BUILTIN_SUBSCRIPTIONS_WRITER => {
458        f.write_str("EntityId::SEDP_BUILTIN_SUBSCRIPTIONS_WRITER")
459      }
460      Self::SEDP_BUILTIN_SUBSCRIPTIONS_READER => {
461        f.write_str("EntityId::SEDP_BUILTIN_SUBSCRIPTIONS_READER")
462      }
463      Self::SPDP_BUILTIN_PARTICIPANT_WRITER => {
464        f.write_str("EntityId::SPDP_BUILTIN_PARTICIPANT_WRITER")
465      }
466      Self::SPDP_BUILTIN_PARTICIPANT_READER => {
467        f.write_str("EntityId::SPDP_BUILTIN_PARTICIPANT_READER")
468      }
469      Self::P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER => {
470        f.write_str("EntityId::P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER")
471      }
472      Self::P2P_BUILTIN_PARTICIPANT_MESSAGE_READER => {
473        f.write_str("EntityId::P2P_BUILTIN_PARTICIPANT_MESSAGE_READER")
474      }
475      // TODO: This list is missing multiple entries.
476      // Can can we somehow autogenerate this?
477      _ => {
478        f.write_str("EntityId {")?;
479        self.entity_key.fmt(f)?;
480        f.write_str(" ")?;
481        self.entity_kind.fmt(f)?;
482        f.write_str("}")
483      }
484    }
485  }
486}
487
488impl<'a, C: Context> Readable<'a, C> for EntityId {
489  #[inline]
490  fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
491    let entity_key = [reader.read_u8()?, reader.read_u8()?, reader.read_u8()?];
492    let entity_kind = EntityKind(reader.read_u8()?);
493    Ok(Self {
494      entity_key,
495      entity_kind,
496    })
497  }
498}
499
500impl<C: Context> Writable<C> for EntityId {
501  #[inline]
502  fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
503    for elem in &self.entity_key {
504      writer.write_u8(*elem)?;
505    }
506    writer.write_u8(self.entity_kind.0)
507  }
508}
509
510/// DDS/RTPS GUID
511///
512/// Spec 2.5, Section 8.2.4.1 Identifying RTPS entities: the GUID
513///
514/// The GUID (Globally Unique Identifier) is an attribute of all RTPS Entities
515/// and uniquely identifies the Entity within a DDS Domain.
516///
517/// The GUID is built as a tuple <prefix, entityId> combining a GuidPrefix_t
518/// prefix and an EntityId_t entityId
519/// ...
520/// The implementation is free to choose the prefix, as long as every
521/// Participant in the Domain has a unique GUID.
522/// ...
523/// The GUIDs of all the Endpoints within a Participant have the same prefix.
524
525#[derive(
526  Copy,
527  Clone,
528  Default,
529  PartialOrd,
530  PartialEq,
531  Ord,
532  Eq,
533  Readable,
534  Writable,
535  Hash,
536  Serialize,
537  Deserialize,
538  CdrEncodingSize,
539)]
540pub struct GUID {
541  // Note: It is important to have guid_prefix first, so that derive'd Ord trait
542  // will produce ordering, where GUIDs with same GuidPrefix are grouped
543  // together.
544  pub prefix: GuidPrefix,
545  pub entity_id: EntityId,
546}
547
548impl GUID {
549  pub const GUID_UNKNOWN: Self = Self {
550    prefix: GuidPrefix::UNKNOWN,
551    entity_id: EntityId::UNKNOWN,
552  };
553
554  /// basic constructor from components
555  pub fn new(prefix: GuidPrefix, entity_id: EntityId) -> Self {
556    Self::new_with_prefix_and_id(prefix, entity_id)
557  }
558
559  pub fn from_bytes(bytes: [u8; 16]) -> Self {
560    let mut prefix = GuidPrefix { bytes: [0; 12] };
561    prefix.bytes.as_mut_slice().copy_from_slice(&bytes[0..12]);
562
563    let mut eid_bytes = [0; 4];
564    eid_bytes.as_mut_slice().copy_from_slice(&bytes[12..16]);
565
566    Self {
567      prefix,
568      entity_id: EntityId::from_slice(eid_bytes),
569    }
570  }
571
572  /// Generates new GUID for Participant when `guid_prefix` is random
573  pub fn new_participant_guid() -> Self {
574    Self {
575      prefix: GuidPrefix::random_for_this_participant(),
576      entity_id: EntityId::PARTICIPANT,
577    }
578  }
579
580  pub fn dummy_test_guid(entity_kind: EntityKind) -> Self {
581    Self {
582      prefix: GuidPrefix::new(b"FakeTestGUID"),
583      entity_id: EntityId {
584        entity_key: [1, 2, 3],
585        entity_kind,
586      },
587    }
588  }
589
590  /// Generates GUID for specific entity_id from current prefix
591  #[must_use]
592  pub fn from_prefix(self, entity_id: EntityId) -> Self {
593    Self {
594      prefix: self.prefix,
595      entity_id,
596    }
597  }
598
599  /// alias for basic constructor from components
600  pub fn new_with_prefix_and_id(prefix: GuidPrefix, entity_id: EntityId) -> Self {
601    Self { prefix, entity_id }
602  }
603
604  pub fn as_usize(&self) -> usize {
605    self.entity_id.as_usize()
606  }
607
608  pub fn to_bytes(&self) -> [u8; 16] {
609    let mut bytes = [0; 16];
610    bytes.as_mut_slice()[0..12].copy_from_slice(self.prefix.as_ref());
611    bytes.as_mut_slice()[12..16].copy_from_slice(&self.entity_id.to_slice());
612    bytes
613  }
614}
615
616impl Key for GUID {}
617
618impl fmt::Debug for GUID {
619  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
620    f.write_fmt(format_args!(
621      "GUID {{{:?} {:?}}}",
622      self.prefix, self.entity_id
623    ))
624  }
625}
626
627#[cfg(test)]
628mod tests {
629  use speedy::Endianness;
630  use log::info;
631  use byteorder::BigEndian;
632
633  use super::*;
634
635  #[test]
636  fn serde_test() {
637    use crate::serialization::{from_bytes, to_vec};
638
639    let test_bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
640    let test_guid = GUID::from_bytes(test_bytes);
641    let ser = to_vec::<GUID, BigEndian>(&test_guid).unwrap();
642    assert_eq!(test_bytes.to_vec(), ser);
643
644    let (and_back, _byte_count) = from_bytes::<GUID, BigEndian>(&ser).unwrap();
645    assert_eq!(test_guid, and_back);
646  }
647
648  // #[test]
649  // fn serde_pl_cdr_test() {
650  //   use crate::{
651  //     serialization::{pl_cdr_deserializer::PlCdrDeserializer,
652  // cdr_serializer::to_vec},   };
653
654  //   let test_bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
655  //   let test_guid = GUID::from_bytes(test_bytes);
656  //   let ser = to_vec::<GUID, BigEndian>(&test_guid).unwrap();
657  //   assert_eq!(test_bytes.to_vec(), ser);
658
659  //   let and_back =
660  // PlCdrDeserializer::from_big_endian_bytes::<GUID>(&ser).unwrap();
661  //   assert_eq!(test_guid, and_back);
662  // }
663
664  #[test]
665  fn keyhash_test() {
666    let test_bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
667    let test_guid = GUID::from_bytes(test_bytes);
668    let key_hash = test_guid.hash_key(false); // from trait Key
669    assert_eq!(key_hash.to_vec(), test_bytes.to_vec());
670  }
671
672  #[test]
673  fn convert_entity_id_to_token_and_back() {
674    let e = EntityId::SPDP_BUILTIN_PARTICIPANT_WRITER;
675    let _t = Token(e.as_usize());
676    info!("{:?}", e.as_usize());
677    let entity = EntityId::from_usize(e.as_usize());
678    assert_eq!(e, entity);
679
680    let e2 = EntityId::P2P_BUILTIN_PARTICIPANT_MESSAGE_READER;
681    let entity2 = EntityId::from_usize(e2.as_usize());
682    assert_eq!(e2, entity2);
683
684    let e3 = EntityId::SEDP_BUILTIN_TOPIC_WRITER;
685    let entity3 = EntityId::from_usize(e3.as_usize());
686    assert_eq!(e3, entity3);
687
688    let e4 = EntityId::SEDP_BUILTIN_TOPIC_WRITER;
689    let entity4 = EntityId::from_usize(e4.as_usize());
690    assert_eq!(e4, entity4);
691
692    let e5 = EntityId::UNKNOWN;
693    let entity5 = EntityId::from_usize(e5.as_usize());
694    assert_eq!(e5, entity5);
695
696    let e6 = EntityId::create_custom_entity_id([12u8, 255u8, 0u8], EntityKind(254u8));
697    let entity6 = EntityId::from_usize(e6.as_usize());
698    assert_eq!(e6, entity6);
699  }
700
701  #[test]
702  fn minimum_bytes_needed() {
703    assert_eq!(
704      12,
705      <GuidPrefix as Readable<Endianness>>::minimum_bytes_needed()
706    );
707  }
708
709  serialization_test!( type = GuidPrefix,
710  {
711      guid_prefix_unknown,
712      GuidPrefix::UNKNOWN,
713      le = [0x00; 12],
714      be = [0x00; 12]
715  },
716  {
717      guid_prefix_default,
718      GuidPrefix::default(),
719      le = [0x00; 12],
720      be = [0x00; 12]
721  },
722  {
723      guid_prefix_endianness_insensitive,
724      GuidPrefix {
725          bytes: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
726                      0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB]
727      },
728      le = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
729            0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB],
730      be = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
731            0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB]
732  });
733
734  serialization_test!( type = EntityId,
735    {
736        entity_unknown,
737        EntityId::UNKNOWN,
738        le = [0x00, 0x00, 0x00, 0x00],
739        be = [0x00, 0x00, 0x00, 0x00]
740    },
741    {
742        entity_default,
743        EntityId::default(),
744        le = [0x00, 0x00, 0x00, 0x00],
745        be = [0x00, 0x00, 0x00, 0x00]
746    },
747    {
748        entity_participant,
749        EntityId::PARTICIPANT,
750        le = [0x00, 0x00, 0x01, 0xC1],
751        be = [0x00, 0x00, 0x01, 0xC1]
752    },
753    {
754        entity_sedp_builtin_topic_writer,
755        EntityId::SEDP_BUILTIN_TOPIC_WRITER,
756        le = [0x00, 0x00, 0x02, 0xC2],
757        be = [0x00, 0x00, 0x02, 0xC2]
758    },
759    {
760        entity_sedp_builtin_topic_reader,
761        EntityId::SEDP_BUILTIN_TOPIC_READER,
762        le = [0x00, 0x00, 0x02, 0xC7],
763        be = [0x00, 0x00, 0x02, 0xC7]
764    },
765    {
766        entity_sedp_builtin_publications_writer,
767        EntityId::SEDP_BUILTIN_PUBLICATIONS_WRITER,
768        le = [0x00, 0x00, 0x03, 0xC2],
769        be = [0x00, 0x00, 0x03, 0xC2]
770    },
771    {
772        entity_sedp_builtin_publications_reader,
773        EntityId::SEDP_BUILTIN_PUBLICATIONS_READER,
774        le = [0x00, 0x00, 0x03, 0xC7],
775        be = [0x00, 0x00, 0x03, 0xC7]
776    },
777    {
778        entity_sedp_builtin_subscriptions_writer,
779        EntityId::SEDP_BUILTIN_SUBSCRIPTIONS_WRITER,
780        le = [0x00, 0x00, 0x04, 0xC2],
781        be = [0x00, 0x00, 0x04, 0xC2]
782    },
783    {
784        entity_sedp_builtin_subscriptions_reader,
785        EntityId::SEDP_BUILTIN_SUBSCRIPTIONS_READER,
786        le = [0x00, 0x00, 0x04, 0xC7],
787        be = [0x00, 0x00, 0x04, 0xC7]
788    },
789    {
790        entity_spdp_builtin_participant_writer,
791        EntityId::SPDP_BUILTIN_PARTICIPANT_WRITER,
792        le = [0x00, 0x01, 0x00, 0xC2],
793        be = [0x00, 0x01, 0x00, 0xC2]
794    },
795    {
796        entity_spdp_builtin_participant_reader,
797        EntityId::SPDP_BUILTIN_PARTICIPANT_READER,
798        le = [0x00, 0x01, 0x00, 0xC7],
799        be = [0x00, 0x01, 0x00, 0xC7]
800    },
801    {
802        entity_p2p_builtin_participant_message_writer,
803        EntityId::P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER,
804        le = [0x00, 0x02, 0x00, 0xC2],
805        be = [0x00, 0x02, 0x00, 0xC2]
806    },
807    {
808        entity_p2p_builtin_participant_message_reader,
809        EntityId::P2P_BUILTIN_PARTICIPANT_MESSAGE_READER,
810        le = [0x00, 0x02, 0x00, 0xC7],
811        be = [0x00, 0x02, 0x00, 0xC7]
812    }
813  );
814
815  #[test]
816  fn guid_unknown_is_a_combination_of_unknown_members() {
817    assert_eq!(
818      GUID {
819        entity_id: EntityId::UNKNOWN,
820        prefix: GuidPrefix::UNKNOWN
821      },
822      GUID::GUID_UNKNOWN
823    );
824  }
825
826  serialization_test!( type = GUID,
827      {
828          guid_unknown,
829          GUID::GUID_UNKNOWN,
830          le = [0x00; 16],
831          be = [0x00; 16]
832      },
833      {
834          guid_default,
835          GUID::default(),
836          le = [0x00; 16],
837          be = [0x00; 16]
838      },
839      {
840          guid_entity_id_on_the_last_position,
841          GUID {
842              entity_id: EntityId::PARTICIPANT,
843              ..GUID::default()
844          },
845          le = [0x00, 0x00, 0x00, 0x00,
846                0x00, 0x00, 0x00, 0x00,
847                0x00, 0x00, 0x00, 0x00,
848                0x00, 0x00, 0x01, 0xC1],
849          be = [0x00, 0x00, 0x00, 0x00,
850                0x00, 0x00, 0x00, 0x00,
851                0x00, 0x00, 0x00, 0x00,
852                0x00, 0x00, 0x01, 0xC1]
853      }
854  );
855}