1pub mod declare;
15pub mod interest;
16pub mod oam;
17pub mod push;
18pub mod request;
19pub mod response;
20
21use core::fmt;
22
23pub use declare::{
24 Declare, DeclareBody, DeclareFinal, DeclareKeyExpr, DeclareQueryable, DeclareSubscriber,
25 DeclareToken, UndeclareKeyExpr, UndeclareQueryable, UndeclareSubscriber, UndeclareToken,
26};
27pub use interest::Interest;
28pub use oam::Oam;
29pub use push::Push;
30pub use request::{AtomicRequestId, Request, RequestId};
31pub use response::{Response, ResponseFinal};
32
33use crate::core::{CongestionControl, Priority, Reliability, WireExpr};
34#[cfg(feature = "shared-memory")]
35use crate::zenoh::{PushBody, RequestBody, ResponseBody};
36
37pub mod id {
38 pub const OAM: u8 = 0x1f;
41 pub const DECLARE: u8 = 0x1e;
42 pub const PUSH: u8 = 0x1d;
43 pub const REQUEST: u8 = 0x1c;
44 pub const RESPONSE: u8 = 0x1b;
45 pub const RESPONSE_FINAL: u8 = 0x1a;
46 pub const INTEREST: u8 = 0x19;
47}
48
49#[repr(u8)]
50#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
51pub enum Mapping {
52 #[default]
53 Receiver = 0,
54 Sender = 1,
55}
56
57impl Mapping {
58 pub const DEFAULT: Self = Self::Receiver;
59
60 #[cfg(feature = "test")]
61 #[doc(hidden)]
62 pub fn rand() -> Self {
63 use rand::Rng;
64
65 let mut rng = rand::thread_rng();
66 if rng.gen_bool(0.5) {
67 Mapping::Sender
68 } else {
69 Mapping::Receiver
70 }
71 }
72}
73
74#[derive(Debug, Clone, PartialEq, Eq)]
76pub enum NetworkBody {
77 Push(Push),
78 Request(Request),
79 Response(Response),
80 ResponseFinal(ResponseFinal),
81 Interest(Interest),
82 Declare(Declare),
83 OAM(Oam),
84}
85
86#[derive(Debug, Copy, Clone, PartialEq, Eq)]
87pub enum NetworkBodyRef<'a> {
88 Push(&'a Push),
89 Request(&'a Request),
90 Response(&'a Response),
91 ResponseFinal(&'a ResponseFinal),
92 Interest(&'a Interest),
93 Declare(&'a Declare),
94 OAM(&'a Oam),
95}
96
97#[derive(Debug, PartialEq, Eq)]
98pub enum NetworkBodyMut<'a> {
99 Push(&'a mut Push),
100 Request(&'a mut Request),
101 Response(&'a mut Response),
102 ResponseFinal(&'a mut ResponseFinal),
103 Interest(&'a mut Interest),
104 Declare(&'a mut Declare),
105 OAM(&'a mut Oam),
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
109pub struct NetworkMessage {
110 pub body: NetworkBody,
111 pub reliability: Reliability,
112}
113
114#[derive(Debug, Copy, Clone, PartialEq, Eq)]
115pub struct NetworkMessageRef<'a> {
116 pub body: NetworkBodyRef<'a>,
117 pub reliability: Reliability,
118}
119
120#[derive(Debug, PartialEq, Eq)]
121pub struct NetworkMessageMut<'a> {
122 pub body: NetworkBodyMut<'a>,
123 pub reliability: Reliability,
124}
125
126pub trait NetworkMessageExt {
127 #[doc(hidden)]
128 fn body(&self) -> NetworkBodyRef<'_>;
129
130 #[doc(hidden)]
131 fn reliability(&self) -> Reliability;
132
133 #[inline]
134 fn is_reliable(&self) -> bool {
135 self.reliability() == Reliability::Reliable
136 }
137
138 #[inline]
139 fn is_express(&self) -> bool {
140 match self.body() {
141 NetworkBodyRef::Push(msg) => msg.ext_qos.is_express(),
142 NetworkBodyRef::Request(msg) => msg.ext_qos.is_express(),
143 NetworkBodyRef::Response(msg) => msg.ext_qos.is_express(),
144 NetworkBodyRef::ResponseFinal(msg) => msg.ext_qos.is_express(),
145 NetworkBodyRef::Interest(msg) => msg.ext_qos.is_express(),
146 NetworkBodyRef::Declare(msg) => msg.ext_qos.is_express(),
147 NetworkBodyRef::OAM(msg) => msg.ext_qos.is_express(),
148 }
149 }
150
151 #[inline]
152 fn congestion_control(&self) -> CongestionControl {
153 match self.body() {
154 NetworkBodyRef::Push(msg) => msg.ext_qos.get_congestion_control(),
155 NetworkBodyRef::Request(msg) => msg.ext_qos.get_congestion_control(),
156 NetworkBodyRef::Response(msg) => msg.ext_qos.get_congestion_control(),
157 NetworkBodyRef::ResponseFinal(msg) => msg.ext_qos.get_congestion_control(),
158 NetworkBodyRef::Interest(msg) => msg.ext_qos.get_congestion_control(),
159 NetworkBodyRef::Declare(msg) => msg.ext_qos.get_congestion_control(),
160 NetworkBodyRef::OAM(msg) => msg.ext_qos.get_congestion_control(),
161 }
162 }
163
164 #[inline]
165 #[cfg(feature = "shared-memory")]
166 fn is_shm(&self) -> bool {
167 match self.body() {
168 NetworkBodyRef::Push(Push { payload, .. }) => match payload {
169 PushBody::Put(p) => p.ext_shm.is_some(),
170 PushBody::Del(_) => false,
171 },
172 NetworkBodyRef::Request(Request { payload, .. }) => match payload {
173 RequestBody::Query(b) => b.ext_body.as_ref().is_some_and(|b| b.ext_shm.is_some()),
174 },
175 NetworkBodyRef::Response(Response { payload, .. }) => match payload {
176 ResponseBody::Reply(b) => match &b.payload {
177 PushBody::Put(p) => p.ext_shm.is_some(),
178 PushBody::Del(_) => false,
179 },
180 ResponseBody::Err(e) => e.ext_shm.is_some(),
181 },
182 NetworkBodyRef::ResponseFinal(_)
183 | NetworkBodyRef::Interest(_)
184 | NetworkBodyRef::Declare(_)
185 | NetworkBodyRef::OAM(_) => false,
186 }
187 }
188
189 #[inline]
190 fn is_droppable(&self) -> bool {
191 !self.is_reliable() || self.congestion_control() == CongestionControl::Drop
192 }
193
194 #[inline]
195 fn priority(&self) -> Priority {
196 match self.body() {
197 NetworkBodyRef::Push(msg) => msg.ext_qos.get_priority(),
198 NetworkBodyRef::Request(msg) => msg.ext_qos.get_priority(),
199 NetworkBodyRef::Response(msg) => msg.ext_qos.get_priority(),
200 NetworkBodyRef::ResponseFinal(msg) => msg.ext_qos.get_priority(),
201 NetworkBodyRef::Interest(msg) => msg.ext_qos.get_priority(),
202 NetworkBodyRef::Declare(msg) => msg.ext_qos.get_priority(),
203 NetworkBodyRef::OAM(msg) => msg.ext_qos.get_priority(),
204 }
205 }
206
207 #[inline]
208 fn wire_expr(&self) -> Option<&WireExpr<'_>> {
209 match &self.body() {
210 NetworkBodyRef::Push(m) => Some(&m.wire_expr),
211 NetworkBodyRef::Request(m) => Some(&m.wire_expr),
212 NetworkBodyRef::Response(m) => Some(&m.wire_expr),
213 NetworkBodyRef::ResponseFinal(_) => None,
214 NetworkBodyRef::Interest(m) => m.wire_expr.as_ref(),
215 NetworkBodyRef::Declare(m) => match &m.body {
216 DeclareBody::DeclareKeyExpr(m) => Some(&m.wire_expr),
217 DeclareBody::UndeclareKeyExpr(_) => None,
218 DeclareBody::DeclareSubscriber(m) => Some(&m.wire_expr),
219 DeclareBody::UndeclareSubscriber(m) => Some(&m.ext_wire_expr.wire_expr),
220 DeclareBody::DeclareQueryable(m) => Some(&m.wire_expr),
221 DeclareBody::UndeclareQueryable(m) => Some(&m.ext_wire_expr.wire_expr),
222 DeclareBody::DeclareToken(m) => Some(&m.wire_expr),
223 DeclareBody::UndeclareToken(m) => Some(&m.ext_wire_expr.wire_expr),
224 DeclareBody::DeclareFinal(_) => None,
225 },
226 NetworkBodyRef::OAM(_) => None,
227 }
228 }
229
230 #[inline]
231 fn payload_size(&self) -> Option<usize> {
232 match &self.body() {
233 NetworkBodyRef::Push(p) => Some(p.payload_size()),
234 NetworkBodyRef::Request(r) => Some(r.payload_size()),
235 NetworkBodyRef::Response(r) => Some(r.payload_size()),
236 NetworkBodyRef::ResponseFinal(_)
237 | NetworkBodyRef::Interest(_)
238 | NetworkBodyRef::Declare(_)
239 | NetworkBodyRef::OAM(_) => None,
240 }
241 }
242
243 #[inline]
244 fn as_ref(&self) -> NetworkMessageRef<'_> {
245 NetworkMessageRef {
246 body: self.body(),
247 reliability: self.reliability(),
248 }
249 }
250
251 #[inline]
252 fn to_owned(&self) -> NetworkMessage {
253 NetworkMessage {
254 body: match self.body() {
255 NetworkBodyRef::Push(msg) => NetworkBody::Push(msg.clone()),
256 NetworkBodyRef::Request(msg) => NetworkBody::Request(msg.clone()),
257 NetworkBodyRef::Response(msg) => NetworkBody::Response(msg.clone()),
258 NetworkBodyRef::ResponseFinal(msg) => NetworkBody::ResponseFinal(msg.clone()),
259 NetworkBodyRef::Interest(msg) => NetworkBody::Interest(msg.clone()),
260 NetworkBodyRef::Declare(msg) => NetworkBody::Declare(msg.clone()),
261 NetworkBodyRef::OAM(msg) => NetworkBody::OAM(msg.clone()),
262 },
263 reliability: self.reliability(),
264 }
265 }
266}
267
268impl<M: NetworkMessageExt> NetworkMessageExt for &M {
269 fn body(&self) -> NetworkBodyRef<'_> {
270 (**self).body()
271 }
272
273 fn reliability(&self) -> Reliability {
274 (**self).reliability()
275 }
276}
277
278impl<M: NetworkMessageExt> NetworkMessageExt for &mut M {
279 fn body(&self) -> NetworkBodyRef<'_> {
280 (**self).body()
281 }
282
283 fn reliability(&self) -> Reliability {
284 (**self).reliability()
285 }
286}
287
288impl NetworkMessageExt for NetworkMessage {
289 fn body(&self) -> NetworkBodyRef<'_> {
290 match &self.body {
291 NetworkBody::Push(body) => NetworkBodyRef::Push(body),
292 NetworkBody::Request(body) => NetworkBodyRef::Request(body),
293 NetworkBody::Response(body) => NetworkBodyRef::Response(body),
294 NetworkBody::ResponseFinal(body) => NetworkBodyRef::ResponseFinal(body),
295 NetworkBody::Interest(body) => NetworkBodyRef::Interest(body),
296 NetworkBody::Declare(body) => NetworkBodyRef::Declare(body),
297 NetworkBody::OAM(body) => NetworkBodyRef::OAM(body),
298 }
299 }
300
301 fn reliability(&self) -> Reliability {
302 self.reliability
303 }
304}
305
306impl NetworkMessageExt for NetworkMessageRef<'_> {
307 fn body(&self) -> NetworkBodyRef<'_> {
308 self.body
309 }
310
311 fn reliability(&self) -> Reliability {
312 self.reliability
313 }
314}
315
316impl NetworkMessageExt for NetworkMessageMut<'_> {
317 fn body(&self) -> NetworkBodyRef<'_> {
318 match &self.body {
319 NetworkBodyMut::Push(body) => NetworkBodyRef::Push(body),
320 NetworkBodyMut::Request(body) => NetworkBodyRef::Request(body),
321 NetworkBodyMut::Response(body) => NetworkBodyRef::Response(body),
322 NetworkBodyMut::ResponseFinal(body) => NetworkBodyRef::ResponseFinal(body),
323 NetworkBodyMut::Interest(body) => NetworkBodyRef::Interest(body),
324 NetworkBodyMut::Declare(body) => NetworkBodyRef::Declare(body),
325 NetworkBodyMut::OAM(body) => NetworkBodyRef::OAM(body),
326 }
327 }
328
329 fn reliability(&self) -> Reliability {
330 self.reliability
331 }
332}
333
334impl NetworkMessage {
335 #[cfg(feature = "test")]
336 #[doc(hidden)]
337 pub fn rand() -> Self {
338 use rand::Rng;
339
340 let mut rng = rand::thread_rng();
341
342 let body = match rng.gen_range(0..6) {
343 0 => NetworkBody::Push(Push::rand()),
344 1 => NetworkBody::Request(Request::rand()),
345 2 => NetworkBody::Response(Response::rand()),
346 3 => NetworkBody::ResponseFinal(ResponseFinal::rand()),
347 4 => NetworkBody::Declare(Declare::rand()),
348 5 => NetworkBody::OAM(Oam::rand()),
349 _ => unreachable!(),
350 };
351
352 body.into()
353 }
354
355 #[inline]
356 pub fn as_mut(&mut self) -> NetworkMessageMut<'_> {
357 let body = match &mut self.body {
358 NetworkBody::Push(body) => NetworkBodyMut::Push(body),
359 NetworkBody::Request(body) => NetworkBodyMut::Request(body),
360 NetworkBody::Response(body) => NetworkBodyMut::Response(body),
361 NetworkBody::ResponseFinal(body) => NetworkBodyMut::ResponseFinal(body),
362 NetworkBody::Interest(body) => NetworkBodyMut::Interest(body),
363 NetworkBody::Declare(body) => NetworkBodyMut::Declare(body),
364 NetworkBody::OAM(body) => NetworkBodyMut::OAM(body),
365 };
366 NetworkMessageMut {
367 body,
368 reliability: self.reliability,
369 }
370 }
371}
372
373impl NetworkMessageMut<'_> {
374 #[inline]
375 pub fn as_mut(&mut self) -> NetworkMessageMut<'_> {
376 let body = match &mut self.body {
377 NetworkBodyMut::Push(body) => NetworkBodyMut::Push(body),
378 NetworkBodyMut::Request(body) => NetworkBodyMut::Request(body),
379 NetworkBodyMut::Response(body) => NetworkBodyMut::Response(body),
380 NetworkBodyMut::ResponseFinal(body) => NetworkBodyMut::ResponseFinal(body),
381 NetworkBodyMut::Interest(body) => NetworkBodyMut::Interest(body),
382 NetworkBodyMut::Declare(body) => NetworkBodyMut::Declare(body),
383 NetworkBodyMut::OAM(body) => NetworkBodyMut::OAM(body),
384 };
385 NetworkMessageMut {
386 body,
387 reliability: self.reliability,
388 }
389 }
390}
391
392impl fmt::Display for NetworkMessageRef<'_> {
393 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
394 match &self.body {
395 NetworkBodyRef::OAM(_) => write!(f, "OAM"),
396 NetworkBodyRef::Push(_) => write!(f, "Push"),
397 NetworkBodyRef::Request(_) => write!(f, "Request"),
398 NetworkBodyRef::Response(_) => write!(f, "Response"),
399 NetworkBodyRef::ResponseFinal(_) => write!(f, "ResponseFinal"),
400 NetworkBodyRef::Interest(_) => write!(f, "Interest"),
401 NetworkBodyRef::Declare(_) => write!(f, "Declare"),
402 }
403 }
404}
405
406impl fmt::Display for NetworkMessage {
407 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
408 self.as_ref().fmt(f)
409 }
410}
411
412impl fmt::Display for NetworkMessageMut<'_> {
413 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
414 self.as_ref().fmt(f)
415 }
416}
417
418impl From<NetworkBody> for NetworkMessage {
419 #[inline]
420 fn from(body: NetworkBody) -> Self {
421 Self {
422 body,
423 reliability: Reliability::DEFAULT,
424 }
425 }
426}
427
428#[cfg(feature = "test")]
429impl From<Push> for NetworkMessage {
430 fn from(push: Push) -> Self {
431 NetworkBody::Push(push).into()
432 }
433}
434
435pub mod ext {
437 use core::fmt;
438
439 use crate::{
440 common::{imsg, ZExtZ64},
441 core::{CongestionControl, EntityId, Priority, ZenohIdProto},
442 };
443
444 #[repr(transparent)]
459 #[derive(Clone, Copy, PartialEq, Eq)]
460 pub struct QoSType<const ID: u8> {
461 inner: u8,
462 }
463
464 impl<const ID: u8> QoSType<{ ID }> {
465 const P_MASK: u8 = 0b00000111;
466 const D_FLAG: u8 = 0b00001000;
467 const E_FLAG: u8 = 0b00010000;
468 const F_FLAG: u8 = 0b00100000;
469
470 pub const DEFAULT: Self = Self::new(Priority::DEFAULT, CongestionControl::DEFAULT, false);
471
472 pub const DECLARE: Self =
473 Self::new(Priority::Control, CongestionControl::DEFAULT_DECLARE, false);
474 pub const PUSH: Self = Self::new(Priority::DEFAULT, CongestionControl::DEFAULT_PUSH, false);
475 pub const REQUEST: Self =
476 Self::new(Priority::DEFAULT, CongestionControl::DEFAULT_REQUEST, false);
477 pub const RESPONSE: Self = Self::new(
478 Priority::DEFAULT,
479 CongestionControl::DEFAULT_RESPONSE,
480 false,
481 );
482 pub const RESPONSE_FINAL: Self = Self::new(
483 Priority::DEFAULT,
484 CongestionControl::DEFAULT_RESPONSE,
485 false,
486 );
487 pub const OAM: Self = Self::new(Priority::Control, CongestionControl::DEFAULT_OAM, false);
488
489 pub const fn new(
490 priority: Priority,
491 congestion_control: CongestionControl,
492 is_express: bool,
493 ) -> Self {
494 let mut inner = priority as u8;
495 match congestion_control {
496 CongestionControl::Block => inner |= Self::D_FLAG,
497 #[cfg(feature = "unstable")]
498 CongestionControl::BlockFirst => inner |= Self::F_FLAG,
499 _ => {}
500 }
501 if is_express {
502 inner |= Self::E_FLAG;
503 }
504 Self { inner }
505 }
506
507 pub fn set_priority(&mut self, priority: Priority) {
508 self.inner = imsg::set_bitfield(self.inner, priority as u8, Self::P_MASK);
509 }
510
511 pub const fn get_priority(&self) -> Priority {
512 unsafe { core::mem::transmute(self.inner & Self::P_MASK) }
513 }
514
515 pub fn set_congestion_control(&mut self, cctrl: CongestionControl) {
516 match cctrl {
517 CongestionControl::Block => {
518 self.inner = imsg::set_flag(self.inner, Self::D_FLAG);
519 self.inner = imsg::unset_flag(self.inner, Self::F_FLAG);
520 }
521 CongestionControl::Drop => {
522 self.inner = imsg::unset_flag(self.inner, Self::D_FLAG);
523 self.inner = imsg::unset_flag(self.inner, Self::F_FLAG);
524 }
525 #[cfg(feature = "unstable")]
526 CongestionControl::BlockFirst => {
527 self.inner = imsg::unset_flag(self.inner, Self::D_FLAG);
528 self.inner = imsg::set_flag(self.inner, Self::F_FLAG);
529 }
530 }
531 }
532
533 pub const fn get_congestion_control(&self) -> CongestionControl {
534 match (
535 imsg::has_flag(self.inner, Self::D_FLAG),
536 imsg::has_flag(self.inner, Self::F_FLAG),
537 ) {
538 (false, false) => CongestionControl::Drop,
539 #[cfg(feature = "unstable")]
540 (false, true) => CongestionControl::BlockFirst,
541 #[cfg(not(feature = "unstable"))]
542 (false, true) => CongestionControl::Drop,
543 (true, _) => CongestionControl::Block,
544 }
545 }
546
547 pub fn set_is_express(&mut self, is_express: bool) {
548 match is_express {
549 true => self.inner = imsg::set_flag(self.inner, Self::E_FLAG),
550 false => self.inner = imsg::unset_flag(self.inner, Self::E_FLAG),
551 }
552 }
553
554 pub const fn is_express(&self) -> bool {
555 imsg::has_flag(self.inner, Self::E_FLAG)
556 }
557
558 #[cfg(feature = "test")]
559 #[doc(hidden)]
560 pub fn rand() -> Self {
561 use rand::Rng;
562 let mut rng = rand::thread_rng();
563
564 let inner: u8 = rng.gen();
565 Self { inner }
566 }
567 }
568
569 impl<const ID: u8> Default for QoSType<{ ID }> {
570 fn default() -> Self {
571 Self::new(Priority::DEFAULT, CongestionControl::DEFAULT, false)
572 }
573 }
574
575 impl<const ID: u8> From<ZExtZ64<{ ID }>> for QoSType<{ ID }> {
576 fn from(ext: ZExtZ64<{ ID }>) -> Self {
577 Self {
578 inner: ext.value as u8,
579 }
580 }
581 }
582
583 impl<const ID: u8> From<QoSType<{ ID }>> for ZExtZ64<{ ID }> {
584 fn from(ext: QoSType<{ ID }>) -> Self {
585 ZExtZ64::new(ext.inner as u64)
586 }
587 }
588
589 impl<const ID: u8> fmt::Debug for QoSType<{ ID }> {
590 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
591 f.debug_struct("QoS")
592 .field("priority", &self.get_priority())
593 .field("congestion", &self.get_congestion_control())
594 .field("express", &self.is_express())
595 .finish()
596 }
597 }
598
599 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
608 pub struct TimestampType<const ID: u8> {
609 pub timestamp: uhlc::Timestamp,
610 }
611
612 impl<const ID: u8> TimestampType<{ ID }> {
613 #[cfg(feature = "test")]
614 #[doc(hidden)]
615 pub fn rand() -> Self {
616 use rand::Rng;
617 let mut rng = rand::thread_rng();
618
619 let time = uhlc::NTP64(rng.gen());
620 let id = uhlc::ID::try_from(ZenohIdProto::rand().to_le_bytes()).unwrap();
621 let timestamp = uhlc::Timestamp::new(time, id);
622 Self { timestamp }
623 }
624 }
625
626 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
635 pub struct NodeIdType<const ID: u8> {
636 pub node_id: u16,
637 }
638
639 impl<const ID: u8> NodeIdType<{ ID }> {
640 pub const DEFAULT: Self = Self { node_id: 0 };
642
643 #[cfg(feature = "test")]
644 #[doc(hidden)]
645 pub fn rand() -> Self {
646 use rand::Rng;
647 let mut rng = rand::thread_rng();
648 let node_id = rng.gen();
649 Self { node_id }
650 }
651 }
652
653 impl<const ID: u8> Default for NodeIdType<{ ID }> {
654 fn default() -> Self {
655 Self::DEFAULT
656 }
657 }
658
659 impl<const ID: u8> From<ZExtZ64<{ ID }>> for NodeIdType<{ ID }> {
660 fn from(ext: ZExtZ64<{ ID }>) -> Self {
661 Self {
662 node_id: ext.value as u16,
663 }
664 }
665 }
666
667 impl<const ID: u8> From<NodeIdType<{ ID }>> for ZExtZ64<{ ID }> {
668 fn from(ext: NodeIdType<{ ID }>) -> Self {
669 ZExtZ64::new(ext.node_id as u64)
670 }
671 }
672
673 #[derive(Debug, Clone, PartialEq, Eq)]
684 pub struct EntityGlobalIdType<const ID: u8> {
685 pub zid: ZenohIdProto,
686 pub eid: EntityId,
687 }
688
689 impl<const ID: u8> EntityGlobalIdType<{ ID }> {
690 #[cfg(feature = "test")]
691 #[doc(hidden)]
692 pub fn rand() -> Self {
693 use rand::Rng;
694 let mut rng = rand::thread_rng();
695
696 let zid = ZenohIdProto::rand();
697 let eid: EntityId = rng.gen();
698 Self { zid, eid }
699 }
700 }
701}