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