1use bytes::Bytes;
2
3use super::{super::*, *};
4
5macro_rules! enum_wrapper {
6 (
7 $(#[$outer:meta])*
8 $vis:vis enum $name:ident $(<$($generic:tt),+>)? {
9 $(
10 $(#[$variant_meta:meta])*
11 $variant:ident(
12 $(#[$variant_ty_meta:meta])*
13 $variant_ty: ident $(<$($variant_generic:tt),+>)? $(,)?
14 ) = $variant_tag:expr
15 ), +$(,)?
16 }
17 ) => {
18 paste::paste! {
19 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::IsVariant)]
20 #[repr(u8)]
21 #[non_exhaustive]
22 #[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
23 $vis enum [< $name Type >] {
24 $(
25 $(#[$variant_meta])*
26 $variant = $variant_tag,
27 )*
28 }
29
30 impl core::fmt::Display for [< $name Type >] {
31 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32 write!(f, "{}", self.kind())
33 }
34 }
35
36 impl TryFrom<u8> for [< $name Type >] {
37 type Error = u8;
38
39 fn try_from(value: u8) -> Result<Self, Self::Error> {
40 match value {
41 $(
42 $variant_tag => Ok(Self::$variant),
43 )*
44 _ => Err(value),
45 }
46 }
47 }
48
49 impl [< $name Type >] {
50 pub const POSSIBLE_VALUES: &'static [Self] = &[
52 $(
53 Self::$variant,
54 )*
55 ];
56
57 #[inline]
59 pub const fn wire_type $(< $($generic),+ >)?(&self) -> WireType
60 where
61 $($($generic: Data),+)?
62 {
63 match self {
64 $(
65 Self::$variant => <$variant_ty $(< $($variant_generic),+ >)? as Data>::WIRE_TYPE,
66 )*
67 }
68 }
69
70 #[inline]
72 pub const fn tag(&self) -> u8 {
73 match self {
74 $(
75 Self::$variant => $variant_tag,
76 )*
77 }
78 }
79
80 #[inline]
82 pub const fn kind(&self) -> &'static str {
83 match self {
84 $(
85 Self::$variant => stringify!([< $variant:camel >]),
86 )*
87 }
88 }
89 }
90 }
91
92 $(#[$outer])*
93 $vis enum $name $(< $($generic),+ >)? {
94 $(
95 $(#[$variant_meta])*
96 $variant(
97 $(#[$variant_ty_meta])*
98 $variant_ty $(< $($variant_generic),+ >)?
99 ),
100 )*
101 }
102
103 impl $(< $($generic),+ >)? $name $(< $($generic),+ >)? {
104 #[inline]
106 pub const fn tag(&self) -> u8 {
107 match self {
108 $(
109 Self::$variant(_) => $variant_tag,
110 )*
111 }
112 }
113
114 paste::paste! {
115 #[inline]
117 pub const fn ty(&self) -> [< $name Type >] {
118 match self {
119 $(
120 Self::$variant(_) => [< $name Type >]::$variant,
121 )*
122 }
123 }
124 }
125
126 $(
127 paste::paste! {
128 #[doc = concat!("Construct a [`", stringify!($name), "`] from [`", stringify!($variant_ty), "`].")]
129 pub const fn [< $variant:snake >](val: $variant_ty $(< $($variant_generic),+ >)?) -> Self {
130 Self::$variant(val)
131 }
132 }
133 )*
134 }
135
136 paste::paste! {
137 impl $(< $($generic),+ >)? [< $name Re f>]<'_, $( $($generic),+ )?> {
138 #[inline]
140 pub const fn ty(&self) -> [< $name Type >] {
141 match self {
142 $(
143 Self::$variant(_) => [< $name Type >]::$variant,
144 )*
145 }
146 }
147 }
148
149 impl$(< $($generic),+ >)? Data for $name $(< $($generic),+ >)?
150 $(
151 where
152 $($generic: Data),+
153 )?
154 {
155 type Ref<'a> = [< $name Ref >]<'a, $($($generic::Ref<'a>),+)?>;
156
157 fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError>
158 where
159 Self: Sized,
160 {
161 Ok(match val {
162 $(
163 Self::Ref::$variant(val) => Self::$variant($variant_ty::from_ref(val)?),
164 )*
165 })
166 }
167
168 fn encoded_len(&self) -> usize {
169 1 + match self {
170 $(
171 Self::$variant(val) => val.encoded_len_with_length_delimited(),
172 )*
173 }
174 }
175
176 fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
177 let len = buf.len();
178 if len < 1 {
179 return Err(EncodeError::insufficient_buffer(self.encoded_len(), len));
180 }
181
182 let mut offset = 0;
183 buf[offset] = self.tag();
184 offset += 1;
185
186 match self {
187 $(
188 Self::$variant(val) => {
189 offset += val.encode_length_delimited(&mut buf[offset..])?;
190 }
191 )*
192 }
193
194 Ok(offset)
195 }
196 }
197 }
198 };
199}
200
201enum_wrapper!(
202 #[derive(
204 Debug,
205 Clone,
206 derive_more::From,
207 derive_more::IsVariant,
208 derive_more::Unwrap,
209 derive_more::TryUnwrap,
210 PartialEq,
211 Eq,
212 Hash,
213 )]
214 #[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
215 #[non_exhaustive]
216 pub enum Message<I, A> {
217 Ping(Ping<I, A>) = PING_MESSAGE_TAG,
219 IndirectPing(IndirectPing<I, A>) = INDIRECT_PING_MESSAGE_TAG,
221 Ack(Ack) = ACK_MESSAGE_TAG,
223 Suspect(Suspect<I>) = SUSPECT_MESSAGE_TAG,
225 Alive(Alive<I, A>) = ALIVE_MESSAGE_TAG,
227 Dead(Dead<I>) = DEAD_MESSAGE_TAG,
229 PushPull(PushPull<I, A>) = PUSH_PULL_MESSAGE_TAG,
231 UserData(
233 #[cfg_attr(any(feature = "arbitrary", test), arbitrary(with = crate::arbitrary_impl::bytes))]
234 Bytes,
235 ) = USER_DATA_MESSAGE_TAG,
236 Nack(Nack) = NACK_MESSAGE_TAG,
238 ErrorResponse(ErrorResponse) = ERROR_RESPONSE_MESSAGE_TAG,
240 }
241);
242
243impl<'a, I, A> DataRef<'a, Message<I, A>> for MessageRef<'a, I::Ref<'a>, A::Ref<'a>>
244where
245 I: Data,
246 A: Data,
247{
248 fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
249 where
250 Self: Sized,
251 {
252 let len = src.len();
253 if len < 1 {
254 return Err(DecodeError::buffer_underflow());
255 }
256
257 let mut offset = 0;
258 let b = src[offset];
259 offset += 1;
260
261 Ok(match b {
262 PING_MESSAGE_TAG => {
263 let (bytes_read, decoded) =
264 <Ping<I::Ref<'_>, A::Ref<'_>> as DataRef<Ping<I, A>>>::decode_length_delimited(
265 &src[offset..],
266 )?;
267 offset += bytes_read;
268 (offset, Self::Ping(decoded))
269 }
270 INDIRECT_PING_MESSAGE_TAG => {
271 let (bytes_read, decoded) = <IndirectPing<I::Ref<'_>, A::Ref<'_>> as DataRef<
272 IndirectPing<I, A>,
273 >>::decode_length_delimited(&src[offset..])?;
274 offset += bytes_read;
275 (offset, Self::IndirectPing(decoded))
276 }
277 ACK_MESSAGE_TAG => {
278 let (bytes_read, decoded) =
279 <AckRef<'_> as DataRef<Ack>>::decode_length_delimited(&src[offset..])?;
280 offset += bytes_read;
281 (offset, Self::Ack(decoded))
282 }
283 SUSPECT_MESSAGE_TAG => {
284 let (bytes_read, decoded) =
285 <Suspect<I::Ref<'_>> as DataRef<Suspect<I>>>::decode_length_delimited(&src[offset..])?;
286 offset += bytes_read;
287 (offset, Self::Suspect(decoded))
288 }
289 ALIVE_MESSAGE_TAG => {
290 let (bytes_read, decoded) = <AliveRef<'_, I::Ref<'_>, A::Ref<'_>> as DataRef<
291 Alive<I, A>,
292 >>::decode_length_delimited(&src[offset..])?;
293 offset += bytes_read;
294 (offset, Self::Alive(decoded))
295 }
296 DEAD_MESSAGE_TAG => {
297 let (bytes_read, decoded) =
298 <Dead<I::Ref<'_>> as DataRef<Dead<I>>>::decode_length_delimited(&src[offset..])?;
299 offset += bytes_read;
300 (offset, Self::Dead(decoded))
301 }
302 PUSH_PULL_MESSAGE_TAG => {
303 let (bytes_read, decoded) = <PushPullRef<'_, I::Ref<'_>, A::Ref<'_>> as DataRef<
304 PushPull<I, A>,
305 >>::decode_length_delimited(&src[offset..])?;
306 offset += bytes_read;
307 (offset, Self::PushPull(decoded))
308 }
309 USER_DATA_MESSAGE_TAG => {
310 let (bytes_read, decoded) =
311 <&[u8] as DataRef<Bytes>>::decode_length_delimited(&src[offset..])?;
312 offset += bytes_read;
313 (offset, Self::UserData(decoded))
314 }
315 NACK_MESSAGE_TAG => {
316 let (bytes_read, decoded) =
317 <Nack as DataRef<Nack>>::decode_length_delimited(&src[offset..])?;
318 offset += bytes_read;
319 (offset, Self::Nack(decoded))
320 }
321 ERROR_RESPONSE_MESSAGE_TAG => {
322 let (bytes_read, decoded) =
323 <ErrorResponseRef<'_> as DataRef<ErrorResponse>>::decode_length_delimited(
324 &src[offset..],
325 )?;
326 offset += bytes_read;
327 (offset, Self::ErrorResponse(decoded))
328 }
329 tag => {
330 return Err(DecodeError::unknown_tag("Message", tag));
331 }
332 })
333 }
334}
335
336#[derive(
338 Debug,
339 Copy,
340 Clone,
341 derive_more::From,
342 derive_more::IsVariant,
343 derive_more::Unwrap,
344 derive_more::TryUnwrap,
345)]
346pub enum MessageRef<'a, I, A> {
347 Ping(Ping<I, A>),
349 IndirectPing(IndirectPing<I, A>),
351 Ack(AckRef<'a>),
353 Suspect(Suspect<I>),
355 Alive(AliveRef<'a, I, A>),
357 Dead(Dead<I>),
359 PushPull(PushPullRef<'a, I, A>),
361 UserData(&'a [u8]),
363 Nack(Nack),
365 ErrorResponse(ErrorResponseRef<'a>),
367}