zenoh_protocol/network/declare.rs
1//
2// Copyright (c) 2022 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12// ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use alloc::borrow::Cow;
15
16pub use common::*;
17pub use keyexpr::*;
18pub use queryable::*;
19pub use subscriber::*;
20pub use token::*;
21
22use crate::{
23 core::{ExprId, WireExpr},
24 network::Mapping,
25 zextz64, zextzbuf,
26};
27
28pub mod flag {
29 pub const I: u8 = 1 << 5; // 0x20 Interest if I==1 then the declare is in a response to an Interest with future==false
30 // pub const X: u8 = 1 << 6; // 0x40 Reserved
31 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
32}
33
34/// ```text
35/// Flags:
36/// - I: Interest If I==1 then interest_id is present
37/// - X: Reserved
38/// - Z: Extension If Z==1 then at least one extension is present
39///
40/// 7 6 5 4 3 2 1 0
41/// +-+-+-+-+-+-+-+-+
42/// |Z|X|I| DECLARE |
43/// +-+-+-+---------+
44/// ~interest_id:z32~ if I==1
45/// +---------------+
46/// ~ [decl_exts] ~ if Z==1
47/// +---------------+
48/// ~ declaration ~
49/// +---------------+
50/// ```
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct Declare {
53 pub interest_id: Option<super::interest::InterestId>,
54 pub ext_qos: ext::QoSType,
55 pub ext_tstamp: Option<ext::TimestampType>,
56 pub ext_nodeid: ext::NodeIdType,
57 pub body: DeclareBody,
58}
59
60pub mod ext {
61 use crate::{zextz64, zextzbuf};
62
63 pub type QoS = zextz64!(0x1, false);
64 pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>;
65
66 pub type Timestamp = zextzbuf!(0x2, false);
67 pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>;
68
69 pub type NodeId = zextz64!(0x3, true);
70 pub type NodeIdType = crate::network::ext::NodeIdType<{ NodeId::ID }>;
71}
72
73pub mod id {
74 pub const D_KEYEXPR: u8 = 0x00;
75 pub const U_KEYEXPR: u8 = 0x01;
76
77 pub const D_SUBSCRIBER: u8 = 0x02;
78 pub const U_SUBSCRIBER: u8 = 0x03;
79
80 pub const D_QUERYABLE: u8 = 0x04;
81 pub const U_QUERYABLE: u8 = 0x05;
82
83 pub const D_TOKEN: u8 = 0x06;
84 pub const U_TOKEN: u8 = 0x07;
85
86 pub const D_FINAL: u8 = 0x1A;
87}
88
89#[derive(Debug, Clone, PartialEq, Eq)]
90pub enum DeclareBody {
91 DeclareKeyExpr(DeclareKeyExpr),
92 UndeclareKeyExpr(UndeclareKeyExpr),
93 DeclareSubscriber(DeclareSubscriber),
94 UndeclareSubscriber(UndeclareSubscriber),
95 DeclareQueryable(DeclareQueryable),
96 UndeclareQueryable(UndeclareQueryable),
97 DeclareToken(DeclareToken),
98 UndeclareToken(UndeclareToken),
99 DeclareFinal(DeclareFinal),
100}
101
102impl DeclareBody {
103 #[cfg(feature = "test")]
104 #[doc(hidden)]
105 pub fn rand() -> Self {
106 use rand::Rng;
107
108 let mut rng = rand::thread_rng();
109
110 match rng.gen_range(0..9) {
111 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()),
112 1 => DeclareBody::UndeclareKeyExpr(UndeclareKeyExpr::rand()),
113 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()),
114 3 => DeclareBody::UndeclareSubscriber(UndeclareSubscriber::rand()),
115 4 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()),
116 5 => DeclareBody::UndeclareQueryable(UndeclareQueryable::rand()),
117 6 => DeclareBody::DeclareToken(DeclareToken::rand()),
118 7 => DeclareBody::UndeclareToken(UndeclareToken::rand()),
119 8 => DeclareBody::DeclareFinal(DeclareFinal::rand()),
120 _ => unreachable!(),
121 }
122 }
123}
124
125impl Declare {
126 #[cfg(feature = "test")]
127 #[doc(hidden)]
128 pub fn rand() -> Self {
129 use rand::Rng;
130
131 let mut rng = rand::thread_rng();
132
133 let interest_id = rng
134 .gen_bool(0.5)
135 .then_some(rng.gen::<super::interest::InterestId>());
136 let ext_qos = ext::QoSType::rand();
137 let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand);
138 let ext_nodeid = ext::NodeIdType::rand();
139 let body = DeclareBody::rand();
140
141 Self {
142 interest_id,
143 ext_qos,
144 ext_tstamp,
145 ext_nodeid,
146 body,
147 }
148 }
149}
150
151pub mod common {
152 use super::*;
153
154 /// ```text
155 /// Flags:
156 /// - X: Reserved
157 /// - X: Reserved
158 /// - Z: Extension If Z==1 then at least one extension is present
159 ///
160 /// 7 6 5 4 3 2 1 0
161 /// +-+-+-+-+-+-+-+-+
162 /// |Z|X|X| D_FINAL |
163 /// +---------------+
164 /// ~ [final_exts] ~ if Z==1
165 /// +---------------+
166 /// ```
167 #[derive(Debug, Clone, PartialEq, Eq)]
168 pub struct DeclareFinal;
169
170 impl DeclareFinal {
171 #[cfg(feature = "test")]
172 #[doc(hidden)]
173 pub fn rand() -> Self {
174 Self
175 }
176 }
177
178 pub mod ext {
179 use super::*;
180
181 /// ```text
182 /// Flags:
183 /// - N: Named If N==1 then the key expr has name/suffix
184 /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
185 ///
186 /// 7 6 5 4 3 2 1 0
187 /// +-+-+-+-+-+-+-+-+
188 /// |X|X|X|X|X|X|M|N|
189 /// +-+-+-+---------+
190 /// ~ key_scope:z16 ~
191 /// +---------------+
192 /// ~ key_suffix ~ if N==1 -- <u8;z16>
193 /// +---------------+
194 /// ```
195 pub type WireExprExt = zextzbuf!(0x0f, true);
196 #[derive(Debug, Clone, PartialEq, Eq)]
197 pub struct WireExprType {
198 pub wire_expr: WireExpr<'static>,
199 }
200
201 impl WireExprType {
202 pub fn null() -> Self {
203 Self {
204 wire_expr: WireExpr {
205 scope: ExprId::MIN,
206 suffix: Cow::from(""),
207 mapping: Mapping::Receiver,
208 },
209 }
210 }
211
212 pub fn is_null(&self) -> bool {
213 self.wire_expr.is_empty()
214 }
215
216 #[cfg(feature = "test")]
217 #[doc(hidden)]
218 pub fn rand() -> Self {
219 Self {
220 wire_expr: WireExpr::rand(),
221 }
222 }
223 }
224 }
225}
226
227pub mod keyexpr {
228 use super::*;
229
230 pub mod flag {
231 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
232 // pub const X: u8 = 1 << 6; // 0x40 Reserved
233 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
234 }
235
236 /// ```text
237 /// Flags:
238 /// - N: Named If N==1 then the key expr has name/suffix
239 /// - X: Reserved
240 /// - Z: Extension If Z==1 then at least one extension is present
241 ///
242 /// 7 6 5 4 3 2 1 0
243 /// +-+-+-+-+-+-+-+-+
244 /// |Z|X|N| D_KEXPR |
245 /// +---------------+
246 /// ~ expr_id:z16 ~
247 /// +---------------+
248 /// ~ key_scope:z16 ~
249 /// +---------------+
250 /// ~ key_suffix ~ if N==1 -- <u8;z16>
251 /// +---------------+
252 /// ~ [decl_exts] ~ if Z==1
253 /// +---------------+
254 /// ```
255 #[derive(Debug, Clone, PartialEq, Eq)]
256 pub struct DeclareKeyExpr {
257 pub id: ExprId,
258 pub wire_expr: WireExpr<'static>,
259 }
260
261 impl DeclareKeyExpr {
262 #[cfg(feature = "test")]
263 #[doc(hidden)]
264 pub fn rand() -> Self {
265 use rand::Rng;
266 let mut rng = rand::thread_rng();
267
268 let id: ExprId = rng.gen();
269 let wire_expr = WireExpr::rand();
270
271 Self { id, wire_expr }
272 }
273 }
274
275 /// ```text
276 /// Flags:
277 /// - X: Reserved
278 /// - X: Reserved
279 /// - Z: Extension If Z==1 then at least one extension is present
280 ///
281 /// 7 6 5 4 3 2 1 0
282 /// +-+-+-+-+-+-+-+-+
283 /// |Z|X|X| U_KEXPR |
284 /// +---------------+
285 /// ~ expr_id:z16 ~
286 /// +---------------+
287 /// ~ [decl_exts] ~ if Z==1
288 /// +---------------+
289 /// ```
290 #[derive(Debug, Clone, PartialEq, Eq)]
291 pub struct UndeclareKeyExpr {
292 pub id: ExprId,
293 }
294
295 impl UndeclareKeyExpr {
296 #[cfg(feature = "test")]
297 #[doc(hidden)]
298 pub fn rand() -> Self {
299 use rand::Rng;
300 let mut rng = rand::thread_rng();
301
302 let id: ExprId = rng.gen();
303
304 Self { id }
305 }
306 }
307}
308
309pub mod subscriber {
310 use super::*;
311 use crate::core::EntityId;
312
313 pub type SubscriberId = EntityId;
314
315 pub mod flag {
316 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
317 pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
318 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
319 }
320
321 /// ```text
322 /// Flags:
323 /// - N: Named If N==1 then the key expr has name/suffix
324 /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
325 /// - Z: Extension If Z==1 then at least one extension is present
326 ///
327 /// 7 6 5 4 3 2 1 0
328 /// +-+-+-+-+-+-+-+-+
329 /// |Z|M|N| D_SUB |
330 /// +---------------+
331 /// ~ subs_id:z32 ~
332 /// +---------------+
333 /// ~ key_scope:z16 ~
334 /// +---------------+
335 /// ~ key_suffix ~ if N==1 -- <u8;z16>
336 /// +---------------+
337 /// ~ [decl_exts] ~ if Z==1
338 /// +---------------+
339 ///
340 /// - if R==1 then the subscription is reliable, else it is best effort ///
341 /// ```
342 #[derive(Debug, Clone, PartialEq, Eq)]
343 pub struct DeclareSubscriber {
344 pub id: SubscriberId,
345 pub wire_expr: WireExpr<'static>,
346 }
347
348 impl DeclareSubscriber {
349 #[cfg(feature = "test")]
350 #[doc(hidden)]
351 pub fn rand() -> Self {
352 use rand::Rng;
353 let mut rng = rand::thread_rng();
354
355 let id: SubscriberId = rng.gen();
356 let wire_expr = WireExpr::rand();
357
358 Self { id, wire_expr }
359 }
360 }
361
362 /// ```text
363 /// Flags:
364 /// - X: Reserved
365 /// - X: Reserved
366 /// - Z: Extension If Z==1 then at least one extension is present
367 ///
368 /// 7 6 5 4 3 2 1 0
369 /// +-+-+-+-+-+-+-+-+
370 /// |Z|X|X| U_SUB |
371 /// +---------------+
372 /// ~ subs_id:z32 ~
373 /// +---------------+
374 /// ~ [decl_exts] ~ if Z==1
375 /// +---------------+
376 /// ```
377 #[derive(Debug, Clone, PartialEq, Eq)]
378 pub struct UndeclareSubscriber {
379 pub id: SubscriberId,
380 pub ext_wire_expr: common::ext::WireExprType,
381 }
382
383 impl UndeclareSubscriber {
384 #[cfg(feature = "test")]
385 #[doc(hidden)]
386 pub fn rand() -> Self {
387 use rand::Rng;
388 let mut rng = rand::thread_rng();
389
390 let id: SubscriberId = rng.gen();
391 let ext_wire_expr = common::ext::WireExprType::rand();
392
393 Self { id, ext_wire_expr }
394 }
395 }
396}
397
398pub mod queryable {
399 use super::*;
400 use crate::core::EntityId;
401
402 pub type QueryableId = EntityId;
403
404 pub mod flag {
405 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
406 pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
407 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
408 }
409
410 /// ```text
411 /// Flags:
412 /// - N: Named If N==1 then the key expr has name/suffix
413 /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
414 /// - Z: Extension If Z==1 then at least one extension is present
415 ///
416 /// 7 6 5 4 3 2 1 0
417 /// +-+-+-+-+-+-+-+-+
418 /// |Z|M|N| D_QBL |
419 /// +---------------+
420 /// ~ qbls_id:z32 ~
421 /// +---------------+
422 /// ~ key_scope:z16 ~
423 /// +---------------+
424 /// ~ key_suffix ~ if N==1 -- <u8;z16>
425 /// +---------------+
426 /// ~ [decl_exts] ~ if Z==1
427 /// +---------------+
428 ///
429 /// - if R==1 then the queryable is reliable, else it is best effort
430 /// - if P==1 then the queryable is pull, else it is push
431 /// - if C==1 then the queryable is complete and the N parameter is present
432 /// - if D==1 then the queryable distance is present
433 /// ```
434 #[derive(Debug, Clone, PartialEq, Eq)]
435 pub struct DeclareQueryable {
436 pub id: QueryableId,
437 pub wire_expr: WireExpr<'static>,
438 pub ext_info: ext::QueryableInfoType,
439 }
440
441 pub mod ext {
442 use super::*;
443
444 pub type QueryableInfo = zextz64!(0x01, false);
445
446 pub mod flag {
447 pub const C: u8 = 1; // 0x01 Complete if C==1 then the queryable is complete
448 }
449 ///
450 /// ```text
451 /// 7 6 5 4 3 2 1 0
452 /// +-+-+-+-+-+-+-+-+
453 /// |Z|0_1| ID |
454 /// +-+-+-+---------+
455 /// |x|x|x|x|x|x|x|C|
456 /// +---------------+
457 /// ~ distance <z16>~
458 /// +---------------+
459 /// ```
460 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
461 pub struct QueryableInfoType {
462 pub complete: bool, // Default false: incomplete
463 pub distance: u16, // Default 0: distance is null (e.g. intra-process communication)
464 }
465
466 impl QueryableInfoType {
467 pub const DEFAULT: Self = Self {
468 complete: false,
469 distance: 0,
470 };
471
472 #[cfg(feature = "test")]
473 #[doc(hidden)]
474 pub fn rand() -> Self {
475 use rand::Rng;
476 let mut rng = rand::thread_rng();
477 let complete: bool = rng.gen_bool(0.5);
478 let distance: u16 = rng.gen();
479
480 Self { complete, distance }
481 }
482 }
483
484 impl Default for QueryableInfoType {
485 fn default() -> Self {
486 Self::DEFAULT
487 }
488 }
489 }
490
491 impl DeclareQueryable {
492 #[cfg(feature = "test")]
493 #[doc(hidden)]
494 pub fn rand() -> Self {
495 use rand::Rng;
496 let mut rng = rand::thread_rng();
497
498 let id: QueryableId = rng.gen();
499 let wire_expr = WireExpr::rand();
500 let ext_info = ext::QueryableInfoType::rand();
501
502 Self {
503 id,
504 wire_expr,
505 ext_info,
506 }
507 }
508 }
509
510 /// ```text
511 /// Flags:
512 /// - X: Reserved
513 /// - X: Reserved
514 /// - Z: Extension If Z==1 then at least one extension is present
515 ///
516 /// 7 6 5 4 3 2 1 0
517 /// +-+-+-+-+-+-+-+-+
518 /// |Z|X|X| U_QBL |
519 /// +---------------+
520 /// ~ qbls_id:z32 ~
521 /// +---------------+
522 /// ~ [decl_exts] ~ if Z==1
523 /// +---------------+
524 /// ```
525 #[derive(Debug, Clone, PartialEq, Eq)]
526 pub struct UndeclareQueryable {
527 pub id: QueryableId,
528 pub ext_wire_expr: common::ext::WireExprType,
529 }
530
531 impl UndeclareQueryable {
532 #[cfg(feature = "test")]
533 #[doc(hidden)]
534 pub fn rand() -> Self {
535 use rand::Rng;
536 let mut rng = rand::thread_rng();
537
538 let id: QueryableId = rng.gen();
539 let ext_wire_expr = common::ext::WireExprType::rand();
540
541 Self { id, ext_wire_expr }
542 }
543 }
544}
545
546pub mod token {
547 use super::*;
548
549 pub type TokenId = u32;
550
551 pub mod flag {
552 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
553 pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
554 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
555 }
556
557 /// ```text
558 /// Flags:
559 /// - N: Named If N==1 then the key expr has name/suffix
560 /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver
561 /// - Z: Extension If Z==1 then at least one extension is present
562 ///
563 /// 7 6 5 4 3 2 1 0
564 /// +-+-+-+-+-+-+-+-+
565 /// |Z|M|N| D_TKN |
566 /// +---------------+
567 /// ~ token_id:z32 ~
568 /// +---------------+
569 /// ~ key_scope:z16 ~
570 /// +---------------+
571 /// ~ key_suffix ~ if N==1 -- <u8;z16>
572 /// +---------------+
573 /// ~ [decl_exts] ~ if Z==1
574 /// +---------------+
575 ///
576 /// ```
577 #[derive(Debug, Clone, PartialEq, Eq)]
578 pub struct DeclareToken {
579 pub id: TokenId,
580 pub wire_expr: WireExpr<'static>,
581 }
582
583 impl DeclareToken {
584 #[cfg(feature = "test")]
585 #[doc(hidden)]
586 pub fn rand() -> Self {
587 use rand::Rng;
588 let mut rng = rand::thread_rng();
589
590 let id: TokenId = rng.gen();
591 let wire_expr = WireExpr::rand();
592
593 Self { id, wire_expr }
594 }
595 }
596
597 /// ```text
598 /// Flags:
599 /// - X: Reserved
600 /// - X: Reserved
601 /// - Z: Extension If Z==1 then at least one extension is present
602 ///
603 /// 7 6 5 4 3 2 1 0
604 /// +-+-+-+-+-+-+-+-+
605 /// |Z|X|X| U_TKN |
606 /// +---------------+
607 /// ~ token_id:z32 ~
608 /// +---------------+
609 /// ~ [decl_exts] ~ if Z==1
610 /// +---------------+
611 /// ```
612 #[derive(Debug, Clone, PartialEq, Eq)]
613 pub struct UndeclareToken {
614 pub id: TokenId,
615 pub ext_wire_expr: common::ext::WireExprType,
616 }
617
618 impl UndeclareToken {
619 #[cfg(feature = "test")]
620 #[doc(hidden)]
621 pub fn rand() -> Self {
622 use rand::Rng;
623 let mut rng = rand::thread_rng();
624
625 let id: TokenId = rng.gen();
626 let ext_wire_expr = common::ext::WireExprType::rand();
627
628 Self { id, ext_wire_expr }
629 }
630 }
631}