/src/zenoh/commons/zenoh-protocol/src/network/response.rs
Line | Count | Source |
1 | | use zenoh_buffers::buffer::Buffer; |
2 | | |
3 | | use crate::zenoh::reply::ReplyBody; |
4 | | // |
5 | | // Copyright (c) 2022 ZettaScale Technology |
6 | | // |
7 | | // This program and the accompanying materials are made available under the |
8 | | // terms of the Eclipse Public License 2.0 which is available at |
9 | | // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
10 | | // which is available at https://www.apache.org/licenses/LICENSE-2.0. |
11 | | // |
12 | | // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
13 | | // |
14 | | // Contributors: |
15 | | // ZettaScale Zenoh Team, <zenoh@zettascale.tech> |
16 | | // |
17 | | use crate::{core::WireExpr, network::RequestId, zenoh::ResponseBody}; |
18 | | |
19 | | /// # Response message |
20 | | /// |
21 | | /// ```text |
22 | | /// Flags: |
23 | | /// - N: Named If N==1 then the key expr has name/suffix |
24 | | /// - 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 |
25 | | /// - Z: Extension If Z==1 then at least one extension is present |
26 | | /// |
27 | | /// 7 6 5 4 3 2 1 0 |
28 | | /// +-+-+-+-+-+-+-+-+ |
29 | | /// |Z|M|N| Response| |
30 | | /// +-+-+-+---------+ |
31 | | /// ~ request_id:z32~ (*) |
32 | | /// +---------------+ |
33 | | /// ~ key_scope:z16 ~ |
34 | | /// +---------------+ |
35 | | /// ~ key_suffix ~ if N==1 -- <u8;z16> |
36 | | /// +---------------+ |
37 | | /// ~ [reply_exts] ~ if Z==1 |
38 | | /// +---------------+ |
39 | | /// ~ ResponseBody ~ -- Payload |
40 | | /// +---------------+ |
41 | | /// |
42 | | /// (*) The resolution of the request id is negotiated during the session establishment. |
43 | | /// This implementation limits the resolution to 32bit. |
44 | | /// ``` |
45 | | pub mod flag { |
46 | | pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix |
47 | | 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 |
48 | | pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow |
49 | | } |
50 | | |
51 | | #[derive(Debug, Clone, PartialEq, Eq)] |
52 | | pub struct Response { |
53 | | pub rid: RequestId, |
54 | | pub wire_expr: WireExpr<'static>, |
55 | | pub payload: ResponseBody, |
56 | | pub ext_qos: ext::QoSType, |
57 | | pub ext_tstamp: Option<ext::TimestampType>, |
58 | | pub ext_respid: Option<ext::ResponderIdType>, |
59 | | pub ext_ts_stack: Option<ext::TsStackType>, |
60 | | } |
61 | | |
62 | | pub mod ext { |
63 | | use crate::{zextz64, zextzbuf}; |
64 | | pub type QoS = zextz64!(0x1, false); |
65 | | pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; |
66 | | |
67 | | pub type Timestamp = zextzbuf!(0x2, false); |
68 | | pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; |
69 | | |
70 | | pub type ResponderId = zextzbuf!(0x3, false); |
71 | | pub type ResponderIdType = crate::network::ext::EntityGlobalIdType<{ ResponderId::ID }>; |
72 | | |
73 | | pub type TsStack = zextzbuf!(0x7, false); |
74 | | pub type TsStackType = crate::network::timestamp_stack::TsStackType<{ TsStack::ID }>; |
75 | | } |
76 | | |
77 | | impl Response { |
78 | 0 | pub fn payload_size(&self) -> usize { |
79 | 0 | match &self.payload { |
80 | 0 | ResponseBody::Reply(r) => match &r.payload { |
81 | 0 | ReplyBody::Put(p) => { |
82 | 0 | p.payload.len() + p.ext_attachment.as_ref().map_or(0, |a| a.buffer.len()) Unexecuted instantiation: <zenoh_protocol::network::response::Response>::payload_size::{closure#0}Unexecuted instantiation: <zenoh_protocol::network::response::Response>::payload_size::{closure#0} |
83 | | } |
84 | 0 | ReplyBody::Del(d) => d.ext_attachment.as_ref().map_or(0, |a| a.buffer.len()), Unexecuted instantiation: <zenoh_protocol::network::response::Response>::payload_size::{closure#1}Unexecuted instantiation: <zenoh_protocol::network::response::Response>::payload_size::{closure#1} |
85 | | }, |
86 | 0 | ResponseBody::Err(e) => e.payload.len(), |
87 | | } |
88 | 0 | } Unexecuted instantiation: <zenoh_protocol::network::response::Response>::payload_size Unexecuted instantiation: <zenoh_protocol::network::response::Response>::payload_size |
89 | | |
90 | | #[cfg(feature = "test")] |
91 | | #[doc(hidden)] |
92 | | pub fn rand() -> Self { |
93 | | use rand::Rng; |
94 | | let mut rng = rand::thread_rng(); |
95 | | |
96 | | let rid: RequestId = rng.gen(); |
97 | | let wire_expr = WireExpr::rand(); |
98 | | let payload = ResponseBody::rand(); |
99 | | let ext_qos = ext::QoSType::rand(); |
100 | | let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); |
101 | | let ext_respid = rng.gen_bool(0.5).then(ext::ResponderIdType::rand); |
102 | | let ext_ts_stack = rng.gen_bool(0.5).then(ext::TsStackType::rand); |
103 | | |
104 | | Self { |
105 | | rid, |
106 | | wire_expr, |
107 | | payload, |
108 | | ext_qos, |
109 | | ext_tstamp, |
110 | | ext_respid, |
111 | | ext_ts_stack, |
112 | | } |
113 | | } |
114 | | } |
115 | | |
116 | | /// # ResponseFinal message |
117 | | /// |
118 | | /// ```text |
119 | | /// Flags: |
120 | | /// - X: Reserved |
121 | | /// - X: Reserved |
122 | | /// - Z: Extension If Z==1 then at least one extension is present |
123 | | /// |
124 | | /// 7 6 5 4 3 2 1 0 |
125 | | /// +-+-+-+-+-+-+-+-+ |
126 | | /// |Z|X|X| ResFinal| |
127 | | /// +-+-+-+---------+ |
128 | | /// ~ request_id:z32~ (*) |
129 | | /// +---------------+ |
130 | | /// ~ [reply_exts] ~ if Z==1 |
131 | | /// +---------------+ |
132 | | /// |
133 | | /// (*) The resolution of the request id is negotiated during the session establishment. |
134 | | /// This implementation limits the resolution to 32bit. |
135 | | #[derive(Debug, Clone, PartialEq, Eq)] |
136 | | pub struct ResponseFinal { |
137 | | pub rid: RequestId, |
138 | | pub ext_qos: ext::QoSType, |
139 | | pub ext_tstamp: Option<ext::TimestampType>, |
140 | | } |
141 | | |
142 | | impl ResponseFinal { |
143 | | #[cfg(feature = "test")] |
144 | | #[doc(hidden)] |
145 | | pub fn rand() -> Self { |
146 | | use rand::Rng; |
147 | | |
148 | | let mut rng = rand::thread_rng(); |
149 | | let rid: RequestId = rng.gen(); |
150 | | let ext_qos = ext::QoSType::rand(); |
151 | | let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); |
152 | | |
153 | | Self { |
154 | | rid, |
155 | | ext_qos, |
156 | | ext_tstamp, |
157 | | } |
158 | | } |
159 | | } |