1use super::ZInt;
15use zenoh_core::{bail, zresult::ZError};
16
17#[repr(u8)]
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum WhatAmI {
20 Router = 1,
21 Peer = 1 << 1,
22 Client = 1 << 2,
23}
24
25impl std::str::FromStr for WhatAmI {
26 type Err = ZError;
27
28 fn from_str(s: &str) -> Result<Self, Self::Err> {
29 match s {
30 "router" => Ok(WhatAmI::Router),
31 "peer" => Ok(WhatAmI::Peer),
32 "client" => Ok(WhatAmI::Client),
33 _ => bail!("{} is not a valid WhatAmI value. Valid values are: [\"router\", \"peer\", \"client\"].", s),
34 }
35 }
36}
37
38impl WhatAmI {
39 pub fn to_str(self) -> &'static str {
40 match self {
41 WhatAmI::Router => "router",
42 WhatAmI::Peer => "peer",
43 WhatAmI::Client => "client",
44 }
45 }
46
47 pub fn try_from(value: ZInt) -> Option<Self> {
48 const CLIENT: ZInt = WhatAmI::Client as ZInt;
49 const ROUTER: ZInt = WhatAmI::Router as ZInt;
50 const PEER: ZInt = WhatAmI::Peer as ZInt;
51 match value {
52 CLIENT => Some(WhatAmI::Client),
53 ROUTER => Some(WhatAmI::Router),
54 PEER => Some(WhatAmI::Peer),
55 _ => None,
56 }
57 }
58}
59
60impl std::fmt::Display for WhatAmI {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 f.write_str(self.to_str())
63 }
64}
65
66impl serde::Serialize for WhatAmI {
67 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68 where
69 S: serde::Serializer,
70 {
71 serializer.serialize_str(self.to_str())
72 }
73}
74
75pub struct WhatAmIVisitor;
76
77impl<'de> serde::de::Visitor<'de> for WhatAmIVisitor {
78 type Value = WhatAmI;
79
80 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
81 formatter.write_str("either 'router', 'client' or 'peer'")
82 }
83 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
84 where
85 E: serde::de::Error,
86 {
87 v.parse()
88 .map_err(|_| serde::de::Error::unknown_variant(v, &["router", "client", "peer"]))
89 }
90 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
91 where
92 E: serde::de::Error,
93 {
94 self.visit_str(v)
95 }
96 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
97 where
98 E: serde::de::Error,
99 {
100 self.visit_str(&v)
101 }
102}
103
104impl<'de> serde::Deserialize<'de> for WhatAmI {
105 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
106 where
107 D: serde::Deserializer<'de>,
108 {
109 deserializer.deserialize_str(WhatAmIVisitor)
110 }
111}
112
113impl From<WhatAmI> for ZInt {
114 fn from(w: WhatAmI) -> Self {
115 w as ZInt
116 }
117}
118
119use std::{num::NonZeroU8, ops::BitOr};
120#[repr(transparent)]
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
122pub struct WhatAmIMatcher(pub NonZeroU8);
123
124impl WhatAmIMatcher {
125 pub fn try_from<T: std::convert::TryInto<u8>>(i: T) -> Option<Self> {
126 let i = i.try_into().ok()?;
127 if 127 < i && i < 136 {
128 Some(WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(i) }))
129 } else {
130 None
131 }
132 }
133
134 pub fn is_empty(self) -> bool {
135 self.0.get() == 128
136 }
137
138 pub fn empty() -> Self {
139 WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(128) })
140 }
141
142 pub fn matches(self, w: WhatAmI) -> bool {
143 (self.0.get() & w as u8) != 0
144 }
145
146 pub fn to_str(self) -> &'static str {
147 match self.0.get() {
148 128 => "",
149 129 => "router",
150 130 => "peer",
151 132 => "client",
152 131 => "router|peer",
153 134 => "client|peer",
154 133 => "client|router",
155 135 => "client|router|peer",
156 _ => "invalid_matcher",
157 }
158 }
159}
160
161impl std::str::FromStr for WhatAmIMatcher {
162 type Err = ();
163
164 fn from_str(s: &str) -> Result<Self, Self::Err> {
165 let mut inner = 128;
166 for s in s.split('|') {
167 match s.trim() {
168 "" => {}
169 "router" => inner |= WhatAmI::Router as u8,
170 "client" => inner |= WhatAmI::Client as u8,
171 "peer" => inner |= WhatAmI::Peer as u8,
172 _ => return Err(()),
173 }
174 }
175 Self::try_from(inner).ok_or(())
176 }
177}
178
179impl serde::Serialize for WhatAmIMatcher {
180 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
181 where
182 S: serde::Serializer,
183 {
184 serializer.serialize_str(self.to_str())
185 }
186}
187pub struct WhatAmIMatcherVisitor;
188impl<'de> serde::de::Visitor<'de> for WhatAmIMatcherVisitor {
189 type Value = WhatAmIMatcher;
190 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
191 formatter.write_str("a | separated list of whatami variants ('peer', 'client' or 'router')")
192 }
193 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
194 where
195 E: serde::de::Error,
196 {
197 v.parse().map_err(|_| {
198 serde::de::Error::invalid_value(
199 serde::de::Unexpected::Str(v),
200 &"a | separated list of whatami variants ('peer', 'client' or 'router')",
201 )
202 })
203 }
204 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
205 where
206 E: serde::de::Error,
207 {
208 self.visit_str(v)
209 }
210 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
211 where
212 E: serde::de::Error,
213 {
214 self.visit_str(&v)
215 }
216}
217
218impl<'de> serde::Deserialize<'de> for WhatAmIMatcher {
219 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
220 where
221 D: serde::Deserializer<'de>,
222 {
223 deserializer.deserialize_str(WhatAmIMatcherVisitor)
224 }
225}
226
227impl std::fmt::Display for WhatAmIMatcher {
228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229 f.write_str(self.to_str())
230 }
231}
232
233impl From<WhatAmIMatcher> for ZInt {
234 fn from(w: WhatAmIMatcher) -> ZInt {
235 w.0.get() as ZInt
236 }
237}
238
239impl<T> BitOr<T> for WhatAmIMatcher
240where
241 NonZeroU8: BitOr<T, Output = NonZeroU8>,
242{
243 type Output = Self;
244 fn bitor(self, rhs: T) -> Self::Output {
245 WhatAmIMatcher(self.0 | rhs)
246 }
247}
248
249impl BitOr<WhatAmI> for WhatAmIMatcher {
250 type Output = Self;
251 fn bitor(self, rhs: WhatAmI) -> Self::Output {
252 self | rhs as u8
253 }
254}
255
256impl BitOr for WhatAmIMatcher {
257 type Output = Self;
258 fn bitor(self, rhs: Self) -> Self::Output {
259 self | rhs.0
260 }
261}
262
263impl BitOr for WhatAmI {
264 type Output = WhatAmIMatcher;
265 fn bitor(self, rhs: Self) -> Self::Output {
266 WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(self as u8 | rhs as u8 | 128) })
267 }
268}
269
270impl From<WhatAmI> for WhatAmIMatcher {
271 fn from(w: WhatAmI) -> Self {
272 WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(w as u8 | 128) })
273 }
274}