memberlist_proto/
ping.rs

1use nodecraft::{CheapClone, Node};
2
3use super::{Data, DataRef, DecodeError, EncodeError};
4
5macro_rules! bail_ping {
6  (
7    $(#[$meta:meta])*
8    $name: ident
9  ) => {
10    $(#[$meta])*
11    #[viewit::viewit(
12      getters(vis_all = "pub"),
13      setters(vis_all = "pub", prefix = "with")
14    )]
15    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
16    #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
17    #[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
18    pub struct $name<I, A> {
19      /// The sequence number of the ack
20      #[viewit(
21        getter(const, attrs(doc = "Returns the sequence number of the ack")),
22        setter(
23          const,
24          attrs(doc = "Sets the sequence number of the ack (Builder pattern)")
25        )
26      )]
27      sequence_number: u32,
28
29      /// Source target, used for a direct reply
30      #[viewit(
31        getter(const, style = "ref", attrs(doc = "Returns the source node of the ping message")),
32        setter(attrs(doc = "Sets the source node of the ping message (Builder pattern)"))
33      )]
34      source: Node<I, A>,
35
36      /// [`Node`] is sent so the target can verify they are
37      /// the intended recipient. This is to protect again an agent
38      /// restart with a new name.
39      #[viewit(
40        getter(const, style = "ref", attrs(doc = "Returns the target node of the ping message")),
41        setter(attrs(doc = "Sets the target node of the ping message (Builder pattern)"))
42      )]
43      target: Node<I, A>,
44    }
45
46    paste::paste! {
47      const [< $name:upper _SEQUENCE_NUMBER_TAG >]: u8 = 1;
48      const [< $name:upper _SEQUENCE_NUMBER_BYTE >]: u8 = super::merge(super::WireType::Varint, [< $name:upper _SEQUENCE_NUMBER_TAG >]);
49      const [< $name:upper _SOURCE_TAG >]: u8 = 2;
50      const [< $name:upper _TARGET_TAG >]: u8 = 3;
51
52      impl<I, A> $name<I, A> {
53        #[inline]
54        const fn source_byte() -> u8
55        where
56          I: Data,
57          A: Data,
58        {
59          super::merge(super::WireType::LengthDelimited, [< $name:upper _SOURCE_TAG >])
60        }
61
62        #[inline]
63        const fn target_byte() -> u8
64        where
65          I: Data,
66          A: Data,
67        {
68          super::merge(super::WireType::LengthDelimited, [< $name:upper _TARGET_TAG >])
69        }
70      }
71
72      impl<'a, I, A> DataRef<'a, $name<I, A>> for $name<I::Ref<'a>, A::Ref<'a>>
73      where
74        I: Data,
75        A: Data,
76      {
77        fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
78        where
79          Self: Sized,
80        {
81          let mut sequence_number = None;
82          let mut source = None;
83          let mut target = None;
84
85          let mut offset = 0;
86          while offset < src.len() {
87            match src[offset] {
88              [< $name:upper _SEQUENCE_NUMBER_BYTE >] => {
89                if sequence_number.is_some() {
90                  return Err(DecodeError::duplicate_field(stringify!($name), "sequence number", [< $name:upper _SEQUENCE_NUMBER_TAG >]));
91                }
92                offset += 1;
93
94                let (bytes_read, value) = <u32 as DataRef<u32>>::decode(&src[offset..])?;
95                offset += bytes_read;
96                sequence_number = Some(value);
97              }
98              b if b == $name::<I, A>::source_byte() => {
99                if source.is_some() {
100                  return Err(DecodeError::duplicate_field(stringify!($name), "source", $name::<I, A>::source_byte()));
101                }
102                offset += 1;
103
104                let (bytes_read, value) = <Node<I::Ref<'_>, A::Ref<'_>> as DataRef<Node<I, A>>>::decode_length_delimited(&src[offset..])?;
105                offset += bytes_read;
106                source = Some(value);
107              }
108              b if b == $name::<I, A>::target_byte() => {
109                if target.is_some() {
110                  return Err(DecodeError::duplicate_field(stringify!($name), "target", $name::<I, A>::target_byte()));
111                }
112                offset += 1;
113
114                let (bytes_read, value) = <Node<I::Ref<'_>, A::Ref<'_>> as DataRef<Node<I, A>>>::decode_length_delimited(&src[offset..])?;
115                offset += bytes_read;
116                target = Some(value);
117              }
118              _ => offset += super::skip(stringify!($name), &src[offset..])?,
119            }
120          }
121
122          let sequence_number = sequence_number.ok_or_else(|| DecodeError::missing_field(stringify!($name), "sequence number"))?;
123          let source = source.ok_or_else(|| DecodeError::missing_field(stringify!($name), "source"))?;
124          let target = target.ok_or_else(|| DecodeError::missing_field(stringify!($name), "target"))?;
125
126          Ok((offset, Self {
127            sequence_number,
128            source,
129            target,
130          }))
131        }
132      }
133
134      impl<I, A> Data for $name<I, A>
135      where
136        I: Data,
137        A: Data,
138      {
139        type Ref<'a> = $name<I::Ref<'a>, A::Ref<'a>>;
140
141        fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError>
142        where
143          Self: Sized,
144        {
145          let Self::Ref { sequence_number, source, target } = val;
146          Node::from_ref(source)
147            .and_then(|source| Node::from_ref(target).map(|target| (source, target)))
148            .map(|(source, target)| Self::new(sequence_number, source, target))
149        }
150
151        fn encoded_len(&self) -> usize {
152          let mut len = 1 + self.sequence_number.encoded_len();
153          len += 1 + self.source.encoded_len_with_length_delimited();
154          len += 1 + self.target.encoded_len_with_length_delimited();
155          len
156        }
157
158        fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError>
159        {
160          macro_rules! bail {
161            ($this:ident($offset:expr, $len:ident)) => {
162              if $offset >= $len {
163                return Err(EncodeError::insufficient_buffer($this.encoded_len(), $len));
164              }
165            }
166          }
167
168          let len = buf.len();
169          let mut offset = 0;
170
171          bail!(self(offset, len));
172          buf[offset] = [< $name:upper _SEQUENCE_NUMBER_BYTE >];
173          offset += 1;
174          offset += self.sequence_number.encode(&mut buf[offset..]).map_err(|e| EncodeError::from(e).update(self.encoded_len(), len))?;
175
176          bail!(self(offset, len));
177          buf[offset] = Self::source_byte();
178          offset += 1;
179          offset += self.source.encode_length_delimited(&mut buf[offset..]).map_err(|e| e.update(self.encoded_len(), len))?;
180
181          bail!(self(offset, len));
182          buf[offset] = Self::target_byte();
183          offset += 1;
184          offset += self.target.encode_length_delimited(&mut buf[offset..]).map_err(|e| e.update(self.encoded_len(), len))?;
185
186          #[cfg(debug_assertions)]
187          super::debug_assert_write_eq::<Self>(offset, self.encoded_len());
188          Ok(offset)
189        }
190      }
191    }
192
193    impl<I, A> $name<I, A> {
194      /// Create a new message
195      #[inline]
196      pub const fn new(sequence_number: u32, source: Node<I, A>, target: Node<I, A>) -> Self {
197        Self {
198          sequence_number,
199          source,
200          target,
201        }
202      }
203
204      /// Sets the sequence number of the message
205      #[inline]
206      pub fn set_sequence_number(&mut self, sequence_number: u32) -> &mut Self {
207        self.sequence_number = sequence_number;
208        self
209      }
210
211      /// Sets the source node of the message
212      #[inline]
213      pub fn set_source(&mut self, source: Node<I, A>) -> &mut Self {
214        self.source = source;
215        self
216      }
217
218      /// Sets the target node of the message
219      #[inline]
220      pub fn set_target(&mut self, target: Node<I, A>) -> &mut Self {
221        self.target = target;
222        self
223      }
224    }
225
226    impl<I: CheapClone, A: CheapClone> CheapClone for $name<I, A> {
227      fn cheap_clone(&self) -> Self {
228        Self {
229          sequence_number: self.sequence_number,
230          source: self.source.cheap_clone(),
231          target: self.target.cheap_clone(),
232        }
233      }
234    }
235  };
236}
237
238bail_ping!(
239  #[doc = "Ping is sent to a target to check if it is alive"]
240  Ping
241);
242bail_ping!(
243  #[doc = "IndirectPing is sent to a target to check if it is alive"]
244  IndirectPing
245);
246
247impl<I, A> From<IndirectPing<I, A>> for Ping<I, A> {
248  fn from(ping: IndirectPing<I, A>) -> Self {
249    Self {
250      sequence_number: ping.sequence_number,
251      source: ping.source,
252      target: ping.target,
253    }
254  }
255}