1use crate::buf::ReverseBuf;
2use crate::encoding::{
3 Capped, DecodeContext, RestrictedDecodeContext, TagMeasurer, TagRevWriter, TagWriter, WireType,
4};
5use crate::{Canonicity, DecodeError};
6use alloc::boxed::Box;
7use bytes::{Buf, BufMut};
8
9pub trait Oneof {
37 const FIELD_TAGS: &'static [u32];
38
39 fn empty() -> Self;
41
42 fn is_empty(&self) -> bool;
44
45 fn clear(&mut self);
47
48 fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter);
50
51 fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter);
53
54 fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize;
56
57 fn oneof_current_tag(&self) -> Option<u32>;
59
60 fn oneof_variant_name(tag: u32) -> (&'static str, &'static str);
63}
64
65pub trait OneofDecoder: Oneof {
67 fn oneof_decode_field<B: Buf + ?Sized>(
69 value: &mut Self,
70 tag: u32,
71 wire_type: WireType,
72 buf: Capped<B>,
73 ctx: DecodeContext,
74 ) -> Result<(), DecodeError>;
75}
76
77pub trait DistinguishedOneofDecoder: Oneof {
79 fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
81 value: &mut Self,
82 tag: u32,
83 wire_type: WireType,
84 buf: Capped<B>,
85 ctx: RestrictedDecodeContext,
86 ) -> Result<Canonicity, DecodeError>;
87}
88
89pub trait OneofBorrowDecoder<'a>: Oneof {
91 fn oneof_borrow_decode_field(
92 value: &mut Self,
93 tag: u32,
94 wire_type: WireType,
95 buf: Capped<&'a [u8]>,
96 ctx: DecodeContext,
97 ) -> Result<(), DecodeError>;
98}
99
100pub trait DistinguishedOneofBorrowDecoder<'a>: Oneof {
102 fn oneof_borrow_decode_field_distinguished(
103 value: &mut Self,
104 tag: u32,
105 wire_type: WireType,
106 buf: Capped<&'a [u8]>,
107 ctx: RestrictedDecodeContext,
108 ) -> Result<Canonicity, DecodeError>;
109}
110
111pub trait NonEmptyOneof {
116 const FIELD_TAGS: &'static [u32];
117
118 fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter);
120
121 fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter);
123
124 fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize;
126
127 fn oneof_current_tag(&self) -> u32;
129
130 fn oneof_variant_name(tag: u32) -> (&'static str, &'static str);
133}
134
135pub trait NonEmptyOneofDecoder: NonEmptyOneof + Sized {
137 fn oneof_decode_field<B: Buf + ?Sized>(
139 tag: u32,
140 wire_type: WireType,
141 buf: Capped<B>,
142 ctx: DecodeContext,
143 ) -> Result<Self, DecodeError>;
144}
145
146pub trait NonEmptyDistinguishedOneofDecoder: NonEmptyOneof + Sized {
148 fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
150 tag: u32,
151 wire_type: WireType,
152 buf: Capped<B>,
153 ctx: RestrictedDecodeContext,
154 ) -> Result<(Self, Canonicity), DecodeError>;
155}
156
157pub trait NonEmptyOneofBorrowDecoder<'a>: NonEmptyOneof + Sized {
159 fn oneof_borrow_decode_field(
160 tag: u32,
161 wire_type: WireType,
162 buf: Capped<&'a [u8]>,
163 ctx: DecodeContext,
164 ) -> Result<Self, DecodeError>;
165}
166
167pub trait NonEmptyDistinguishedOneofBorrowDecoder<'a>: NonEmptyOneof + Sized {
169 fn oneof_borrow_decode_field_distinguished(
170 tag: u32,
171 wire_type: WireType,
172 buf: Capped<&'a [u8]>,
173 ctx: RestrictedDecodeContext,
174 ) -> Result<(Self, Canonicity), DecodeError>;
175}
176
177mod generic_oneof_grant_empty_state_impls {
180 use super::*;
181 use crate::DecodeErrorKind::{ConflictingFields, UnexpectedlyRepeated};
182
183 impl<T> Oneof for Option<T>
184 where
185 T: NonEmptyOneof,
186 {
187 const FIELD_TAGS: &'static [u32] = T::FIELD_TAGS;
188
189 fn empty() -> Self {
190 None
191 }
192
193 fn is_empty(&self) -> bool {
194 self.is_none()
195 }
196
197 fn clear(&mut self) {
198 *self = None;
199 }
200
201 #[inline]
202 fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter) {
203 if let Some(value) = self {
204 value.oneof_encode(buf, tw);
205 }
206 }
207
208 #[inline]
209 fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter) {
210 if let Some(value) = self {
211 value.oneof_prepend(buf, tw);
212 }
213 }
214
215 #[inline]
216 fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize {
217 if let Some(value) = self {
218 value.oneof_encoded_len(tm)
219 } else {
220 0
221 }
222 }
223
224 #[inline]
225 fn oneof_current_tag(&self) -> Option<u32> {
226 self.as_ref().map(NonEmptyOneof::oneof_current_tag)
227 }
228
229 #[inline]
230 fn oneof_variant_name(tag: u32) -> (&'static str, &'static str) {
231 T::oneof_variant_name(tag)
232 }
233 }
234
235 impl<T> OneofDecoder for Option<T>
236 where
237 T: NonEmptyOneofDecoder,
238 {
239 #[inline]
240 fn oneof_decode_field<B: Buf + ?Sized>(
241 value: &mut Self,
242 tag: u32,
243 wire_type: WireType,
244 buf: Capped<B>,
245 ctx: DecodeContext,
246 ) -> Result<(), DecodeError> {
247 if let Some(already) = value {
248 Err(DecodeError::new(if already.oneof_current_tag() == tag {
249 UnexpectedlyRepeated
250 } else {
251 ConflictingFields
252 }))
253 } else {
254 T::oneof_decode_field(tag, wire_type, buf, ctx)
255 .map(|decoded| *value = Some(decoded))
256 }
257 .map_err(|mut err| {
258 let (msg, field) = T::oneof_variant_name(tag);
259 err.push(msg, field);
260 err
261 })
262 }
263 }
264
265 impl<T> DistinguishedOneofDecoder for Option<T>
266 where
267 T: NonEmptyDistinguishedOneofDecoder + NonEmptyOneof,
268 Self: Oneof,
269 {
270 #[inline]
271 fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
272 value: &mut Self,
273 tag: u32,
274 wire_type: WireType,
275 buf: Capped<B>,
276 ctx: RestrictedDecodeContext,
277 ) -> Result<Canonicity, DecodeError> {
278 if let Some(already) = value {
279 Err(DecodeError::new(if already.oneof_current_tag() == tag {
280 UnexpectedlyRepeated
281 } else {
282 ConflictingFields
283 }))
284 } else {
285 T::oneof_decode_field_distinguished(tag, wire_type, buf, ctx.clone()).map(
286 |(decoded, canon)| {
287 *value = Some(decoded);
288 canon
289 },
290 )
291 }
292 .map_err(|mut err| {
293 let (msg, field) = T::oneof_variant_name(tag);
294 err.push(msg, field);
295 err
296 })
297 }
298 }
299
300 impl<'a, T> OneofBorrowDecoder<'a> for Option<T>
301 where
302 T: NonEmptyOneofBorrowDecoder<'a>,
303 {
304 #[inline]
305 fn oneof_borrow_decode_field(
306 value: &mut Self,
307 tag: u32,
308 wire_type: WireType,
309 buf: Capped<&'a [u8]>,
310 ctx: DecodeContext,
311 ) -> Result<(), DecodeError> {
312 if let Some(already) = value {
313 Err(DecodeError::new(if already.oneof_current_tag() == tag {
314 UnexpectedlyRepeated
315 } else {
316 ConflictingFields
317 }))
318 } else {
319 T::oneof_borrow_decode_field(tag, wire_type, buf, ctx)
320 .map(|decoded| *value = Some(decoded))
321 }
322 .map_err(|mut err| {
323 let (msg, field) = T::oneof_variant_name(tag);
324 err.push(msg, field);
325 err
326 })
327 }
328 }
329
330 impl<'a, T> DistinguishedOneofBorrowDecoder<'a> for Option<T>
331 where
332 T: NonEmptyDistinguishedOneofBorrowDecoder<'a> + NonEmptyOneof,
333 Self: Oneof,
334 {
335 #[inline]
336 fn oneof_borrow_decode_field_distinguished(
337 value: &mut Self,
338 tag: u32,
339 wire_type: WireType,
340 buf: Capped<&'a [u8]>,
341 ctx: RestrictedDecodeContext,
342 ) -> Result<Canonicity, DecodeError> {
343 if let Some(already) = value {
344 Err(DecodeError::new(if already.oneof_current_tag() == tag {
345 UnexpectedlyRepeated
346 } else {
347 ConflictingFields
348 }))
349 } else {
350 T::oneof_borrow_decode_field_distinguished(tag, wire_type, buf, ctx.clone()).map(
351 |(decoded, canon)| {
352 *value = Some(decoded);
353 canon
354 },
355 )
356 }
357 .map_err(|mut err| {
358 let (msg, field) = T::oneof_variant_name(tag);
359 err.push(msg, field);
360 err
361 })
362 }
363 }
364}
365
366mod generic_boxed_oneof_impls {
368 use super::*;
369
370 impl<T> Oneof for Box<T>
371 where
372 T: Oneof,
373 {
374 const FIELD_TAGS: &'static [u32] = <T as Oneof>::FIELD_TAGS;
375
376 #[inline]
377 fn empty() -> Self {
378 Box::new(T::empty())
379 }
380
381 #[inline]
382 fn is_empty(&self) -> bool {
383 self.as_ref().is_empty()
384 }
385
386 #[inline]
387 fn clear(&mut self) {
388 self.as_mut().clear()
389 }
390
391 #[inline]
392 fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter) {
393 Oneof::oneof_encode(&**self, buf, tw)
394 }
395
396 #[inline]
397 fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter) {
398 Oneof::oneof_prepend(&**self, buf, tw)
399 }
400
401 #[inline]
402 fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize {
403 Oneof::oneof_encoded_len(&**self, tm)
404 }
405
406 #[inline]
407 fn oneof_current_tag(&self) -> Option<u32> {
408 Oneof::oneof_current_tag(&**self)
409 }
410
411 #[inline]
412 fn oneof_variant_name(tag: u32) -> (&'static str, &'static str) {
413 T::oneof_variant_name(tag)
414 }
415 }
416
417 impl<T> OneofDecoder for Box<T>
418 where
419 T: OneofDecoder,
420 {
421 #[inline]
422 fn oneof_decode_field<B: Buf + ?Sized>(
423 value: &mut Self,
424 tag: u32,
425 wire_type: WireType,
426 buf: Capped<B>,
427 ctx: DecodeContext,
428 ) -> Result<(), DecodeError> {
429 OneofDecoder::oneof_decode_field(&mut **value, tag, wire_type, buf, ctx)
430 }
431 }
432
433 impl<T> DistinguishedOneofDecoder for Box<T>
434 where
435 T: DistinguishedOneofDecoder,
436 {
437 #[inline]
438 fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
439 value: &mut Self,
440 tag: u32,
441 wire_type: WireType,
442 buf: Capped<B>,
443 ctx: RestrictedDecodeContext,
444 ) -> Result<Canonicity, DecodeError> {
445 DistinguishedOneofDecoder::oneof_decode_field_distinguished(
446 &mut **value,
447 tag,
448 wire_type,
449 buf,
450 ctx,
451 )
452 }
453 }
454
455 impl<'a, T> OneofBorrowDecoder<'a> for Box<T>
456 where
457 T: OneofBorrowDecoder<'a>,
458 {
459 #[inline]
460 fn oneof_borrow_decode_field(
461 value: &mut Self,
462 tag: u32,
463 wire_type: WireType,
464 buf: Capped<&'a [u8]>,
465 ctx: DecodeContext,
466 ) -> Result<(), DecodeError> {
467 OneofBorrowDecoder::oneof_borrow_decode_field(&mut **value, tag, wire_type, buf, ctx)
468 }
469 }
470
471 impl<'a, T> DistinguishedOneofBorrowDecoder<'a> for Box<T>
472 where
473 T: DistinguishedOneofBorrowDecoder<'a>,
474 {
475 #[inline]
476 fn oneof_borrow_decode_field_distinguished(
477 value: &mut Self,
478 tag: u32,
479 wire_type: WireType,
480 buf: Capped<&'a [u8]>,
481 ctx: RestrictedDecodeContext,
482 ) -> Result<Canonicity, DecodeError> {
483 DistinguishedOneofBorrowDecoder::oneof_borrow_decode_field_distinguished(
484 &mut **value,
485 tag,
486 wire_type,
487 buf,
488 ctx,
489 )
490 }
491 }
492
493 impl<T> NonEmptyOneof for Box<T>
494 where
495 T: NonEmptyOneof,
496 {
497 const FIELD_TAGS: &'static [u32] = <T as NonEmptyOneof>::FIELD_TAGS;
498
499 #[inline]
500 fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter) {
501 NonEmptyOneof::oneof_encode(&**self, buf, tw)
502 }
503
504 #[inline]
505 fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter) {
506 NonEmptyOneof::oneof_prepend(&**self, buf, tw)
507 }
508
509 #[inline]
510 fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize {
511 NonEmptyOneof::oneof_encoded_len(&**self, tm)
512 }
513
514 #[inline]
515 fn oneof_current_tag(&self) -> u32 {
516 NonEmptyOneof::oneof_current_tag(&**self)
517 }
518
519 #[inline]
520 fn oneof_variant_name(tag: u32) -> (&'static str, &'static str) {
521 T::oneof_variant_name(tag)
522 }
523 }
524
525 impl<T> NonEmptyOneofDecoder for Box<T>
526 where
527 T: NonEmptyOneofDecoder,
528 {
529 #[inline]
530 fn oneof_decode_field<B: Buf + ?Sized>(
531 tag: u32,
532 wire_type: WireType,
533 buf: Capped<B>,
534 ctx: DecodeContext,
535 ) -> Result<Self, DecodeError> {
536 T::oneof_decode_field(tag, wire_type, buf, ctx).map(Box::new)
537 }
538 }
539
540 impl<T> NonEmptyDistinguishedOneofDecoder for Box<T>
541 where
542 T: NonEmptyDistinguishedOneofDecoder,
543 {
544 #[inline]
545 fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
546 tag: u32,
547 wire_type: WireType,
548 buf: Capped<B>,
549 ctx: RestrictedDecodeContext,
550 ) -> Result<(Self, Canonicity), DecodeError> {
551 NonEmptyDistinguishedOneofDecoder::oneof_decode_field_distinguished(
552 tag, wire_type, buf, ctx,
553 )
554 .map(|(val, canon)| (Box::new(val), canon))
555 }
556 }
557
558 impl<'a, T> NonEmptyOneofBorrowDecoder<'a> for Box<T>
559 where
560 T: NonEmptyOneofBorrowDecoder<'a>,
561 {
562 #[inline]
563 fn oneof_borrow_decode_field(
564 tag: u32,
565 wire_type: WireType,
566 buf: Capped<&'a [u8]>,
567 ctx: DecodeContext,
568 ) -> Result<Self, DecodeError> {
569 NonEmptyOneofBorrowDecoder::oneof_borrow_decode_field(tag, wire_type, buf, ctx)
570 .map(Box::new)
571 }
572 }
573
574 impl<'a, T> NonEmptyDistinguishedOneofBorrowDecoder<'a> for Box<T>
575 where
576 T: NonEmptyDistinguishedOneofBorrowDecoder<'a>,
577 {
578 #[inline]
579 fn oneof_borrow_decode_field_distinguished(
580 tag: u32,
581 wire_type: WireType,
582 buf: Capped<&'a [u8]>,
583 ctx: RestrictedDecodeContext,
584 ) -> Result<(Self, Canonicity), DecodeError> {
585 NonEmptyDistinguishedOneofBorrowDecoder::oneof_borrow_decode_field_distinguished(
586 tag, wire_type, buf, ctx,
587 )
588 .map(|(val, canon)| (Box::new(val), canon))
589 }
590 }
591}