use tonic::Status;
use tonic::codec::Codec;
use tonic::codec::DecodeBuf;
use tonic::codec::Decoder;
use tonic::codec::EncodeBuf;
use tonic::codec::Encoder;
mod req;
mod resp;
use bytes::BufMut;
pub use req::ProtoRequest;
pub use resp::ProtoResponse;
pub use resp::map_proto_response;
pub use resp::map_proto_stream_result;
use crate::ProtoDecode;
use crate::ProtoEncode;
use crate::ProtoExt;
use crate::alloc::boxed::Box;
use crate::alloc::sync::Arc;
use crate::coders::AsBytes;
use crate::coders::BytesMode;
use crate::coders::ProtoCodec;
use crate::coders::ProtoDecoder;
use crate::coders::ProtoEncoder;
use crate::coders::SunByRef;
use crate::coders::SunByRefDeref;
use crate::coders::SunByVal;
use crate::encoding::DecodeContext;
impl<Encode, Decode, Mode> Codec for ProtoCodec<Encode, Decode, Mode>
where
Encode: Send + 'static,
Decode: ProtoDecode + Send + 'static,
Mode: Send + Sync + 'static,
ProtoEncoder<Encode, Mode>: EncoderExt<Encode, Mode>,
{
type Encode = Encode;
type Decode = Decode;
type Encoder = ProtoEncoder<Encode, Mode>;
type Decoder = ProtoDecoder<Decode>;
fn encoder(&mut self) -> Self::Encoder {
ProtoEncoder::default()
}
fn decoder(&mut self) -> Self::Decoder {
ProtoDecoder::default()
}
}
pub trait EncoderExt<T, Mode> {
fn encode_sun(&mut self, item: T, dst: &mut EncodeBuf<'_>) -> Result<(), Status>;
}
impl<T, Mode> EncoderExt<T, Mode> for ProtoEncoder<T, BytesMode>
where
T: AsBytes,
{
fn encode_sun(&mut self, item: T, dst: &mut EncodeBuf<'_>) -> Result<(), Status> {
dst.put_slice(item.as_bytes());
Ok(())
}
}
impl<T> EncoderExt<T, SunByVal> for ProtoEncoder<T, SunByVal>
where
T: ProtoEncode + ProtoExt,
{
fn encode_sun(&mut self, item: T, dst: &mut EncodeBuf<'_>) -> Result<(), Status> {
ProtoEncode::encode(&item, dst).map_err(|e| Status::internal(format!("encode failed: {e}")))
}
}
impl<T> EncoderExt<T, SunByRef> for ProtoEncoder<T, SunByRef>
where
T: ProtoEncode + ProtoExt,
{
fn encode_sun(&mut self, item: T, dst: &mut EncodeBuf<'_>) -> Result<(), Status> {
ProtoEncode::encode(&item, dst).map_err(|e| Status::internal(format!("encode failed: {e}")))
}
}
impl<T> EncoderExt<Arc<T>, SunByRefDeref> for ProtoEncoder<Arc<T>, SunByRefDeref>
where
T: ProtoEncode + ProtoExt,
{
fn encode_sun(&mut self, item: Arc<T>, dst: &mut EncodeBuf<'_>) -> Result<(), Status> {
ProtoEncode::encode(item.as_ref(), dst).map_err(|e| Status::internal(format!("encode failed: {e}")))
}
}
impl<T> EncoderExt<Box<T>, SunByRefDeref> for ProtoEncoder<Box<T>, SunByRefDeref>
where
T: ProtoEncode + ProtoExt,
{
fn encode_sun(&mut self, item: Box<T>, dst: &mut EncodeBuf<'_>) -> Result<(), Status> {
ProtoEncode::encode(item.as_ref(), dst).map_err(|e| Status::internal(format!("encode failed: {e}")))
}
}
impl<T, Mode> Encoder for ProtoEncoder<T, Mode>
where
ProtoEncoder<T, Mode>: EncoderExt<T, Mode>,
{
type Item = T;
type Error = Status;
#[inline]
fn encode(&mut self, item: T, dst: &mut EncodeBuf<'_>) -> Result<(), Status> {
<Self as EncoderExt<T, Mode>>::encode_sun(self, item, dst)
}
}
impl<T> Decoder for ProtoDecoder<T>
where
T: ProtoDecode,
{
type Item = T;
type Error = Status;
fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
match T::decode(src, DecodeContext::default()) {
Ok(msg) => Ok(Some(msg)),
Err(err) => Err(Status::data_loss(format!("failed to decode message: {err}"))),
}
}
}