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 pub fn rand() -> Self {
109 use rand::Rng;
110
111 let mut rng = rand::thread_rng();
112
113 match rng.gen_range(0..9) {
114 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()),
115 1 => DeclareBody::UndeclareKeyExpr(UndeclareKeyExpr::rand()),
116 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()),
117 3 => DeclareBody::UndeclareSubscriber(UndeclareSubscriber::rand()),
118 4 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()),
119 5 => DeclareBody::UndeclareQueryable(UndeclareQueryable::rand()),
120 6 => DeclareBody::DeclareToken(DeclareToken::rand()),
121 7 => DeclareBody::UndeclareToken(UndeclareToken::rand()),
122 8 => DeclareBody::DeclareFinal(DeclareFinal::rand()),
123 _ => unreachable!(),
124 }
125 }
126}
127
128impl Declare {
129 #[cfg(feature = "test")]
130 pub fn rand() -> Self {
131 use rand::Rng;
132
133 let mut rng = rand::thread_rng();
134
135 let interest_id = rng
136 .gen_bool(0.5)
137 .then_some(rng.gen::<super::interest::InterestId>());
138 let ext_qos = ext::QoSType::rand();
139 let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand);
140 let ext_nodeid = ext::NodeIdType::rand();
141 let body = DeclareBody::rand();
142
143 Self {
144 interest_id,
145 ext_qos,
146 ext_tstamp,
147 ext_nodeid,
148 body,
149 }
150 }
151}
152
153pub mod common {
154 use super::*;
155
156 /// ```text
157 /// Flags:
158 /// - X: Reserved
159 /// - X: Reserved
160 /// - Z: Extension If Z==1 then at least one extension is present
161 ///
162 /// 7 6 5 4 3 2 1 0
163 /// +-+-+-+-+-+-+-+-+
164 /// |Z|X|X| D_FINAL |
165 /// +---------------+
166 /// ~ [final_exts] ~ if Z==1
167 /// +---------------+
168 /// ```
169 #[derive(Debug, Clone, PartialEq, Eq)]
170 pub struct DeclareFinal;
171
172 impl DeclareFinal {
173 #[cfg(feature = "test")]
174 pub fn rand() -> Self {
175 Self
176 }
177 }
178
179 pub mod ext {
180 use super::*;
181
182 /// ```text
183 /// Flags:
184 /// - N: Named If N==1 then the key expr has name/suffix
185 /// - 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
186 ///
187 /// 7 6 5 4 3 2 1 0
188 /// +-+-+-+-+-+-+-+-+
189 /// |X|X|X|X|X|X|M|N|
190 /// +-+-+-+---------+
191 /// ~ key_scope:z16 ~
192 /// +---------------+
193 /// ~ key_suffix ~ if N==1 -- <u8;z16>
194 /// +---------------+
195 /// ```
196 pub type WireExprExt = zextzbuf!(0x0f, true);
197 #[derive(Debug, Clone, PartialEq, Eq)]
198 pub struct WireExprType {
199 pub wire_expr: WireExpr<'static>,
200 }
201
202 impl WireExprType {
203 pub fn null() -> Self {
204 Self {
205 wire_expr: WireExpr {
206 scope: ExprId::MIN,
207 suffix: Cow::from(""),
208 mapping: Mapping::Receiver,
209 },
210 }
211 }
212
213 pub fn is_null(&self) -> bool {
214 self.wire_expr.is_empty()
215 }
216
217 #[cfg(feature = "test")]
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 pub fn rand() -> Self {
264 use rand::Rng;
265 let mut rng = rand::thread_rng();
266
267 let id: ExprId = rng.gen();
268 let wire_expr = WireExpr::rand();
269
270 Self { id, wire_expr }
271 }
272 }
273
274 /// ```text
275 /// Flags:
276 /// - X: Reserved
277 /// - X: Reserved
278 /// - Z: Extension If Z==1 then at least one extension is present
279 ///
280 /// 7 6 5 4 3 2 1 0
281 /// +-+-+-+-+-+-+-+-+
282 /// |Z|X|X| U_KEXPR |
283 /// +---------------+
284 /// ~ expr_id:z16 ~
285 /// +---------------+
286 /// ~ [decl_exts] ~ if Z==1
287 /// +---------------+
288 /// ```
289 #[derive(Debug, Clone, PartialEq, Eq)]
290 pub struct UndeclareKeyExpr {
291 pub id: ExprId,
292 }
293
294 impl UndeclareKeyExpr {
295 #[cfg(feature = "test")]
296 pub fn rand() -> Self {
297 use rand::Rng;
298 let mut rng = rand::thread_rng();
299
300 let id: ExprId = rng.gen();
301
302 Self { id }
303 }
304 }
305}
306
307pub mod subscriber {
308 use super::*;
309 use crate::core::EntityId;
310
311 pub type SubscriberId = EntityId;
312
313 pub mod flag {
314 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
315 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
316 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
317 }
318
319 /// ```text
320 /// Flags:
321 /// - N: Named If N==1 then the key expr has name/suffix
322 /// - 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
323 /// - Z: Extension If Z==1 then at least one extension is present
324 ///
325 /// 7 6 5 4 3 2 1 0
326 /// +-+-+-+-+-+-+-+-+
327 /// |Z|M|N| D_SUB |
328 /// +---------------+
329 /// ~ subs_id:z32 ~
330 /// +---------------+
331 /// ~ key_scope:z16 ~
332 /// +---------------+
333 /// ~ key_suffix ~ if N==1 -- <u8;z16>
334 /// +---------------+
335 /// ~ [decl_exts] ~ if Z==1
336 /// +---------------+
337 ///
338 /// - if R==1 then the subscription is reliable, else it is best effort ///
339 /// ```
340 #[derive(Debug, Clone, PartialEq, Eq)]
341 pub struct DeclareSubscriber {
342 pub id: SubscriberId,
343 pub wire_expr: WireExpr<'static>,
344 }
345
346 impl DeclareSubscriber {
347 #[cfg(feature = "test")]
348 pub fn rand() -> Self {
349 use rand::Rng;
350 let mut rng = rand::thread_rng();
351
352 let id: SubscriberId = rng.gen();
353 let wire_expr = WireExpr::rand();
354
355 Self { id, wire_expr }
356 }
357 }
358
359 /// ```text
360 /// Flags:
361 /// - X: Reserved
362 /// - X: Reserved
363 /// - Z: Extension If Z==1 then at least one extension is present
364 ///
365 /// 7 6 5 4 3 2 1 0
366 /// +-+-+-+-+-+-+-+-+
367 /// |Z|X|X| U_SUB |
368 /// +---------------+
369 /// ~ subs_id:z32 ~
370 /// +---------------+
371 /// ~ [decl_exts] ~ if Z==1
372 /// +---------------+
373 /// ```
374 #[derive(Debug, Clone, PartialEq, Eq)]
375 pub struct UndeclareSubscriber {
376 pub id: SubscriberId,
377 pub ext_wire_expr: common::ext::WireExprType,
378 }
379
380 impl UndeclareSubscriber {
381 #[cfg(feature = "test")]
382 pub fn rand() -> Self {
383 use rand::Rng;
384 let mut rng = rand::thread_rng();
385
386 let id: SubscriberId = rng.gen();
387 let ext_wire_expr = common::ext::WireExprType::rand();
388
389 Self { id, ext_wire_expr }
390 }
391 }
392}
393
394pub mod queryable {
395 use super::*;
396 use crate::core::EntityId;
397
398 pub type QueryableId = EntityId;
399
400 pub mod flag {
401 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
402 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
403 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
404 }
405
406 /// ```text
407 /// Flags:
408 /// - N: Named If N==1 then the key expr has name/suffix
409 /// - 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
410 /// - Z: Extension If Z==1 then at least one extension is present
411 ///
412 /// 7 6 5 4 3 2 1 0
413 /// +-+-+-+-+-+-+-+-+
414 /// |Z|M|N| D_QBL |
415 /// +---------------+
416 /// ~ qbls_id:z32 ~
417 /// +---------------+
418 /// ~ key_scope:z16 ~
419 /// +---------------+
420 /// ~ key_suffix ~ if N==1 -- <u8;z16>
421 /// +---------------+
422 /// ~ [decl_exts] ~ if Z==1
423 /// +---------------+
424 ///
425 /// - if R==1 then the queryable is reliable, else it is best effort
426 /// - if P==1 then the queryable is pull, else it is push
427 /// - if C==1 then the queryable is complete and the N parameter is present
428 /// - if D==1 then the queryable distance is present
429 /// ```
430 #[derive(Debug, Clone, PartialEq, Eq)]
431 pub struct DeclareQueryable {
432 pub id: QueryableId,
433 pub wire_expr: WireExpr<'static>,
434 pub ext_info: ext::QueryableInfoType,
435 }
436
437 pub mod ext {
438 use super::*;
439
440 pub type QueryableInfo = zextz64!(0x01, false);
441
442 pub mod flag {
443 pub const C: u8 = 1; // 0x01 Complete if C==1 then the queryable is complete
444 }
445 ///
446 /// ```text
447 /// 7 6 5 4 3 2 1 0
448 /// +-+-+-+-+-+-+-+-+
449 /// |Z|0_1| ID |
450 /// +-+-+-+---------+
451 /// |x|x|x|x|x|x|x|C|
452 /// +---------------+
453 /// ~ distance <z16>~
454 /// +---------------+
455 /// ```
456 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
457 pub struct QueryableInfoType {
458 pub complete: bool, // Default false: incomplete
459 pub distance: u16, // Default 0: no distance
460 }
461
462 impl QueryableInfoType {
463 pub const DEFAULT: Self = Self {
464 complete: false,
465 distance: 0,
466 };
467
468 #[cfg(feature = "test")]
469 pub fn rand() -> Self {
470 use rand::Rng;
471 let mut rng = rand::thread_rng();
472 let complete: bool = rng.gen_bool(0.5);
473 let distance: u16 = rng.gen();
474
475 Self { complete, distance }
476 }
477 }
478
479 impl Default for QueryableInfoType {
480 fn default() -> Self {
481 Self::DEFAULT
482 }
483 }
484 }
485
486 impl DeclareQueryable {
487 #[cfg(feature = "test")]
488 pub fn rand() -> Self {
489 use rand::Rng;
490 let mut rng = rand::thread_rng();
491
492 let id: QueryableId = rng.gen();
493 let wire_expr = WireExpr::rand();
494 let ext_info = ext::QueryableInfoType::rand();
495
496 Self {
497 id,
498 wire_expr,
499 ext_info,
500 }
501 }
502 }
503
504 /// ```text
505 /// Flags:
506 /// - X: Reserved
507 /// - X: Reserved
508 /// - Z: Extension If Z==1 then at least one extension is present
509 ///
510 /// 7 6 5 4 3 2 1 0
511 /// +-+-+-+-+-+-+-+-+
512 /// |Z|X|X| U_QBL |
513 /// +---------------+
514 /// ~ qbls_id:z32 ~
515 /// +---------------+
516 /// ~ [decl_exts] ~ if Z==1
517 /// +---------------+
518 /// ```
519 #[derive(Debug, Clone, PartialEq, Eq)]
520 pub struct UndeclareQueryable {
521 pub id: QueryableId,
522 pub ext_wire_expr: common::ext::WireExprType,
523 }
524
525 impl UndeclareQueryable {
526 #[cfg(feature = "test")]
527 pub fn rand() -> Self {
528 use rand::Rng;
529 let mut rng = rand::thread_rng();
530
531 let id: QueryableId = rng.gen();
532 let ext_wire_expr = common::ext::WireExprType::rand();
533
534 Self { id, ext_wire_expr }
535 }
536 }
537}
538
539pub mod token {
540 use super::*;
541
542 pub type TokenId = u32;
543
544 pub mod flag {
545 pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix
546 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
547 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
548 }
549
550 /// ```text
551 /// Flags:
552 /// - N: Named If N==1 then the key expr has name/suffix
553 /// - 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
554 /// - Z: Extension If Z==1 then at least one extension is present
555 ///
556 /// 7 6 5 4 3 2 1 0
557 /// +-+-+-+-+-+-+-+-+
558 /// |Z|M|N| D_TKN |
559 /// +---------------+
560 /// ~ token_id:z32 ~
561 /// +---------------+
562 /// ~ key_scope:z16 ~
563 /// +---------------+
564 /// ~ key_suffix ~ if N==1 -- <u8;z16>
565 /// +---------------+
566 /// ~ [decl_exts] ~ if Z==1
567 /// +---------------+
568 ///
569 /// ```
570 #[derive(Debug, Clone, PartialEq, Eq)]
571 pub struct DeclareToken {
572 pub id: TokenId,
573 pub wire_expr: WireExpr<'static>,
574 }
575
576 impl DeclareToken {
577 #[cfg(feature = "test")]
578 pub fn rand() -> Self {
579 use rand::Rng;
580 let mut rng = rand::thread_rng();
581
582 let id: TokenId = rng.gen();
583 let wire_expr = WireExpr::rand();
584
585 Self { id, wire_expr }
586 }
587 }
588
589 /// ```text
590 /// Flags:
591 /// - X: Reserved
592 /// - X: Reserved
593 /// - Z: Extension If Z==1 then at least one extension is present
594 ///
595 /// 7 6 5 4 3 2 1 0
596 /// +-+-+-+-+-+-+-+-+
597 /// |Z|X|X| U_TKN |
598 /// +---------------+
599 /// ~ token_id:z32 ~
600 /// +---------------+
601 /// ~ [decl_exts] ~ if Z==1
602 /// +---------------+
603 /// ```
604 #[derive(Debug, Clone, PartialEq, Eq)]
605 pub struct UndeclareToken {
606 pub id: TokenId,
607 pub ext_wire_expr: common::ext::WireExprType,
608 }
609
610 impl UndeclareToken {
611 #[cfg(feature = "test")]
612 pub fn rand() -> Self {
613 use rand::Rng;
614 let mut rng = rand::thread_rng();
615
616 let id: TokenId = rng.gen();
617 let ext_wire_expr = common::ext::WireExprType::rand();
618
619 Self { id, ext_wire_expr }
620 }
621 }
622}