1use crate::buf::ReverseBuf;
2use crate::encoding::{
3 encode_varint, encoded_len_varint, implement_core_empty_state_rules, prepend_varint,
4 Canonicity, Capped, DecodeContext, DistinguishedValueBorrowDecoder, DistinguishedValueDecoder,
5 EmptyState, ForOverwrite, RestrictedDecodeContext, TagReader, ValueBorrowDecoder, ValueDecoder,
6 ValueEncoder, WireType, Wiretyped,
7};
8use crate::Canonicity::Canonical;
9use crate::DecodeError;
10use alloc::boxed::Box;
11use bytes::{Buf, BufMut};
12
13pub struct MessageEncoding;
17
18implement_core_empty_state_rules!(MessageEncoding);
19
20#[inline]
23pub(crate) fn merge<T: RawMessageDecoder, B: Buf + ?Sized>(
24 value: &mut T,
25 mut buf: Capped<B>,
26 ctx: DecodeContext,
27) -> Result<(), DecodeError> {
28 let tr = &mut TagReader::new();
29 let mut last_tag = None::<u32>;
30 while buf.has_remaining()? {
31 let (tag, wire_type) = tr.decode_key(buf.lend())?;
32 let duplicated = last_tag == Some(tag);
33 last_tag = Some(tag);
34 value.raw_decode_field(tag, wire_type, duplicated, buf.lend(), ctx.clone())?;
35 }
36 Ok(())
37}
38
39#[inline]
42pub(crate) fn merge_distinguished<T: RawDistinguishedMessageDecoder, B: Buf + ?Sized>(
43 value: &mut T,
44 mut buf: Capped<B>,
45 ctx: RestrictedDecodeContext,
46) -> Result<Canonicity, DecodeError> {
47 let tr = &mut TagReader::new();
48 let mut last_tag = None::<u32>;
49 let mut canon = Canonical;
50 while buf.has_remaining()? {
51 let (tag, wire_type) = tr.decode_key(buf.lend())?;
52 let duplicated = last_tag == Some(tag);
53 last_tag = Some(tag);
54 canon.update(value.raw_decode_field_distinguished(
55 tag,
56 wire_type,
57 duplicated,
58 buf.lend(),
59 ctx.clone(),
60 )?);
61 }
62 debug_assert!(
63 canon >= ctx.min_canonicity,
64 "a poorly behaved distinguished decoder did not check canonicity against the context and \
65 convert it into an error"
66 );
67 Ok(canon)
68}
69
70#[inline]
73pub(crate) fn borrow_merge<'a, T: RawMessageBorrowDecoder<'a>>(
74 value: &mut T,
75 mut buf: Capped<&'a [u8]>,
76 ctx: DecodeContext,
77) -> Result<(), DecodeError> {
78 let tr = &mut TagReader::new();
79 let mut last_tag = None::<u32>;
80 while buf.has_remaining()? {
81 let (tag, wire_type) = tr.decode_key(buf.lend())?;
82 let duplicated = last_tag == Some(tag);
83 last_tag = Some(tag);
84 value.raw_borrow_decode_field(tag, wire_type, duplicated, buf.lend(), ctx.clone())?;
85 }
86 Ok(())
87}
88
89#[inline]
92pub(crate) fn borrow_merge_distinguished<'a, T: RawDistinguishedMessageBorrowDecoder<'a>>(
93 value: &mut T,
94 mut buf: Capped<&'a [u8]>,
95 ctx: RestrictedDecodeContext,
96) -> Result<Canonicity, DecodeError> {
97 let tr = &mut TagReader::new();
98 let mut last_tag = None::<u32>;
99 let mut canon = Canonical;
100 while buf.has_remaining()? {
101 let (tag, wire_type) = tr.decode_key(buf.lend())?;
102 let duplicated = last_tag == Some(tag);
103 last_tag = Some(tag);
104 canon.update(value.raw_borrow_decode_field_distinguished(
105 tag,
106 wire_type,
107 duplicated,
108 buf.lend(),
109 ctx.clone(),
110 )?);
111 }
112 debug_assert!(
113 canon >= ctx.min_canonicity,
114 "a poorly behaved distinguished decoder did not check canonicity against the context and \
115 convert it into an error"
116 );
117 Ok(canon)
118}
119
120pub trait RawMessage {
123 const __ASSERTIONS: ();
124
125 fn empty() -> Self
127 where
128 Self: Sized;
129
130 fn is_empty(&self) -> bool;
132
133 fn clear(&mut self);
135
136 fn raw_encode<B: BufMut + ?Sized>(&self, buf: &mut B);
140
141 fn raw_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B);
143
144 fn raw_encoded_len(&self) -> usize;
146}
147
148pub trait RawMessageDecoder: RawMessage {
151 fn raw_decode_field<B: Buf + ?Sized>(
153 &mut self,
154 tag: u32,
155 wire_type: WireType,
156 duplicated: bool,
157 buf: Capped<B>,
158 ctx: DecodeContext,
159 ) -> Result<(), DecodeError>
160 where
161 Self: Sized;
162}
163
164pub trait RawDistinguishedMessageDecoder: RawMessage + Eq {
167 fn raw_decode_field_distinguished<B: Buf + ?Sized>(
168 &mut self,
169 tag: u32,
170 wire_type: WireType,
171 duplicated: bool,
172 buf: Capped<B>,
173 ctx: RestrictedDecodeContext,
174 ) -> Result<Canonicity, DecodeError>
175 where
176 Self: Sized;
177}
178
179pub trait RawMessageBorrowDecoder<'a>: RawMessage {
182 fn raw_borrow_decode_field(
184 &mut self,
185 tag: u32,
186 wire_type: WireType,
187 duplicated: bool,
188 buf: Capped<&'a [u8]>,
189 ctx: DecodeContext,
190 ) -> Result<(), DecodeError>
191 where
192 Self: Sized;
193}
194
195pub trait RawDistinguishedMessageBorrowDecoder<'a>: RawMessage + Eq {
198 fn raw_borrow_decode_field_distinguished(
199 &mut self,
200 tag: u32,
201 wire_type: WireType,
202 duplicated: bool,
203 buf: Capped<&'a [u8]>,
204 ctx: RestrictedDecodeContext,
205 ) -> Result<Canonicity, DecodeError>
206 where
207 Self: Sized;
208}
209
210impl<T> RawMessage for Box<T>
211where
212 T: RawMessage + Sized,
213{
214 const __ASSERTIONS: () = ();
215
216 fn empty() -> Self
217 where
218 Self: Sized,
219 {
220 Box::new(T::empty())
221 }
222
223 fn is_empty(&self) -> bool {
224 self.as_ref().is_empty()
225 }
226
227 fn clear(&mut self) {
228 self.as_mut().clear();
229 }
230
231 fn raw_encode<B: BufMut + ?Sized>(&self, buf: &mut B) {
232 (**self).raw_encode(buf)
233 }
234
235 fn raw_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B) {
236 (**self).raw_prepend(buf)
237 }
238
239 fn raw_encoded_len(&self) -> usize {
240 (**self).raw_encoded_len()
241 }
242}
243
244impl<T> RawMessageDecoder for Box<T>
245where
246 T: RawMessageDecoder,
247{
248 fn raw_decode_field<B: Buf + ?Sized>(
249 &mut self,
250 tag: u32,
251 wire_type: WireType,
252 duplicated: bool,
253 buf: Capped<B>,
254 ctx: DecodeContext,
255 ) -> Result<(), DecodeError>
256 where
257 Self: Sized,
258 {
259 (**self).raw_decode_field(tag, wire_type, duplicated, buf, ctx)
260 }
261}
262
263impl<'a, T> RawMessageBorrowDecoder<'a> for Box<T>
264where
265 T: RawMessageBorrowDecoder<'a>,
266{
267 fn raw_borrow_decode_field(
268 &mut self,
269 tag: u32,
270 wire_type: WireType,
271 duplicated: bool,
272 buf: Capped<&'a [u8]>,
273 ctx: DecodeContext,
274 ) -> Result<(), DecodeError>
275 where
276 Self: Sized,
277 {
278 (**self).raw_borrow_decode_field(tag, wire_type, duplicated, buf, ctx)
279 }
280}
281
282impl<T> RawDistinguishedMessageDecoder for Box<T>
283where
284 T: RawDistinguishedMessageDecoder,
285{
286 fn raw_decode_field_distinguished<B: Buf + ?Sized>(
287 &mut self,
288 tag: u32,
289 wire_type: WireType,
290 duplicated: bool,
291 buf: Capped<B>,
292 ctx: RestrictedDecodeContext,
293 ) -> Result<Canonicity, DecodeError>
294 where
295 Self: Sized,
296 {
297 (**self).raw_decode_field_distinguished(tag, wire_type, duplicated, buf, ctx)
298 }
299}
300
301impl<'a, T> RawDistinguishedMessageBorrowDecoder<'a> for Box<T>
302where
303 T: RawDistinguishedMessageBorrowDecoder<'a>,
304{
305 fn raw_borrow_decode_field_distinguished(
306 &mut self,
307 tag: u32,
308 wire_type: WireType,
309 duplicated: bool,
310 buf: Capped<&'a [u8]>,
311 ctx: RestrictedDecodeContext,
312 ) -> Result<Canonicity, DecodeError>
313 where
314 Self: Sized,
315 {
316 (**self).raw_borrow_decode_field_distinguished(tag, wire_type, duplicated, buf, ctx)
317 }
318}
319
320impl<T> ForOverwrite<MessageEncoding, T> for ()
321where
322 T: RawMessage,
323{
324 fn for_overwrite() -> T
325 where
326 T: Sized,
327 {
328 T::empty()
329 }
330}
331
332impl<T> EmptyState<MessageEncoding, T> for ()
333where
334 T: RawMessage,
335{
336 fn is_empty(val: &T) -> bool {
337 val.is_empty()
338 }
339
340 fn clear(val: &mut T) {
341 val.clear();
342 }
343}
344
345impl<T> Wiretyped<MessageEncoding, T> for ()
346where
347 T: RawMessage,
348{
349 const WIRE_TYPE: WireType = WireType::LengthDelimited;
350}
351
352impl<T> ValueEncoder<MessageEncoding, T> for ()
353where
354 T: RawMessage,
355{
356 #[inline]
357 fn encode_value<B: BufMut + ?Sized>(value: &T, buf: &mut B) {
358 encode_varint(value.raw_encoded_len() as u64, buf);
359 value.raw_encode(buf);
360 }
361
362 #[inline]
363 fn prepend_value<B: ReverseBuf + ?Sized>(value: &T, buf: &mut B) {
364 let end = buf.remaining();
365 value.raw_prepend(buf);
366 prepend_varint((buf.remaining() - end) as u64, buf);
367 }
368
369 #[inline]
370 fn value_encoded_len(value: &T) -> usize {
371 let inner_len = value.raw_encoded_len();
372 encoded_len_varint(inner_len as u64) + inner_len
373 }
374}
375
376impl<T> ValueDecoder<MessageEncoding, T> for ()
377where
378 T: RawMessageDecoder,
379{
380 #[inline]
381 fn decode_value<B: Buf + ?Sized>(
382 value: &mut T,
383 mut buf: Capped<B>,
384 ctx: DecodeContext,
385 ) -> Result<(), DecodeError> {
386 ctx.limit_reached()?;
387 merge(value, buf.take_length_delimited()?, ctx.enter_recursion())
388 }
389}
390
391impl<T> DistinguishedValueDecoder<MessageEncoding, T> for ()
392where
393 T: RawDistinguishedMessageDecoder + Eq,
394{
395 const CHECKS_EMPTY: bool = true; #[inline]
398 fn decode_value_distinguished<const ALLOW_EMPTY: bool>(
399 value: &mut T,
400 mut buf: Capped<impl Buf + ?Sized>,
401 ctx: RestrictedDecodeContext,
402 ) -> Result<Canonicity, DecodeError> {
403 ctx.limit_reached()?;
404 let buf = buf.take_length_delimited()?;
405 if !ALLOW_EMPTY && buf.remaining_before_cap() == 0 {
409 return ctx.check(Canonicity::NotCanonical);
410 }
411 merge_distinguished(value, buf, ctx.enter_recursion())
412 }
413}
414
415impl<'a, T> ValueBorrowDecoder<'a, MessageEncoding, T> for ()
416where
417 T: RawMessageBorrowDecoder<'a>,
418{
419 #[inline]
420 fn borrow_decode_value(
421 value: &mut T,
422 mut buf: Capped<&'a [u8]>,
423 ctx: DecodeContext,
424 ) -> Result<(), DecodeError> {
425 ctx.limit_reached()?;
426 borrow_merge(value, buf.take_length_delimited()?, ctx.enter_recursion())
427 }
428}
429
430impl<'a, T> DistinguishedValueBorrowDecoder<'a, MessageEncoding, T> for ()
431where
432 T: RawDistinguishedMessageBorrowDecoder<'a> + Eq,
433{
434 const CHECKS_EMPTY: bool = true; #[inline]
437 fn borrow_decode_value_distinguished<const ALLOW_EMPTY: bool>(
438 value: &mut T,
439 mut buf: Capped<&'a [u8]>,
440 ctx: RestrictedDecodeContext,
441 ) -> Result<Canonicity, DecodeError> {
442 ctx.limit_reached()?;
443 let buf = buf.take_length_delimited()?;
444 if !ALLOW_EMPTY && buf.remaining_before_cap() == 0 {
448 return ctx.check(Canonicity::NotCanonical);
449 }
450 borrow_merge_distinguished(value, buf, ctx.enter_recursion())
451 }
452}