structured_proxy/transcode/
codec.rs1use prost::bytes::Buf;
7use prost::Message;
8use prost_reflect::{DynamicMessage, MessageDescriptor};
9use tonic::codec::{BufferSettings, Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
10use tonic::Status;
11
12#[derive(Debug, Clone)]
14pub struct DynamicEncoder;
15
16impl Encoder for DynamicEncoder {
17 type Item = DynamicMessage;
18 type Error = Status;
19
20 fn encode(&mut self, item: Self::Item, buf: &mut EncodeBuf<'_>) -> Result<(), Status> {
21 item.encode(buf)
22 .map_err(|e| Status::internal(format!("encode error: {e}")))
23 }
24
25 fn buffer_settings(&self) -> BufferSettings {
26 BufferSettings::default()
27 }
28}
29
30#[derive(Debug, Clone)]
32pub struct DynamicDecoder {
33 desc: MessageDescriptor,
34}
35
36impl DynamicDecoder {
37 pub fn new(desc: MessageDescriptor) -> Self {
38 Self { desc }
39 }
40}
41
42impl Decoder for DynamicDecoder {
43 type Item = DynamicMessage;
44 type Error = Status;
45
46 fn decode(&mut self, buf: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Status> {
47 let remaining = buf.remaining();
48 if remaining == 0 {
49 return Ok(None);
50 }
51 let msg = DynamicMessage::decode(self.desc.clone(), buf.copy_to_bytes(remaining))
52 .map_err(|e| Status::internal(format!("decode error: {e}")))?;
53 Ok(Some(msg))
54 }
55
56 fn buffer_settings(&self) -> BufferSettings {
57 BufferSettings::default()
58 }
59}
60
61#[derive(Debug, Clone)]
63pub struct DynamicCodec {
64 response_desc: MessageDescriptor,
65}
66
67impl DynamicCodec {
68 pub fn new(response_desc: MessageDescriptor) -> Self {
69 Self { response_desc }
70 }
71}
72
73impl Codec for DynamicCodec {
74 type Encode = DynamicMessage;
75 type Decode = DynamicMessage;
76 type Encoder = DynamicEncoder;
77 type Decoder = DynamicDecoder;
78
79 fn encoder(&mut self) -> Self::Encoder {
80 DynamicEncoder
81 }
82
83 fn decoder(&mut self) -> Self::Decoder {
84 DynamicDecoder::new(self.response_desc.clone())
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 #[test]
91 fn test_dynamic_codec_creation() {
92 let pool = prost_reflect::DescriptorPool::decode(
94 prost_reflect::DescriptorPool::global()
95 .encode_to_vec()
96 .as_slice(),
97 )
98 .unwrap_or_else(|_| prost_reflect::DescriptorPool::new());
99 let _ = pool;
101 }
102}