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}