Skip to main content

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}