use std::marker::PhantomData;
use protobuf::Message;
use super::{
codec::{Codec, Decoder, Encoder},
GrpcCallBuilder,
};
#[derive(Clone)]
pub struct ProtobufEncoder<T>(PhantomData<T>);
impl<T: Message> Default for ProtobufEncoder<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<T: Message> Encoder for ProtobufEncoder<T> {
type Input = T;
type Output<'a> = Vec<u8>;
type Error = protobuf::Error;
fn encode<'a>(&'a mut self, input: &'a Self::Input) -> Result<Self::Output<'a>, Self::Error> {
input.write_to_bytes()
}
}
#[derive(Clone)]
pub struct ProtobufDecoder<T>(PhantomData<T>);
impl<T: Message + Default> Default for ProtobufDecoder<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<T: Message + Default> Decoder for ProtobufDecoder<T> {
type Output = T;
type Error = protobuf::Error;
fn decode(&mut self, bytes: Vec<u8>) -> Result<Self::Output, Self::Error> {
T::parse_from_bytes(&bytes)
}
}
impl<'a, C: Codec> GrpcCallBuilder<'a, C> {
pub fn protobuf<Req, Res>(
self,
) -> GrpcCallBuilder<'a, (ProtobufEncoder<Req>, ProtobufDecoder<Res>)>
where
Req: Message,
Res: Message + Default,
{
self.codec((ProtobufEncoder::default(), ProtobufDecoder::default()))
}
}