1use std::{
2 borrow::Cow,
3 fmt,
4 fmt::{Error, Write},
5 ops::Deref,
6};
7
8use prometheus_client::encoding::{
9 EncodeLabelSet, EncodeLabelValue, LabelSetEncoder, LabelValueEncoder,
10};
11use zenoh_protocol::{
12 core::{Locator, Priority, WhatAmI, ZenohIdProto},
13 network::NetworkBodyRef,
14 zenoh::{PushBody, ResponseBody},
15};
16
17pub(crate) struct LabelsSetRef<'a, S>(pub(crate) &'a S);
19impl<S: EncodeLabelSet> EncodeLabelSet for LabelsSetRef<'_, S> {
20 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), Error> {
21 self.0.encode(encoder)
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26pub enum ResourceLabel {
27 Subscriber,
28 Queryable,
29 Token,
30}
31
32impl EncodeLabelValue for ResourceLabel {
33 fn encode(&self, encoder: &mut LabelValueEncoder) -> fmt::Result {
34 encoder.write_str(match self {
35 Self::Subscriber => "subscriber",
36 Self::Queryable => "queryable",
37 Self::Token => "token",
38 })
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Hash)]
43pub enum LocalityLabel {
44 Local,
45 Remote,
46}
47
48impl EncodeLabelValue for LocalityLabel {
49 fn encode(&self, encoder: &mut LabelValueEncoder) -> fmt::Result {
50 encoder.write_str(match self {
51 Self::Local => "local",
52 Self::Remote => "remote",
53 })
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
58pub enum MessageLabel {
59 Put,
60 Del,
61 Query,
62 Reply,
63 ReplyErr,
64 ResponseFinal,
65 Interest,
66 Declare,
67 Oam,
68}
69
70impl MessageLabel {
71 pub(crate) const NUM: usize = 9;
72}
73
74impl EncodeLabelValue for MessageLabel {
75 fn encode(&self, encoder: &mut LabelValueEncoder) -> fmt::Result {
76 encoder.write_str(match self {
77 Self::Put => "put",
78 Self::Del => "delete",
79 Self::Query => "query",
80 Self::Reply => "reply",
81 Self::ReplyErr => "reply-err",
82 Self::ResponseFinal => "response-final",
83 Self::Interest => "interest",
84 Self::Declare => "declare",
85 Self::Oam => "oam",
86 })
87 }
88}
89
90impl From<NetworkBodyRef<'_>> for MessageLabel {
91 fn from(value: NetworkBodyRef<'_>) -> Self {
92 match value {
93 NetworkBodyRef::Push(push) => match push.payload {
94 PushBody::Put(_) => MessageLabel::Put,
95 PushBody::Del(_) => MessageLabel::Del,
96 },
97 NetworkBodyRef::Request(_) => MessageLabel::Query,
98 NetworkBodyRef::Response(res) => match res.payload {
99 ResponseBody::Reply(_) => MessageLabel::Reply,
100 ResponseBody::Err(_) => MessageLabel::ReplyErr,
101 },
102 NetworkBodyRef::ResponseFinal(_) => MessageLabel::ResponseFinal,
103 NetworkBodyRef::Interest(_) => MessageLabel::Interest,
104 NetworkBodyRef::Declare(_) => MessageLabel::Declare,
105 NetworkBodyRef::OAM(_) => MessageLabel::Oam,
106 }
107 }
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
111pub enum SpaceLabel {
112 User,
113 Admin,
114}
115
116impl SpaceLabel {
117 pub(crate) const NUM: usize = 2;
118}
119
120impl EncodeLabelValue for SpaceLabel {
121 fn encode(&self, encoder: &mut LabelValueEncoder) -> fmt::Result {
122 encoder.write_str(match self {
123 Self::User => "user",
124 Self::Admin => "admin",
125 })
126 }
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
130pub enum ReasonLabel {
131 AccessControl,
132 Congestion,
133 Downsampling,
134 LowPass,
135 NoLink,
136}
137
138impl EncodeLabelValue for ReasonLabel {
139 fn encode(&self, encoder: &mut LabelValueEncoder) -> fmt::Result {
140 encoder.write_str(match self {
141 Self::AccessControl => "access-control",
142 Self::Congestion => "congestion",
143 Self::Downsampling => "downsampling",
144 Self::LowPass => "low-pass",
145 Self::NoLink => "no-link",
146 })
147 }
148}
149
150pub(crate) const SHM_NUM: usize = 2;
151
152macro_rules! wrap_label {
153 ($ty:ty, $label:ident $(, $derive:ty)*) => {
154 #[derive(Debug, Clone, PartialEq, Eq, Hash, $($derive),*)]
155 pub(crate) struct $label(pub(crate) $ty);
156
157 impl EncodeLabelValue for $label {
158 fn encode(&self, encoder: &mut LabelValueEncoder) -> fmt::Result {
159 write!(encoder, "{}", self.0)
160 }
161 }
162
163 impl<T: Into<$ty>> From<T> for $label {
164 fn from(value: T) -> Self {
165 Self(value.into())
166 }
167 }
168
169 impl Deref for $label {
170 type Target = $ty;
171
172 fn deref(&self) -> &Self::Target {
173 &self.0
174 }
175 }
176 };
177}
178
179wrap_label!(ZenohIdProto, ZidLabel, Copy);
180wrap_label!(WhatAmI, WhatAmILabel, Copy);
181wrap_label!(Priority, PriorityLabel, Copy);
182wrap_label!(Locator, LocatorLabel);
183
184pub(crate) type ProtocolLabel = Cow<'static, str>;
185
186#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
187pub(crate) struct TransportLabels {
188 pub(crate) remote_zid: Option<ZidLabel>,
189 pub(crate) remote_whatami: Option<WhatAmILabel>,
190 pub(crate) remote_group: Option<String>,
191 pub(crate) remote_cn: Option<String>,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
195pub(crate) struct ProtocolLabels {
196 pub(crate) protocol: ProtocolLabel,
197}
198
199#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EncodeLabelSet)]
200pub(crate) struct DisconnectedLabels {
201 pub(crate) disconnected: bool,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
205pub(crate) struct LinkLabels {
206 pub(crate) src_locator: LocatorLabel,
207 pub(crate) dst_locator: LocatorLabel,
208}
209
210impl LinkLabels {
211 pub(crate) fn protocol(&self) -> ProtocolLabel {
212 static KNOWN_PROTOCOLS: &[&str] = &[
213 "tcp",
214 "udp",
215 "tls",
216 "quic",
217 "unixsock-stream",
218 "ws",
219 "serial",
220 "unixpipe",
221 "vsock",
222 ];
223 let protocol = self.dst_locator.protocol().as_str();
224 match KNOWN_PROTOCOLS.iter().find(|p| **p == protocol) {
225 Some(p) => Cow::Borrowed(*p),
226 None => Cow::Owned(self.dst_locator.to_string()),
227 }
228 }
229}
230
231impl From<(&Locator, &Locator)> for LinkLabels {
232 fn from(value: (&Locator, &Locator)) -> Self {
233 Self {
234 src_locator: value.0.clone().into(),
235 dst_locator: value.1.clone().into(),
236 }
237 }
238}
239
240#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
241pub(crate) struct ResourceDeclaredLabels {
242 pub(crate) resource: ResourceLabel,
243 pub(crate) locality: LocalityLabel,
244}
245
246#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
247pub(crate) struct BytesLabels {
248 pub(crate) protocol: ProtocolLabel,
249}
250
251#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
252pub(crate) struct TransportMessageLabels {
253 pub(crate) protocol: ProtocolLabel,
254}
255
256#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
257pub(crate) struct NetworkMessageLabels {
258 pub(crate) priority: PriorityLabel,
259 pub(crate) message: MessageLabel,
260 pub(crate) shm: bool,
261 pub(crate) protocol: ProtocolLabel,
262}
263
264#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
265pub(crate) struct NetworkMessagePayloadLabels {
266 pub(crate) space: SpaceLabel,
267 pub(crate) priority: PriorityLabel,
268 pub(crate) message: MessageLabel,
269 pub(crate) shm: bool,
270}
271
272#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
273pub(crate) struct NetworkMessageDroppedPayloadLabels {
274 pub(crate) priority: PriorityLabel,
275 pub(crate) message: MessageLabel,
276 pub(crate) protocol: Option<ProtocolLabel>,
277 pub(crate) reason: ReasonLabel,
278}