pdk-classy 1.9.1-alpha.2

PDK Classy
Documentation
// Copyright (c) 2026, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

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> {
    /// Sets `Protocol Buffers` as the message encoding format.
    pub fn protobuf<Req, Res>(
        self,
    ) -> GrpcCallBuilder<'a, (ProtobufEncoder<Req>, ProtobufDecoder<Res>)>
    where
        Req: Message,
        Res: Message + Default,
    {
        self.codec((ProtobufEncoder::default(), ProtobufDecoder::default()))
    }
}