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}