memberlist_proto/data/
tuple.rs

1use varing::{encode_u32_varint_to, encoded_u32_varint_len};
2
3use crate::utils::{merge, skip};
4
5use super::{Data, DataRef, DecodeError, EncodeError};
6
7const A_TAG: u8 = 1;
8const B_TAG: u8 = 2;
9
10impl<'a, A, B> DataRef<'a, (A, B)> for (A::Ref<'a>, B::Ref<'a>)
11where
12  A: Data,
13  B: Data,
14{
15  fn decode(buf: &'a [u8]) -> Result<(usize, Self), DecodeError>
16  where
17    Self: Sized,
18  {
19    let mut offset = 0;
20    let buf_len = buf.len();
21    let mut a = None;
22    let mut b = None;
23
24    while offset < buf_len {
25      match buf[offset] {
26        byte if byte == merge(A::WIRE_TYPE, A_TAG) => {
27          if a.is_some() {
28            return Err(DecodeError::duplicate_field("tuple(2)", "0", A_TAG));
29          }
30
31          offset += 1;
32          let (bytes_read, value) = A::Ref::decode_length_delimited(&buf[offset..])?;
33          offset += bytes_read;
34          a = Some(value);
35        }
36        byte if byte == merge(B::WIRE_TYPE, B_TAG) => {
37          if b.is_some() {
38            return Err(DecodeError::duplicate_field("tuple(2)", "1", B_TAG));
39          }
40
41          offset += 1;
42          let (bytes_read, value) = B::Ref::decode_length_delimited(&buf[offset..])?;
43          offset += bytes_read;
44          b = Some(value);
45        }
46        _ => offset += skip("tuple(2)", &buf[offset..])?,
47      }
48    }
49
50    let a = a.ok_or_else(|| DecodeError::missing_field("tuple(2)", "0"))?;
51    let b = b.ok_or_else(|| DecodeError::missing_field("tuple(2)", "1"))?;
52
53    Ok((offset, (a, b)))
54  }
55}
56
57impl<A, B> Data for (A, B)
58where
59  A: Data,
60  B: Data,
61{
62  type Ref<'a> = (A::Ref<'a>, B::Ref<'a>);
63
64  fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError>
65  where
66    Self: Sized,
67  {
68    let (a, b) = val;
69    Ok((A::from_ref(a)?, B::from_ref(b)?))
70  }
71
72  fn encoded_len(&self) -> usize {
73    TupleEncoder::new(&self.0, &self.1).encoded_len()
74  }
75
76  fn encoded_len_with_length_delimited(&self) -> usize {
77    TupleEncoder::new(&self.0, &self.1).encoded_len_with_length_delimited()
78  }
79
80  fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
81    TupleEncoder::new(&self.0, &self.1).encode(buf)
82  }
83
84  fn encode_length_delimited(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
85    TupleEncoder::new(&self.0, &self.1).encode_with_length_delimited(buf)
86  }
87}
88
89/// The encoder for a tuple of two data types.
90pub struct TupleEncoder<'a, A, B> {
91  a: &'a A,
92  b: &'a B,
93}
94
95impl<'a, A, B> TupleEncoder<'a, A, B> {
96  /// Create a new tuple encoder.
97  pub fn new(a: &'a A, b: &'a B) -> Self {
98    Self { a, b }
99  }
100}
101
102impl<A, B> TupleEncoder<'_, A, B>
103where
104  A: Data,
105  B: Data,
106{
107  /// Returns the encoded length of the data only considering the data itself, (e.g. no length prefix, no wire type).
108  pub fn encoded_len(&self) -> usize {
109    1 + self.a.encoded_len_with_length_delimited() + 1 + self.b.encoded_len_with_length_delimited()
110  }
111
112  /// Returns the encoded length of the data including the length delimited.
113  pub fn encoded_len_with_length_delimited(&self) -> usize {
114    let len = self.encoded_len();
115    encoded_u32_varint_len(len as u32).get() + len
116  }
117
118  /// Encodes the message to a buffer.
119  ///
120  /// An error will be returned if the buffer does not have sufficient capacity.
121  pub fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
122    let mut offset = 0;
123    let buf_len = buf.len();
124
125    if offset >= buf_len {
126      return Err(EncodeError::insufficient_buffer(self.encoded_len(), 0));
127    }
128
129    buf[offset] = merge(A::WIRE_TYPE, A_TAG);
130    offset += 1;
131
132    offset += self
133      .a
134      .encode_length_delimited(&mut buf[offset..])
135      .map_err(|e| e.update(self.encoded_len(), buf_len))?;
136
137    if offset >= buf_len {
138      return Err(EncodeError::insufficient_buffer(self.encoded_len(), offset));
139    }
140
141    buf[offset] = merge(B::WIRE_TYPE, B_TAG);
142    offset += 1;
143
144    offset += self
145      .b
146      .encode_length_delimited(&mut buf[offset..])
147      .map_err(|e| e.update(self.encoded_len(), buf_len))?;
148
149    Ok(offset)
150  }
151
152  /// Encodes the message with a length-delimiter to a buffer.
153  ///
154  /// An error will be returned if the buffer does not have sufficient capacity.
155  pub fn encode_with_length_delimited(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
156    let len = self.encoded_len();
157    if len > u32::MAX as usize {
158      return Err(EncodeError::TooLarge);
159    }
160
161    let mut offset = 0;
162    offset += encode_u32_varint_to(len as u32, buf)?.get();
163    offset += self.encode(&mut buf[offset..])?;
164
165    #[cfg(debug_assertions)]
166    super::super::debug_assert_write_eq::<Self>(offset, self.encoded_len_with_length_delimited());
167
168    Ok(offset)
169  }
170}