use prost::Message; use prost_reflect::{DynamicMessage, MessageDescriptor}; use tonic::{ Status, codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder}, }; pub struct JsonCodec { request_descriptor: MessageDescriptor, response_descriptor: MessageDescriptor, } impl JsonCodec { pub fn new( request_descriptor: MessageDescriptor, response_descriptor: MessageDescriptor, ) -> Self { Self { request_descriptor, response_descriptor, } } } impl Codec for JsonCodec { type Encode = serde_json::Value; type Decode = serde_json::Value; type Encoder = JsonEncoder; type Decoder = JsonDecoder; fn encoder(&mut self) -> Self::Encoder { JsonEncoder(self.request_descriptor.clone()) } fn decoder(&mut self) -> Self::Decoder { JsonDecoder(self.response_descriptor.clone()) } } pub struct JsonEncoder(MessageDescriptor); impl Encoder for JsonEncoder { type Item = serde_json::Value; type Error = Status; fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> { let message = DynamicMessage::deserialize(self.0.clone(), item) .map_err(|error| Status::invalid_argument(error.to_string()))?; message.encode_raw(dst); Ok(()) } } pub struct JsonDecoder(MessageDescriptor); impl Decoder for JsonDecoder { type Item = serde_json::Value; type Error = Status; fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result, Self::Error> { let mut message = DynamicMessage::new(self.0.clone()); message .merge(src) .map_err(|error| Status::internal(error.to_string()))?; serde_json::to_value(&message) .map(Some) .map_err(|error| Status::internal(error.to_string())) } }