use crate::buf::ReverseBuf;
use crate::encoding::{
Capped, DecodeContext, RestrictedDecodeContext, TagMeasurer, TagRevWriter, TagWriter, WireType,
};
use crate::{Canonicity, DecodeError};
use alloc::boxed::Box;
use bytes::{Buf, BufMut};
pub trait Oneof {
const FIELD_TAGS: &'static [u32];
fn empty() -> Self;
fn is_empty(&self) -> bool;
fn clear(&mut self);
fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter);
fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter);
fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize;
fn oneof_current_tag(&self) -> Option<u32>;
fn oneof_variant_name(tag: u32) -> (&'static str, &'static str);
}
pub trait OneofDecoder: Oneof {
fn oneof_decode_field<B: Buf + ?Sized>(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<(), DecodeError>;
}
pub trait DistinguishedOneofDecoder: Oneof {
fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: RestrictedDecodeContext,
) -> Result<Canonicity, DecodeError>;
}
pub trait OneofBorrowDecoder<'a>: Oneof {
fn oneof_borrow_decode_field(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: DecodeContext,
) -> Result<(), DecodeError>;
}
pub trait DistinguishedOneofBorrowDecoder<'a>: Oneof {
fn oneof_borrow_decode_field_distinguished(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: RestrictedDecodeContext,
) -> Result<Canonicity, DecodeError>;
}
pub trait NonEmptyOneof {
const FIELD_TAGS: &'static [u32];
fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter);
fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter);
fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize;
fn oneof_current_tag(&self) -> u32;
fn oneof_variant_name(tag: u32) -> (&'static str, &'static str);
}
pub trait NonEmptyOneofDecoder: NonEmptyOneof + Sized {
fn oneof_decode_field<B: Buf + ?Sized>(
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<Self, DecodeError>;
}
pub trait NonEmptyDistinguishedOneofDecoder: NonEmptyOneof + Sized {
fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: RestrictedDecodeContext,
) -> Result<(Self, Canonicity), DecodeError>;
}
pub trait NonEmptyOneofBorrowDecoder<'a>: NonEmptyOneof + Sized {
fn oneof_borrow_decode_field(
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: DecodeContext,
) -> Result<Self, DecodeError>;
}
pub trait NonEmptyDistinguishedOneofBorrowDecoder<'a>: NonEmptyOneof + Sized {
fn oneof_borrow_decode_field_distinguished(
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: RestrictedDecodeContext,
) -> Result<(Self, Canonicity), DecodeError>;
}
mod generic_oneof_grant_empty_state_impls {
use super::*;
use crate::DecodeErrorKind::{ConflictingFields, UnexpectedlyRepeated};
impl<T> Oneof for Option<T>
where
T: NonEmptyOneof,
{
const FIELD_TAGS: &'static [u32] = T::FIELD_TAGS;
fn empty() -> Self {
None
}
fn is_empty(&self) -> bool {
self.is_none()
}
fn clear(&mut self) {
*self = None;
}
#[inline]
fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter) {
if let Some(value) = self {
value.oneof_encode(buf, tw);
}
}
#[inline]
fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter) {
if let Some(value) = self {
value.oneof_prepend(buf, tw);
}
}
#[inline]
fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize {
if let Some(value) = self {
value.oneof_encoded_len(tm)
} else {
0
}
}
#[inline]
fn oneof_current_tag(&self) -> Option<u32> {
self.as_ref().map(NonEmptyOneof::oneof_current_tag)
}
#[inline]
fn oneof_variant_name(tag: u32) -> (&'static str, &'static str) {
T::oneof_variant_name(tag)
}
}
impl<T> OneofDecoder for Option<T>
where
T: NonEmptyOneofDecoder,
{
#[inline]
fn oneof_decode_field<B: Buf + ?Sized>(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<(), DecodeError> {
if let Some(already) = value {
Err(DecodeError::new(if already.oneof_current_tag() == tag {
UnexpectedlyRepeated
} else {
ConflictingFields
}))
} else {
T::oneof_decode_field(tag, wire_type, buf, ctx)
.map(|decoded| *value = Some(decoded))
}
.map_err(|mut err| {
let (msg, field) = T::oneof_variant_name(tag);
err.push(msg, field);
err
})
}
}
impl<T> DistinguishedOneofDecoder for Option<T>
where
T: NonEmptyDistinguishedOneofDecoder + NonEmptyOneof,
Self: Oneof,
{
#[inline]
fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: RestrictedDecodeContext,
) -> Result<Canonicity, DecodeError> {
if let Some(already) = value {
Err(DecodeError::new(if already.oneof_current_tag() == tag {
UnexpectedlyRepeated
} else {
ConflictingFields
}))
} else {
T::oneof_decode_field_distinguished(tag, wire_type, buf, ctx.clone()).map(
|(decoded, canon)| {
*value = Some(decoded);
canon
},
)
}
.map_err(|mut err| {
let (msg, field) = T::oneof_variant_name(tag);
err.push(msg, field);
err
})
}
}
impl<'a, T> OneofBorrowDecoder<'a> for Option<T>
where
T: NonEmptyOneofBorrowDecoder<'a>,
{
#[inline]
fn oneof_borrow_decode_field(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: DecodeContext,
) -> Result<(), DecodeError> {
if let Some(already) = value {
Err(DecodeError::new(if already.oneof_current_tag() == tag {
UnexpectedlyRepeated
} else {
ConflictingFields
}))
} else {
T::oneof_borrow_decode_field(tag, wire_type, buf, ctx)
.map(|decoded| *value = Some(decoded))
}
.map_err(|mut err| {
let (msg, field) = T::oneof_variant_name(tag);
err.push(msg, field);
err
})
}
}
impl<'a, T> DistinguishedOneofBorrowDecoder<'a> for Option<T>
where
T: NonEmptyDistinguishedOneofBorrowDecoder<'a> + NonEmptyOneof,
Self: Oneof,
{
#[inline]
fn oneof_borrow_decode_field_distinguished(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: RestrictedDecodeContext,
) -> Result<Canonicity, DecodeError> {
if let Some(already) = value {
Err(DecodeError::new(if already.oneof_current_tag() == tag {
UnexpectedlyRepeated
} else {
ConflictingFields
}))
} else {
T::oneof_borrow_decode_field_distinguished(tag, wire_type, buf, ctx.clone()).map(
|(decoded, canon)| {
*value = Some(decoded);
canon
},
)
}
.map_err(|mut err| {
let (msg, field) = T::oneof_variant_name(tag);
err.push(msg, field);
err
})
}
}
}
mod generic_boxed_oneof_impls {
use super::*;
impl<T> Oneof for Box<T>
where
T: Oneof,
{
const FIELD_TAGS: &'static [u32] = <T as Oneof>::FIELD_TAGS;
#[inline]
fn empty() -> Self {
Box::new(T::empty())
}
#[inline]
fn is_empty(&self) -> bool {
self.as_ref().is_empty()
}
#[inline]
fn clear(&mut self) {
self.as_mut().clear()
}
#[inline]
fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter) {
Oneof::oneof_encode(&**self, buf, tw)
}
#[inline]
fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter) {
Oneof::oneof_prepend(&**self, buf, tw)
}
#[inline]
fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize {
Oneof::oneof_encoded_len(&**self, tm)
}
#[inline]
fn oneof_current_tag(&self) -> Option<u32> {
Oneof::oneof_current_tag(&**self)
}
#[inline]
fn oneof_variant_name(tag: u32) -> (&'static str, &'static str) {
T::oneof_variant_name(tag)
}
}
impl<T> OneofDecoder for Box<T>
where
T: OneofDecoder,
{
#[inline]
fn oneof_decode_field<B: Buf + ?Sized>(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<(), DecodeError> {
OneofDecoder::oneof_decode_field(&mut **value, tag, wire_type, buf, ctx)
}
}
impl<T> DistinguishedOneofDecoder for Box<T>
where
T: DistinguishedOneofDecoder,
{
#[inline]
fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: RestrictedDecodeContext,
) -> Result<Canonicity, DecodeError> {
DistinguishedOneofDecoder::oneof_decode_field_distinguished(
&mut **value,
tag,
wire_type,
buf,
ctx,
)
}
}
impl<'a, T> OneofBorrowDecoder<'a> for Box<T>
where
T: OneofBorrowDecoder<'a>,
{
#[inline]
fn oneof_borrow_decode_field(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: DecodeContext,
) -> Result<(), DecodeError> {
OneofBorrowDecoder::oneof_borrow_decode_field(&mut **value, tag, wire_type, buf, ctx)
}
}
impl<'a, T> DistinguishedOneofBorrowDecoder<'a> for Box<T>
where
T: DistinguishedOneofBorrowDecoder<'a>,
{
#[inline]
fn oneof_borrow_decode_field_distinguished(
value: &mut Self,
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: RestrictedDecodeContext,
) -> Result<Canonicity, DecodeError> {
DistinguishedOneofBorrowDecoder::oneof_borrow_decode_field_distinguished(
&mut **value,
tag,
wire_type,
buf,
ctx,
)
}
}
impl<T> NonEmptyOneof for Box<T>
where
T: NonEmptyOneof,
{
const FIELD_TAGS: &'static [u32] = <T as NonEmptyOneof>::FIELD_TAGS;
#[inline]
fn oneof_encode<B: BufMut + ?Sized>(&self, buf: &mut B, tw: &mut TagWriter) {
NonEmptyOneof::oneof_encode(&**self, buf, tw)
}
#[inline]
fn oneof_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B, tw: &mut TagRevWriter) {
NonEmptyOneof::oneof_prepend(&**self, buf, tw)
}
#[inline]
fn oneof_encoded_len(&self, tm: &mut impl TagMeasurer) -> usize {
NonEmptyOneof::oneof_encoded_len(&**self, tm)
}
#[inline]
fn oneof_current_tag(&self) -> u32 {
NonEmptyOneof::oneof_current_tag(&**self)
}
#[inline]
fn oneof_variant_name(tag: u32) -> (&'static str, &'static str) {
T::oneof_variant_name(tag)
}
}
impl<T> NonEmptyOneofDecoder for Box<T>
where
T: NonEmptyOneofDecoder,
{
#[inline]
fn oneof_decode_field<B: Buf + ?Sized>(
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<Self, DecodeError> {
T::oneof_decode_field(tag, wire_type, buf, ctx).map(Box::new)
}
}
impl<T> NonEmptyDistinguishedOneofDecoder for Box<T>
where
T: NonEmptyDistinguishedOneofDecoder,
{
#[inline]
fn oneof_decode_field_distinguished<B: Buf + ?Sized>(
tag: u32,
wire_type: WireType,
buf: Capped<B>,
ctx: RestrictedDecodeContext,
) -> Result<(Self, Canonicity), DecodeError> {
NonEmptyDistinguishedOneofDecoder::oneof_decode_field_distinguished(
tag, wire_type, buf, ctx,
)
.map(|(val, canon)| (Box::new(val), canon))
}
}
impl<'a, T> NonEmptyOneofBorrowDecoder<'a> for Box<T>
where
T: NonEmptyOneofBorrowDecoder<'a>,
{
#[inline]
fn oneof_borrow_decode_field(
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: DecodeContext,
) -> Result<Self, DecodeError> {
NonEmptyOneofBorrowDecoder::oneof_borrow_decode_field(tag, wire_type, buf, ctx)
.map(Box::new)
}
}
impl<'a, T> NonEmptyDistinguishedOneofBorrowDecoder<'a> for Box<T>
where
T: NonEmptyDistinguishedOneofBorrowDecoder<'a>,
{
#[inline]
fn oneof_borrow_decode_field_distinguished(
tag: u32,
wire_type: WireType,
buf: Capped<&'a [u8]>,
ctx: RestrictedDecodeContext,
) -> Result<(Self, Canonicity), DecodeError> {
NonEmptyDistinguishedOneofBorrowDecoder::oneof_borrow_decode_field_distinguished(
tag, wire_type, buf, ctx,
)
.map(|(val, canon)| (Box::new(val), canon))
}
}
}