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 #[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 #[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 #[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 #[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 #[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 #[inline]
213 pub fn set_source(&mut self, source: Node<I, A>) -> &mut Self {
214 self.source = source;
215 self
216 }
217
218 #[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}