1use crate::buf::ReverseBuf;
2use crate::encoding::{
3 check_wire_type, Capped, DecodeContext, ForOverwrite, RestrictedDecodeContext, TagMeasurer,
4 TagRevWriter, TagWriter, WireType,
5};
6use crate::{Canonicity, DecodeError};
7use bytes::{Buf, BufMut};
8use core::ops::Deref;
9
10pub trait Encoder<E, T: ?Sized> {
12 fn encode<B: BufMut + ?Sized>(tag: u32, value: &T, buf: &mut B, tw: &mut TagWriter);
14
15 fn prepend_encode<B: ReverseBuf + ?Sized>(
17 tag: u32,
18 value: &T,
19 buf: &mut B,
20 tw: &mut TagRevWriter,
21 );
22
23 fn encoded_len(tag: u32, value: &T, tm: &mut impl TagMeasurer) -> usize;
25}
26
27pub trait Decoder<E, T>: Encoder<E, T> {
29 fn decode<B: Buf + ?Sized>(
32 wire_type: WireType,
33 value: &mut T,
34 buf: Capped<B>,
35 ctx: DecodeContext,
36 ) -> Result<(), DecodeError>;
37}
38
39pub trait DistinguishedDecoder<E, T>: Encoder<E, T> {
43 fn decode_distinguished<B: Buf + ?Sized>(
45 wire_type: WireType,
46 value: &mut T,
47 buf: Capped<B>,
48 ctx: RestrictedDecodeContext,
49 ) -> Result<Canonicity, DecodeError>;
50}
51
52pub trait BorrowDecoder<'a, E, T>: Encoder<E, T> {
54 fn borrow_decode(
55 wire_type: WireType,
56 value: &mut T,
57 buf: Capped<&'a [u8]>,
58 ctx: DecodeContext,
59 ) -> Result<(), DecodeError>;
60}
61
62pub trait DistinguishedBorrowDecoder<'a, E, T>: Encoder<E, T> {
64 fn borrow_decode_distinguished(
66 wire_type: WireType,
67 value: &mut T,
68 buf: Capped<&'a [u8]>,
69 ctx: RestrictedDecodeContext,
70 ) -> Result<Canonicity, DecodeError>;
71}
72
73pub trait Wiretyped<E, T: ?Sized> {
80 const WIRE_TYPE: WireType;
81}
82
83pub trait ValueEncoder<E, T: ?Sized>: Wiretyped<E, T> {
86 fn encode_value<B: BufMut + ?Sized>(value: &T, buf: &mut B);
88
89 fn prepend_value<B: ReverseBuf + ?Sized>(value: &T, buf: &mut B);
91
92 fn value_encoded_len(value: &T) -> usize;
94
95 #[inline]
97 fn many_values_encoded_len<I>(values: I) -> usize
98 where
99 I: ExactSizeIterator,
100 I::Item: Deref<Target = T>,
101 {
102 let len = values.len();
103 Self::WIRE_TYPE.fixed_size().map_or_else(
104 || values.map(|val| Self::value_encoded_len(&val)).sum(),
105 |fixed_size| fixed_size * len, )
107 }
108}
109
110pub trait ValueDecoder<E, T>: ValueEncoder<E, T> {
113 fn decode_value<B: Buf + ?Sized>(
115 value: &mut T,
116 buf: Capped<B>,
117 ctx: DecodeContext,
118 ) -> Result<(), DecodeError>;
119}
120
121pub trait DistinguishedValueDecoder<E, T>: ValueEncoder<E, T> + Eq {
124 const CHECKS_EMPTY: bool;
130
131 fn decode_value_distinguished<const ALLOW_EMPTY: bool>(
135 value: &mut T,
136 buf: Capped<impl Buf + ?Sized>,
137 ctx: RestrictedDecodeContext,
138 ) -> Result<Canonicity, DecodeError>;
139}
140
141pub trait ValueBorrowDecoder<'a, E, T>: ValueEncoder<E, T> {
143 fn borrow_decode_value(
145 value: &mut T,
146 buf: Capped<&'a [u8]>,
147 ctx: DecodeContext,
148 ) -> Result<(), DecodeError>;
149}
150
151pub trait DistinguishedValueBorrowDecoder<'a, E, T>: ValueEncoder<E, T> + Eq {
153 const CHECKS_EMPTY: bool;
159
160 fn borrow_decode_value_distinguished<const ALLOW_EMPTY: bool>(
164 value: &mut T,
165 buf: Capped<&'a [u8]>,
166 ctx: RestrictedDecodeContext,
167 ) -> Result<Canonicity, DecodeError>;
168}
169
170pub trait FieldEncoder<E, T: ?Sized>: ValueEncoder<E, T> {
173 fn encode_field<B: BufMut + ?Sized>(tag: u32, value: &T, buf: &mut B, tw: &mut TagWriter);
175
176 fn prepend_field<B: ReverseBuf + ?Sized>(
178 tag: u32,
179 value: &T,
180 buf: &mut B,
181 tw: &mut TagRevWriter,
182 );
183
184 fn field_encoded_len(tag: u32, value: &T, tm: &mut impl TagMeasurer) -> usize;
186}
187
188pub trait FieldDecoder<E, T>: ValueDecoder<E, T> {
191 fn decode_field<B: Buf + ?Sized>(
193 wire_type: WireType,
194 value: &mut T,
195 buf: Capped<B>,
196 ctx: DecodeContext,
197 ) -> Result<(), DecodeError>;
198}
199
200pub trait DistinguishedFieldDecoder<E, T>: DistinguishedValueDecoder<E, T> {
203 fn decode_field_distinguished<const ALLOW_EMPTY: bool>(
205 wire_type: WireType,
206 value: &mut T,
207 buf: Capped<impl Buf + ?Sized>,
208 ctx: RestrictedDecodeContext,
209 ) -> Result<Canonicity, DecodeError>;
210}
211
212pub trait FieldBorrowDecoder<'a, E, T>: ValueBorrowDecoder<'a, E, T> {
215 fn borrow_decode_field(
217 wire_type: WireType,
218 value: &mut T,
219 buf: Capped<&'a [u8]>,
220 ctx: DecodeContext,
221 ) -> Result<(), DecodeError>;
222}
223
224pub trait DistinguishedFieldBorrowDecoder<'a, E, T>:
227 DistinguishedValueBorrowDecoder<'a, E, T>
228{
229 fn borrow_decode_field_distinguished<const ALLOW_EMPTY: bool>(
231 wire_type: WireType,
232 value: &mut T,
233 buf: Capped<&'a [u8]>,
234 ctx: RestrictedDecodeContext,
235 ) -> Result<Canonicity, DecodeError>;
236}
237
238impl<E, T: ?Sized> FieldEncoder<E, T> for ()
239where
240 (): ValueEncoder<E, T>,
241{
242 #[inline]
243 fn encode_field<B: BufMut + ?Sized>(tag: u32, value: &T, buf: &mut B, tw: &mut TagWriter) {
244 tw.encode_key(tag, <() as Wiretyped<E, T>>::WIRE_TYPE, buf);
245 <() as ValueEncoder<E, T>>::encode_value(value, buf);
246 }
247
248 #[inline]
249 fn prepend_field<B: ReverseBuf + ?Sized>(
250 tag: u32,
251 value: &T,
252 buf: &mut B,
253 tw: &mut TagRevWriter,
254 ) {
255 tw.begin_field(tag, <() as Wiretyped<E, T>>::WIRE_TYPE, buf);
256 <() as ValueEncoder<E, T>>::prepend_value(value, buf);
257 }
258
259 #[inline]
260 fn field_encoded_len(tag: u32, value: &T, tm: &mut impl TagMeasurer) -> usize {
261 tm.key_len(tag) + <() as ValueEncoder<E, T>>::value_encoded_len(value)
262 }
263}
264
265impl<T, E> FieldDecoder<E, T> for ()
266where
267 (): ValueDecoder<E, T>,
268{
269 #[inline]
270 fn decode_field<B: Buf + ?Sized>(
271 wire_type: WireType,
272 value: &mut T,
273 buf: Capped<B>,
274 ctx: DecodeContext,
275 ) -> Result<(), DecodeError> {
276 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
277 <() as ValueDecoder<E, T>>::decode_value(value, buf, ctx)
278 }
279}
280
281impl<T, E> DistinguishedFieldDecoder<E, T> for ()
282where
283 (): DistinguishedValueDecoder<E, T>,
284{
285 #[inline(always)]
286 fn decode_field_distinguished<const ALLOW_EMPTY: bool>(
287 wire_type: WireType,
288 value: &mut T,
289 buf: Capped<impl Buf + ?Sized>,
290 ctx: RestrictedDecodeContext,
291 ) -> Result<Canonicity, DecodeError> {
292 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
293 <() as DistinguishedValueDecoder<E, T>>::decode_value_distinguished::<ALLOW_EMPTY>(
294 value, buf, ctx,
295 )
296 }
297}
298
299impl<'a, T, E> FieldBorrowDecoder<'a, E, T> for ()
300where
301 (): ValueBorrowDecoder<'a, E, T>,
302{
303 #[inline]
304 fn borrow_decode_field(
305 wire_type: WireType,
306 value: &mut T,
307 buf: Capped<&'a [u8]>,
308 ctx: DecodeContext,
309 ) -> Result<(), DecodeError> {
310 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
311 <() as ValueBorrowDecoder<E, T>>::borrow_decode_value(value, buf, ctx)
312 }
313}
314
315impl<'a, T, E> DistinguishedFieldBorrowDecoder<'a, E, T> for ()
316where
317 (): DistinguishedValueBorrowDecoder<'a, E, T>,
318{
319 #[inline(always)]
320 fn borrow_decode_field_distinguished<const ALLOW_EMPTY: bool>(
321 wire_type: WireType,
322 value: &mut T,
323 buf: Capped<&'a [u8]>,
324 ctx: RestrictedDecodeContext,
325 ) -> Result<Canonicity, DecodeError> {
326 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
327 <() as DistinguishedValueBorrowDecoder<E, T>>::borrow_decode_value_distinguished::<
328 ALLOW_EMPTY,
329 >(value, buf, ctx)
330 }
331}
332
333mod generic_optional {
342 use super::*;
343
344 impl<T, E> Encoder<E, Option<T>> for ()
345 where
346 (): ValueEncoder<E, T> + ForOverwrite<E, T>,
347 {
348 #[inline]
349 fn encode<B: BufMut + ?Sized>(
350 tag: u32,
351 value: &Option<T>,
352 buf: &mut B,
353 tw: &mut TagWriter,
354 ) {
355 if let Some(value) = value {
356 <() as FieldEncoder<E, T>>::encode_field(tag, value, buf, tw);
357 }
358 }
359
360 #[inline]
361 fn prepend_encode<B: ReverseBuf + ?Sized>(
362 tag: u32,
363 value: &Option<T>,
364 buf: &mut B,
365 tw: &mut TagRevWriter,
366 ) {
367 if let Some(value) = value {
368 <() as FieldEncoder<E, T>>::prepend_field(tag, value, buf, tw)
369 }
370 }
371
372 #[inline]
373 fn encoded_len(tag: u32, value: &Option<T>, tm: &mut impl TagMeasurer) -> usize {
374 if let Some(value) = value {
375 <() as FieldEncoder<E, T>>::field_encoded_len(tag, value, tm)
376 } else {
377 0
378 }
379 }
380 }
381
382 impl<T, E> Decoder<E, Option<T>> for ()
383 where
384 (): ValueDecoder<E, T> + ForOverwrite<E, T>,
385 {
386 #[inline]
387 fn decode<B: Buf + ?Sized>(
388 wire_type: WireType,
389 value: &mut Option<T>,
390 buf: Capped<B>,
391 ctx: DecodeContext,
392 ) -> Result<(), DecodeError> {
393 <() as FieldDecoder<E, T>>::decode_field(
394 wire_type,
395 value.get_or_insert_with(<() as ForOverwrite<E, T>>::for_overwrite),
396 buf,
397 ctx,
398 )
399 }
400 }
401
402 impl<T, E> DistinguishedDecoder<E, Option<T>> for ()
403 where
404 Option<T>: Eq,
405 (): DistinguishedValueDecoder<E, T> + ForOverwrite<E, T>,
406 {
407 #[inline]
408 fn decode_distinguished<B: Buf + ?Sized>(
409 wire_type: WireType,
410 value: &mut Option<T>,
411 buf: Capped<B>,
412 ctx: RestrictedDecodeContext,
413 ) -> Result<Canonicity, DecodeError> {
414 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
415 <() as DistinguishedValueDecoder<E, T>>::decode_value_distinguished::<true>(
416 value.get_or_insert_with(<() as ForOverwrite<E, T>>::for_overwrite),
417 buf,
418 ctx,
419 )
420 }
421 }
422
423 impl<'a, T, E> BorrowDecoder<'a, E, Option<T>> for ()
424 where
425 (): ValueBorrowDecoder<'a, E, T> + ForOverwrite<E, T>,
426 {
427 #[inline]
428 fn borrow_decode(
429 wire_type: WireType,
430 value: &mut Option<T>,
431 buf: Capped<&'a [u8]>,
432 ctx: DecodeContext,
433 ) -> Result<(), DecodeError> {
434 <() as FieldBorrowDecoder<E, T>>::borrow_decode_field(
435 wire_type,
436 value.get_or_insert_with(<() as ForOverwrite<E, T>>::for_overwrite),
437 buf,
438 ctx,
439 )
440 }
441 }
442
443 impl<'a, T, E> DistinguishedBorrowDecoder<'a, E, Option<T>> for ()
444 where
445 Option<T>: Eq,
446 (): DistinguishedValueBorrowDecoder<'a, E, T> + ForOverwrite<E, T>,
447 {
448 #[inline]
449 fn borrow_decode_distinguished(
450 wire_type: WireType,
451 value: &mut Option<T>,
452 buf: Capped<&'a [u8]>,
453 ctx: RestrictedDecodeContext,
454 ) -> Result<Canonicity, DecodeError> {
455 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
456 <() as DistinguishedValueBorrowDecoder<E, T>>::borrow_decode_value_distinguished::<true>(
457 value.get_or_insert_with(<() as ForOverwrite<E, T>>::for_overwrite),
458 buf,
459 ctx,
460 )
461 }
462 }
463}