memberlist_proto/
data.rs

1use std::borrow::Cow;
2
3use varing::{decode_u32_varint, encode_u32_varint_to, encoded_u32_varint_len};
4
5use super::WireType;
6
7pub use tuple::TupleEncoder;
8
9#[cfg(any(feature = "std", feature = "alloc"))]
10mod bytes;
11#[cfg(any(feature = "std", feature = "alloc"))]
12mod nodecraft;
13mod primitives;
14#[cfg(any(feature = "std", feature = "alloc"))]
15mod string;
16
17mod tuple;
18
19/// The reference type of the data.
20pub trait DataRef<'a, D>
21where
22  D: Data + ?Sized,
23  Self: Copy + core::fmt::Debug + Send + Sync,
24{
25  /// Decodes the reference type from a buffer.
26  ///
27  /// The entire buffer will be consumed.
28  fn decode(buf: &'a [u8]) -> Result<(usize, Self), DecodeError>
29  where
30    Self: Sized;
31
32  /// Decodes a length-delimited reference instance of the message from the buffer.
33  fn decode_length_delimited(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
34  where
35    Self: Sized,
36  {
37    if D::WIRE_TYPE != WireType::LengthDelimited {
38      return Self::decode(src);
39    }
40
41    let (offset, len) = decode_u32_varint(src)?;
42    let mut offset = offset.get();
43    let len = len as usize;
44    if len + offset > src.len() {
45      return Err(DecodeError::buffer_underflow());
46    }
47
48    let src = &src[offset..offset + len];
49    let (bytes_read, value) = Self::decode(src)?;
50
51    #[cfg(debug_assertions)]
52    super::debug_assert_read_eq::<Self>(bytes_read, len);
53
54    offset += bytes_read;
55    Ok((offset, value))
56  }
57}
58
59/// The memberlist data can be transmitted through the network.
60pub trait Data: core::fmt::Debug + Send + Sync {
61  /// The wire type of the data.
62  const WIRE_TYPE: WireType = WireType::LengthDelimited;
63
64  /// The reference type of the data.
65  type Ref<'a>: DataRef<'a, Self>;
66
67  /// Converts the reference type to the owned type.
68  fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError>
69  where
70    Self: Sized;
71
72  /// Returns the encoded length of the data only considering the data itself, (e.g. no length prefix, no wire type).
73  fn encoded_len(&self) -> usize;
74
75  /// Returns the encoded length of the data including the length delimited.
76  fn encoded_len_with_length_delimited(&self) -> usize {
77    let len = self.encoded_len();
78    match Self::WIRE_TYPE {
79      WireType::LengthDelimited => encoded_u32_varint_len(len as u32).get() + len,
80      _ => len,
81    }
82  }
83
84  /// Encodes the message to a buffer.
85  ///
86  /// An error will be returned if the buffer does not have sufficient capacity.
87  fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError>;
88
89  /// Encodes the message into a vec.
90  #[cfg(any(feature = "std", feature = "alloc"))]
91  fn encode_to_vec(&self) -> Result<std::vec::Vec<u8>, EncodeError> {
92    let len = self.encoded_len();
93    let mut vec = std::vec![0; len];
94    self.encode(&mut vec).map(|_| vec)
95  }
96
97  /// Encodes the message into a [`Bytes`](::bytes::Bytes).
98  #[cfg(any(feature = "std", feature = "alloc"))]
99  fn encode_to_bytes(&self) -> Result<::bytes::Bytes, EncodeError> {
100    self.encode_to_vec().map(Into::into)
101  }
102
103  /// Encodes the message with a length-delimiter to a buffer.
104  ///
105  /// An error will be returned if the buffer does not have sufficient capacity.
106  fn encode_length_delimited(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
107    if Self::WIRE_TYPE != WireType::LengthDelimited {
108      return self.encode(buf);
109    }
110
111    let len = self.encoded_len();
112    if len > u32::MAX as usize {
113      return Err(EncodeError::TooLarge);
114    }
115
116    let mut offset = 0;
117    offset += encode_u32_varint_to(len as u32, buf)?.get();
118    offset += self.encode(&mut buf[offset..])?;
119
120    #[cfg(debug_assertions)]
121    super::debug_assert_write_eq::<Self>(offset, self.encoded_len_with_length_delimited());
122
123    Ok(offset)
124  }
125
126  /// Encodes the message with a length-delimiter into a vec.
127  #[cfg(any(feature = "std", feature = "alloc"))]
128  fn encode_length_delimited_to_vec(&self) -> Result<std::vec::Vec<u8>, EncodeError> {
129    let len = self.encoded_len_with_length_delimited();
130    let mut vec = std::vec![0; len];
131    self.encode_length_delimited(&mut vec).map(|_| vec)
132  }
133
134  /// Encodes the message with a length-delimiter into a [`Bytes`](::bytes::Bytes).
135  #[cfg(any(feature = "std", feature = "alloc"))]
136  fn encode_length_delimited_to_bytes(&self) -> Result<::bytes::Bytes, EncodeError> {
137    self.encode_length_delimited_to_vec().map(Into::into)
138  }
139
140  /// Decodes an instance of the message from a buffer.
141  ///
142  /// The entire buffer will be consumed.
143  fn decode(src: &[u8]) -> Result<(usize, Self), DecodeError>
144  where
145    Self: Sized,
146  {
147    <Self::Ref<'_> as DataRef<Self>>::decode(src)
148      .and_then(|(bytes_read, value)| Self::from_ref(value).map(|val| (bytes_read, val)))
149  }
150
151  /// Decodes a length-delimited instance of the message from the buffer.
152  fn decode_length_delimited(buf: &[u8]) -> Result<(usize, Self), DecodeError>
153  where
154    Self: Sized,
155  {
156    <Self::Ref<'_> as DataRef<Self>>::decode_length_delimited(buf)
157      .and_then(|(bytes_read, value)| Self::from_ref(value).map(|val| (bytes_read, val)))
158  }
159}
160
161/// A data encoding error
162#[derive(Debug, thiserror::Error)]
163pub enum EncodeError {
164  /// Returned when the encoded buffer is too small to hold the bytes format of the types.
165  #[error("insufficient buffer capacity, required: {required}, remaining: {remaining}")]
166  InsufficientBuffer {
167    /// The required buffer capacity.
168    required: usize,
169    /// The remaining buffer capacity.
170    remaining: usize,
171  },
172  /// Returned when the data in encoded format is larger than the maximum allowed size.
173  #[error("encoded data is too large, the maximum allowed size is {MAX} bytes", MAX = u32::MAX)]
174  TooLarge,
175  /// A custom encoding error.
176  #[error("{0}")]
177  Custom(Cow<'static, str>),
178}
179
180impl EncodeError {
181  /// Creates an insufficient buffer error.
182  #[inline]
183  pub const fn insufficient_buffer(required: usize, remaining: usize) -> Self {
184    Self::InsufficientBuffer {
185      required,
186      remaining,
187    }
188  }
189
190  /// Creates a custom encoding error.
191  pub fn custom<T>(value: T) -> Self
192  where
193    T: Into<Cow<'static, str>>,
194  {
195    Self::Custom(value.into())
196  }
197
198  /// Update the error with the required and remaining buffer capacity.
199  pub fn update(mut self, required: usize, remaining: usize) -> Self {
200    match self {
201      Self::InsufficientBuffer {
202        required: ref mut r,
203        remaining: ref mut rem,
204      } => {
205        *r = required;
206        *rem = remaining;
207        self
208      }
209      _ => self,
210    }
211  }
212}
213
214impl From<varing::EncodeError> for EncodeError {
215  #[inline]
216  fn from(value: varing::EncodeError) -> Self {
217    match value {
218      varing::EncodeError::InsufficientSpace(err) => Self::InsufficientBuffer {
219        required: err.requested().get(),
220        remaining: err.available(),
221      },
222      varing::EncodeError::Other(e) => EncodeError::custom(e),
223      _ => EncodeError::custom("unknown encoding error"),
224    }
225  }
226}
227
228impl From<varing::ConstEncodeError> for EncodeError {
229  #[inline]
230  fn from(value: varing::ConstEncodeError) -> Self {
231    match value {
232      varing::ConstEncodeError::InsufficientSpace(err) => Self::InsufficientBuffer {
233        required: err.requested().get(),
234        remaining: err.available(),
235      },
236      varing::ConstEncodeError::Other(e) => EncodeError::custom(e),
237      _ => EncodeError::custom("unknown encoding error"),
238    }
239  }
240}
241
242impl From<Cow<'static, str>> for EncodeError {
243  fn from(value: Cow<'static, str>) -> Self {
244    Self::Custom(value)
245  }
246}
247
248/// A message decoding error.
249///
250/// `DecodeError` indicates that the input buffer does not contain a valid
251/// message. The error details should be considered 'best effort': in
252/// general it is not possible to exactly pinpoint why data is malformed.
253#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error, derive_more::IsVariant)]
254pub enum DecodeError {
255  /// Returned when the buffer does not have enough data to decode the message.
256  #[error("buffer underflow")]
257  BufferUnderflow,
258
259  /// Returned when the buffer does not contain the required field.
260  #[error("missing {field} in {ty}")]
261  MissingField {
262    /// The type of the message.
263    ty: &'static str,
264    /// The name of the field.
265    field: &'static str,
266  },
267
268  /// Returned when the buffer contains duplicate fields for the same tag in a message.
269  #[error("duplicate field {field} with tag {tag} in {ty}")]
270  DuplicateField {
271    /// The type of the message.
272    ty: &'static str,
273    /// The name of the field.
274    field: &'static str,
275    /// The tag of the field.
276    tag: u8,
277  },
278
279  /// Returned when there is a unknown wire type.
280  #[error("unknown wire type value {value} with tag {tag} when decoding {ty}")]
281  UnknownWireType {
282    /// The type of the message.
283    ty: &'static str,
284    /// The unknown wire type value.
285    value: u8,
286    /// The tag of the field.
287    tag: u8,
288  },
289
290  /// Returned when finding a unknown tag.
291  #[error("unknown tag {tag} when decoding {ty}")]
292  UnknownTag {
293    /// The type of the message.
294    ty: &'static str,
295    /// The unknown tag value.
296    tag: u8,
297  },
298
299  /// Returned when fail to decode the length-delimited
300  #[error("length-delimited overflow the maximum value of u32")]
301  LengthDelimitedOverflow,
302
303  /// A custom decoding error.
304  #[error("{0}")]
305  Custom(Cow<'static, str>),
306}
307
308impl From<varing::DecodeError> for DecodeError {
309  #[inline]
310  fn from(e: varing::DecodeError) -> Self {
311    match e {
312      varing::DecodeError::Overflow => Self::LengthDelimitedOverflow,
313      varing::DecodeError::InsufficientData { .. } => Self::buffer_underflow(),
314      varing::DecodeError::Other(cow) => Self::Custom(cow),
315      _ => {
316        // Convert other decode errors to custom error
317        Self::custom("unknown decoding error")
318      }
319    }
320  }
321}
322
323impl From<varing::ConstDecodeError> for DecodeError {
324  #[inline]
325  fn from(e: varing::ConstDecodeError) -> Self {
326    match e {
327      varing::ConstDecodeError::Overflow => Self::LengthDelimitedOverflow,
328      varing::ConstDecodeError::InsufficientData { .. } => Self::buffer_underflow(),
329      varing::ConstDecodeError::Other(cow) => Self::custom(cow),
330      _ => {
331        // Convert other decode errors to custom error
332        Self::custom("unknown decoding error")
333      }
334    }
335  }
336}
337
338impl DecodeError {
339  /// Creates a new buffer underflow decoding error.
340  #[inline]
341  pub const fn buffer_underflow() -> Self {
342    Self::BufferUnderflow
343  }
344
345  /// Creates a new missing field decoding error.
346  #[inline]
347  pub const fn missing_field(ty: &'static str, field: &'static str) -> Self {
348    Self::MissingField { ty, field }
349  }
350
351  /// Creates a new duplicate field decoding error.
352  #[inline]
353  pub const fn duplicate_field(ty: &'static str, field: &'static str, tag: u8) -> Self {
354    Self::DuplicateField { ty, field, tag }
355  }
356
357  /// Creates a new unknown wire type decoding error.
358  #[inline]
359  pub const fn unknown_wire_type(ty: &'static str, value: u8, tag: u8) -> Self {
360    Self::UnknownWireType { ty, value, tag }
361  }
362
363  /// Creates a new unknown tag decoding error.
364  #[inline]
365  pub const fn unknown_tag(ty: &'static str, tag: u8) -> Self {
366    Self::UnknownTag { ty, tag }
367  }
368
369  /// Creates a custom decoding error.
370  #[inline]
371  pub fn custom<T>(value: T) -> Self
372  where
373    T: Into<Cow<'static, str>>,
374  {
375    Self::Custom(value.into())
376  }
377}