use alloc::boxed::Box;
use alloc::vec::Vec;
use bytes::{Buf, BufMut, Bytes, BytesMut};
use crate::buf::{ReverseBuf, ReverseBuffer};
use crate::encoding::{
encode_varint, encoded_len_varint, prepend_varint, Canonicity, Capped, DecodeContext,
EmptyState, TagReader, WireType,
};
use crate::{DecodeError, EncodeError};
#[inline]
pub(crate) fn merge<T: RawMessage, B: Buf + ?Sized>(
value: &mut T,
mut buf: Capped<B>,
ctx: DecodeContext,
) -> Result<(), DecodeError> {
let tr = &mut TagReader::new();
let mut last_tag = None::<u32>;
while buf.has_remaining()? {
let (tag, wire_type) = tr.decode_key(buf.lend())?;
let duplicated = last_tag == Some(tag);
last_tag = Some(tag);
value.raw_decode_field(tag, wire_type, duplicated, buf.lend(), ctx.clone())?;
}
Ok(())
}
#[inline]
pub(crate) fn merge_distinguished<T: RawDistinguishedMessage, B: Buf + ?Sized>(
value: &mut T,
mut buf: Capped<B>,
ctx: DecodeContext,
) -> Result<Canonicity, DecodeError> {
let tr = &mut TagReader::new();
let mut last_tag = None::<u32>;
let mut canon = Canonicity::Canonical;
while buf.has_remaining()? {
let (tag, wire_type) = tr.decode_key(buf.lend())?;
let duplicated = last_tag == Some(tag);
last_tag = Some(tag);
canon.update(value.raw_decode_field_distinguished(
tag,
wire_type,
duplicated,
buf.lend(),
ctx.clone(),
)?);
}
Ok(canon)
}
pub trait Message: EmptyState {
fn encode<B: BufMut + ?Sized>(&self, buf: &mut B) -> Result<(), EncodeError>
where
Self: Sized;
fn prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B)
where
Self: Sized;
fn encode_length_delimited<B: BufMut + ?Sized>(&self, buf: &mut B) -> Result<(), EncodeError>
where
Self: Sized;
fn decode<B: Buf>(buf: B) -> Result<Self, DecodeError>
where
Self: Sized;
fn decode_length_delimited<B: Buf>(buf: B) -> Result<Self, DecodeError>
where
Self: Sized;
#[doc(hidden)]
fn decode_capped<B: Buf + ?Sized>(buf: Capped<B>) -> Result<Self, DecodeError>
where
Self: Sized;
fn replace_from<B: Buf>(&mut self, buf: B) -> Result<(), DecodeError>
where
Self: Sized;
fn replace_from_length_delimited<B: Buf>(&mut self, buf: B) -> Result<(), DecodeError>
where
Self: Sized;
#[doc(hidden)]
fn replace_from_capped<B: Buf + ?Sized>(&mut self, buf: Capped<B>) -> Result<(), DecodeError>
where
Self: Sized;
fn encoded_len(&self) -> usize;
fn encode_to_vec(&self) -> Vec<u8>;
fn encode_to_bytes(&self) -> Bytes;
fn encode_fast(&self) -> ReverseBuffer;
fn encode_length_delimited_fast(&self) -> ReverseBuffer;
fn encode_dyn(&self, buf: &mut dyn BufMut) -> Result<(), EncodeError>;
fn encode_length_delimited_to_vec(&self) -> Vec<u8>;
fn encode_length_delimited_to_bytes(&self) -> Bytes;
fn encode_length_delimited_dyn(&self, buf: &mut dyn BufMut) -> Result<(), EncodeError>;
fn replace_from_slice(&mut self, buf: &[u8]) -> Result<(), DecodeError>;
fn replace_from_length_delimited_slice(&mut self, buf: &[u8]) -> Result<(), DecodeError>;
fn replace_from_dyn(&mut self, buf: &mut dyn Buf) -> Result<(), DecodeError>;
fn replace_from_length_delimited_dyn(&mut self, buf: &mut dyn Buf) -> Result<(), DecodeError>;
#[doc(hidden)]
fn replace_from_capped_dyn(&mut self, buf: Capped<dyn Buf>) -> Result<(), DecodeError>;
}
pub trait DistinguishedMessage: Message {
fn decode_distinguished<B: Buf>(buf: B) -> Result<(Self, Canonicity), DecodeError>
where
Self: Sized;
fn decode_distinguished_length_delimited<B: Buf>(
buf: B,
) -> Result<(Self, Canonicity), DecodeError>
where
Self: Sized;
#[doc(hidden)]
fn decode_distinguished_capped<B: Buf + ?Sized>(
buf: Capped<B>,
) -> Result<(Self, Canonicity), DecodeError>
where
Self: Sized;
fn replace_distinguished_from<B: Buf>(&mut self, buf: B) -> Result<Canonicity, DecodeError>
where
Self: Sized;
fn replace_distinguished_from_length_delimited<B: Buf>(
&mut self,
buf: B,
) -> Result<Canonicity, DecodeError>
where
Self: Sized;
#[doc(hidden)]
fn replace_distinguished_from_capped<B: Buf + ?Sized>(
&mut self,
buf: Capped<B>,
) -> Result<Canonicity, DecodeError>
where
Self: Sized;
fn replace_distinguished_from_slice(&mut self, buf: &[u8]) -> Result<Canonicity, DecodeError>;
fn replace_distinguished_from_dyn(
&mut self,
buf: &mut dyn Buf,
) -> Result<Canonicity, DecodeError>;
fn replace_distinguished_from_length_delimited_slice(
&mut self,
buf: &[u8],
) -> Result<Canonicity, DecodeError>;
fn replace_distinguished_from_length_delimited_dyn(
&mut self,
buf: &mut dyn Buf,
) -> Result<Canonicity, DecodeError>;
#[doc(hidden)]
fn replace_distinguished_from_capped_dyn(
&mut self,
buf: Capped<dyn Buf>,
) -> Result<Canonicity, DecodeError>;
}
impl<T> Message for T
where
T: RawMessage,
{
fn encode<B: BufMut + ?Sized>(&self, buf: &mut B) -> Result<(), EncodeError> {
let required = self.encoded_len();
let remaining = buf.remaining_mut();
if required > remaining {
return Err(EncodeError::new(required, remaining));
}
self.raw_encode(buf);
Ok(())
}
fn prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B)
where
Self: Sized,
{
self.raw_prepend(buf);
}
fn encode_length_delimited<B: BufMut + ?Sized>(&self, buf: &mut B) -> Result<(), EncodeError> {
let len = self.encoded_len();
let required = len + encoded_len_varint(len as u64);
let remaining = buf.remaining_mut();
if required > remaining {
return Err(EncodeError::new(required, remaining));
}
encode_varint(len as u64, buf);
self.raw_encode(buf);
Ok(())
}
fn decode<B: Buf>(mut buf: B) -> Result<Self, DecodeError> {
Self::decode_capped(Capped::new(&mut buf))
}
fn decode_length_delimited<B: Buf>(mut buf: B) -> Result<Self, DecodeError> {
Self::decode_capped(Capped::new_length_delimited(&mut buf)?)
}
#[doc(hidden)]
fn decode_capped<B: Buf + ?Sized>(buf: Capped<B>) -> Result<Self, DecodeError> {
let mut message = Self::empty();
merge(&mut message, buf, DecodeContext::default())?;
Ok(message)
}
fn replace_from<B: Buf>(&mut self, mut buf: B) -> Result<(), DecodeError> {
self.replace_from_capped(Capped::new(&mut buf))
}
fn replace_from_length_delimited<B: Buf>(&mut self, mut buf: B) -> Result<(), DecodeError> {
self.replace_from_capped(Capped::new_length_delimited(&mut buf)?)
}
#[doc(hidden)]
fn replace_from_capped<B: Buf + ?Sized>(&mut self, buf: Capped<B>) -> Result<(), DecodeError> {
self.clear();
merge(self, buf, DecodeContext::default()).map_err(|err| {
self.clear();
err
})
}
fn encoded_len(&self) -> usize {
self.raw_encoded_len()
}
fn encode_to_vec(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(self.encoded_len());
self.raw_encode(&mut buf);
buf
}
fn encode_to_bytes(&self) -> Bytes {
let mut buf = BytesMut::with_capacity(self.encoded_len());
self.raw_encode(&mut buf);
buf.freeze()
}
fn encode_fast(&self) -> ReverseBuffer {
let mut buf = ReverseBuffer::new();
self.raw_prepend(&mut buf);
buf
}
fn encode_length_delimited_fast(&self) -> ReverseBuffer {
let mut buf = self.encode_fast();
prepend_varint(buf.remaining() as u64, &mut buf);
buf
}
fn encode_dyn(&self, buf: &mut dyn BufMut) -> Result<(), EncodeError> {
self.encode(buf)
}
fn encode_length_delimited_to_vec(&self) -> Vec<u8> {
let len = self.encoded_len();
let mut buf = Vec::with_capacity(len + encoded_len_varint(len as u64));
encode_varint(len as u64, &mut buf);
self.raw_encode(&mut buf);
buf
}
fn encode_length_delimited_to_bytes(&self) -> Bytes {
let len = self.encoded_len();
let mut buf = BytesMut::with_capacity(len + encoded_len_varint(len as u64));
encode_varint(len as u64, &mut buf);
self.raw_encode(&mut buf);
buf.freeze()
}
fn encode_length_delimited_dyn(&self, buf: &mut dyn BufMut) -> Result<(), EncodeError> {
self.encode_length_delimited(buf)
}
fn replace_from_slice(&mut self, buf: &[u8]) -> Result<(), DecodeError> {
self.replace_from(buf)
}
fn replace_from_length_delimited_slice(&mut self, buf: &[u8]) -> Result<(), DecodeError> {
self.replace_from_length_delimited(buf)
}
fn replace_from_dyn(&mut self, buf: &mut dyn Buf) -> Result<(), DecodeError> {
self.replace_from(buf)
}
fn replace_from_length_delimited_dyn(&mut self, buf: &mut dyn Buf) -> Result<(), DecodeError> {
self.replace_from_length_delimited(buf)
}
#[doc(hidden)]
fn replace_from_capped_dyn(&mut self, buf: Capped<dyn Buf>) -> Result<(), DecodeError> {
self.replace_from_capped(buf)
}
}
impl<T> DistinguishedMessage for T
where
T: RawDistinguishedMessage + Message,
{
fn decode_distinguished<B: Buf>(mut buf: B) -> Result<(Self, Canonicity), DecodeError> {
Self::decode_distinguished_capped(Capped::new(&mut buf))
}
fn decode_distinguished_length_delimited<B: Buf>(
mut buf: B,
) -> Result<(Self, Canonicity), DecodeError> {
Self::decode_distinguished_capped(Capped::new_length_delimited(&mut buf)?)
}
#[doc(hidden)]
fn decode_distinguished_capped<B: Buf + ?Sized>(
buf: Capped<B>,
) -> Result<(Self, Canonicity), DecodeError> {
let mut message = Self::empty();
let canon = merge_distinguished(&mut message, buf, DecodeContext::default())?;
Ok((message, canon))
}
fn replace_distinguished_from<B: Buf>(
&mut self,
mut buf: B,
) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from_capped(Capped::new(&mut buf))
}
fn replace_distinguished_from_length_delimited<B: Buf>(
&mut self,
mut buf: B,
) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from_capped(Capped::new_length_delimited(&mut buf)?)
}
#[doc(hidden)]
fn replace_distinguished_from_capped<B: Buf + ?Sized>(
&mut self,
buf: Capped<B>,
) -> Result<Canonicity, DecodeError> {
self.clear();
merge_distinguished(self, buf, DecodeContext::default()).map_err(|err| {
self.clear();
err
})
}
fn replace_distinguished_from_slice(&mut self, buf: &[u8]) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from(buf)
}
fn replace_distinguished_from_dyn(
&mut self,
buf: &mut dyn Buf,
) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from(buf)
}
fn replace_distinguished_from_length_delimited_slice(
&mut self,
buf: &[u8],
) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from_length_delimited(buf)
}
fn replace_distinguished_from_length_delimited_dyn(
&mut self,
buf: &mut dyn Buf,
) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from_length_delimited(buf)
}
#[doc(hidden)]
fn replace_distinguished_from_capped_dyn(
&mut self,
buf: Capped<dyn Buf>,
) -> Result<Canonicity, DecodeError> {
self.replace_distinguished_from_capped(buf)
}
}
pub trait RawMessage: EmptyState {
const __ASSERTIONS: ();
fn raw_encode<B: BufMut + ?Sized>(&self, buf: &mut B);
fn raw_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B);
fn raw_encoded_len(&self) -> usize;
fn raw_decode_field<B: Buf + ?Sized>(
&mut self,
tag: u32,
wire_type: WireType,
duplicated: bool,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<(), DecodeError>
where
Self: Sized;
}
pub trait RawDistinguishedMessage: RawMessage + Eq {
fn raw_decode_field_distinguished<B: Buf + ?Sized>(
&mut self,
tag: u32,
wire_type: WireType,
duplicated: bool,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<Canonicity, DecodeError>
where
Self: Sized;
}
impl<T> RawMessage for Box<T>
where
T: RawMessage,
{
const __ASSERTIONS: () = ();
fn raw_encode<B: BufMut + ?Sized>(&self, buf: &mut B) {
(**self).raw_encode(buf)
}
fn raw_prepend<B: ReverseBuf + ?Sized>(&self, buf: &mut B) {
(**self).raw_prepend(buf)
}
fn raw_encoded_len(&self) -> usize {
(**self).raw_encoded_len()
}
fn raw_decode_field<B: Buf + ?Sized>(
&mut self,
tag: u32,
wire_type: WireType,
duplicated: bool,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<(), DecodeError>
where
Self: Sized,
{
(**self).raw_decode_field(tag, wire_type, duplicated, buf, ctx)
}
}
impl<T> RawDistinguishedMessage for Box<T>
where
T: RawDistinguishedMessage,
{
fn raw_decode_field_distinguished<B: Buf + ?Sized>(
&mut self,
tag: u32,
wire_type: WireType,
duplicated: bool,
buf: Capped<B>,
ctx: DecodeContext,
) -> Result<Canonicity, DecodeError>
where
Self: Sized,
{
(**self).raw_decode_field_distinguished(tag, wire_type, duplicated, buf, ctx)
}
}
#[cfg(test)]
mod tests {
use super::{DistinguishedMessage, Message, Vec};
use crate::WithCanonicity;
const _MESSAGE_DYN_IS_OBJECT_SAFE: Option<&dyn Message> = None;
const _DISTINGUISHED_MESSAGE_DYN_IS_OBJECT_SAFE: Option<&dyn DistinguishedMessage> = None;
fn use_dyn_messages<M: Message>(safe: &mut dyn Message, mut msg: M) {
let mut vec = Vec::<u8>::new();
safe.encoded_len();
safe.encode_dyn(&mut vec).unwrap();
assert_eq!(vec, safe.encode_to_vec());
safe.replace_from_length_delimited_dyn(&mut [0u8].as_slice())
.unwrap();
msg.encoded_len();
msg = M::decode_length_delimited(&mut [0u8].as_slice()).unwrap();
msg.encode(&mut vec).unwrap();
msg.clear();
}
fn use_dyn_distinguished_messages<M: DistinguishedMessage>(
safe: &mut dyn DistinguishedMessage,
mut msg: M,
) {
let mut vec = Vec::<u8>::new();
safe.encoded_len();
safe.encode_dyn(&mut vec).unwrap();
assert_eq!(vec, safe.encode_to_vec());
safe.replace_from_length_delimited_dyn(&mut [0u8].as_slice())
.unwrap();
safe.replace_distinguished_from_length_delimited_dyn(&mut [0u8].as_slice())
.canonical()
.unwrap();
safe.clear();
msg.encoded_len();
msg = M::decode_length_delimited(&mut [0u8].as_slice()).unwrap();
msg.encode(&mut vec).unwrap();
msg.clear();
}
#[test]
fn using_dyn_messages() {
let mut vec = Vec::<u8>::new();
use_dyn_messages(&mut (), ());
use_dyn_distinguished_messages(&mut (), ());
assert_eq!(().encoded_len(), 0);
().encode(&mut vec).unwrap();
().encode_dyn(&mut vec).unwrap();
<()>::decode(&mut [].as_slice()).unwrap();
}
}