pdk_classy/grpc/
protobuf.rs

1// Copyright (c) 2025, Salesforce, Inc.,
2// All rights reserved.
3// For full license text, see the LICENSE.txt file
4
5use std::marker::PhantomData;
6
7use protobuf::Message;
8
9use super::{
10    codec::{Codec, Decoder, Encoder},
11    GrpcCallBuilder,
12};
13
14#[derive(Clone)]
15pub struct ProtobufEncoder<T>(PhantomData<T>);
16
17impl<T: Message> Default for ProtobufEncoder<T> {
18    fn default() -> Self {
19        Self(PhantomData)
20    }
21}
22
23impl<T: Message> Encoder for ProtobufEncoder<T> {
24    type Input = T;
25    type Output<'a> = Vec<u8>;
26    type Error = protobuf::Error;
27
28    fn encode<'a>(&'a mut self, input: &'a Self::Input) -> Result<Self::Output<'a>, Self::Error> {
29        input.write_to_bytes()
30    }
31}
32
33#[derive(Clone)]
34pub struct ProtobufDecoder<T>(PhantomData<T>);
35
36impl<T: Message + Default> Default for ProtobufDecoder<T> {
37    fn default() -> Self {
38        Self(PhantomData)
39    }
40}
41
42impl<T: Message + Default> Decoder for ProtobufDecoder<T> {
43    type Output = T;
44    type Error = protobuf::Error;
45
46    fn decode(&mut self, bytes: Vec<u8>) -> Result<Self::Output, Self::Error> {
47        T::parse_from_bytes(&bytes)
48    }
49}
50
51impl<'a, C: Codec> GrpcCallBuilder<'a, C> {
52    /// Sets `Protocol Buffers` as the message encoding format.
53    pub fn protobuf<Req, Res>(
54        self,
55    ) -> GrpcCallBuilder<'a, (ProtobufEncoder<Req>, ProtobufDecoder<Res>)>
56    where
57        Req: Message,
58        Res: Message + Default,
59    {
60        self.codec((ProtobufEncoder::default(), ProtobufDecoder::default()))
61    }
62}