memberlist_proto/proto/
message.rs

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        /// All possible values of this enum.
51        pub const POSSIBLE_VALUES: &'static [Self] = &[
52          $(
53            Self::$variant,
54          )*
55        ];
56
57        /// Returns the wire type of this message.
58        #[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        /// Returns the tag of this message type for encoding/decoding.
71        #[inline]
72        pub const fn tag(&self) -> u8 {
73          match self {
74            $(
75              Self::$variant => $variant_tag,
76            )*
77          }
78        }
79
80        /// Returns the kind of this message.
81        #[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      /// Returns the tag of this message type for encoding/decoding.
105      #[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        /// Returns the type of the message.
116        #[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        /// Returns the type of the message.
139        #[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  /// Request to be sent to the Raft node.
203  #[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 message
218    Ping(Ping<I, A>) = PING_MESSAGE_TAG,
219    /// Indirect ping message
220    IndirectPing(IndirectPing<I, A>) = INDIRECT_PING_MESSAGE_TAG,
221    /// Ack response message
222    Ack(Ack) = ACK_MESSAGE_TAG,
223    /// Suspect message
224    Suspect(Suspect<I>) = SUSPECT_MESSAGE_TAG,
225    /// Alive message
226    Alive(Alive<I, A>) = ALIVE_MESSAGE_TAG,
227    /// Dead message
228    Dead(Dead<I>) = DEAD_MESSAGE_TAG,
229    /// PushPull message
230    PushPull(PushPull<I, A>) = PUSH_PULL_MESSAGE_TAG,
231    /// User mesg, not handled by us
232    UserData(
233      #[cfg_attr(any(feature = "arbitrary", test), arbitrary(with = crate::arbitrary_impl::bytes))]
234      Bytes,
235    ) = USER_DATA_MESSAGE_TAG,
236    /// Nack response message
237    Nack(Nack) = NACK_MESSAGE_TAG,
238    /// Error response message
239    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/// The reference type of the [`Message`] enum.
337#[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 message
348  Ping(Ping<I, A>),
349  /// Indirect ping message
350  IndirectPing(IndirectPing<I, A>),
351  /// Ack response message
352  Ack(AckRef<'a>),
353  /// Suspect message
354  Suspect(Suspect<I>),
355  /// Alive message
356  Alive(AliveRef<'a, I, A>),
357  /// Dead message
358  Dead(Dead<I>),
359  /// PushPull message
360  PushPull(PushPullRef<'a, I, A>),
361  /// User mesg, not handled by us
362  UserData(&'a [u8]),
363  /// Nack response message
364  Nack(Nack),
365  /// Error response message
366  ErrorResponse(ErrorResponseRef<'a>),
367}